vue-router 用 subRoute 替换父视图
vue-router replace parent view with subRoute
我正在使用 vue-router 并且有一个关于 subRoutes 的问题。我想设置我的路线,所以主要路线是列表,子路线是 edit/add/etc.
我想要子路由组件替换父路由的<router-view>
。我理解文档的方式以及我测试过的内容,看起来我应该在父组件模板中定义另一个 <router-view>
以便子路径呈现到其中,但用户列表将保持可见。
示例路线:
'/users': {
name: 'user-list',
component(resolve) {
require(['./components/users.vue'], resolve)
},
subRoutes: {
'/add': {
name: 'add-user',
component(resolve) {
require(['./components/users_add.vue'], resolve)
}
}
}
}
主路由器视图:
<!-- main router view -->
<div id="app">
<router-view></router-view>
</div>
用户列表:
<template>
<a v-link="{ name: 'add-user' }">Add</a>
<ul>
<li>{{ name }}</li>
</ul>
</template>
添加用户:
<template>
<div>
<a v-link="{ name: 'user-list' }">back</a>
<input type="text" v-model="name">
</div>
</template>
当我点击 "Add" 时,我想填充添加用户模板。这可能吗?
另外,我可以在用户列表和添加用户组件之间建立父子关系吗?我希望能够将道具(用户列表)传递给添加组件并将事件分派回用户列表。
谢谢!
听起来那些 edit/add 路由不应该是子路由,就这么简单。
仅仅因为路径使它看起来像嵌套并不意味着您必须实际嵌套它们。
'/users': {
name: 'user-list',
component(resolve) {
require(['./components/users.vue'], resolve)
}
},
'users/add': {
name: 'add-user',
component(resolve) {
require(['./components/users_add.vue'], resolve)
}
}
所以我玩了很久,终于弄清楚了如何实现。诀窍是让列表也成为一个子路由,并让根级路由只提供一个 <router-view>
容器供所有子组件渲染到其中。然后,将 "list loading" 东西移动到父组件并将列表作为道具传递给列表组件。然后您可以告诉家长通过事件重新加载列表。
暂时就这些了,它就像一个魅力。唯一的缺点是我有另一个我并不真正需要的组件。我会在有时间的时候跟进一个例子。
编辑
按要求添加了示例。请注意:此代码来自 2016 年 - 它可能不适用于当前的 Vue 版本。他们更改了事件系统,因此 parent/child 通信方式有所不同。现在认为双向通信是不好的做法(至少我在这里这样做)。此外,这些天我会以不同的方式解决这个问题,并在商店中为每条路线提供自己的模块。
也就是说,这是我在 2016 年添加的示例:
让我们继续使用用户示例 - 我们有一个页面,您可以使用该页面 list/add/edit 用户。
这是路由定义:
'/users': {
name: 'users',
component(resolve) {
// this is what I meant with "root-level" route, it acts as a parent to the sub routes
require(['./pages/users.vue'], resolve)
},
subRoutes: {
'/': {
name: 'user-list',
component(resolve) {
require(['./pages/users/list.vue'], resolve)
}
},
'/add': {
name: 'user-add',
component(resolve) {
require(['./pages/users/add.vue'], resolve)
}
},
// etc.
}
},
users.vue
<template>
<div>
<router-view :users="users"></router-view>
</div>
</template>
<script>
/**
* This component acts as a parent and sort of state-storage for
* all user child components. It's the route that's loaded at /users.
* the list component is the actual component that is shown though, but since
* that's a sibling of the other child components, we need this.
*/
export default {
events: {
/**
* Update users when child says so
*/
updateUsers() {
this.loadUsers();
}
},
data() {
return {
users: []
}
},
route: {
data() {
// load users from server
if (!this.users.length) {
this.loadUsers();
}
}
},
methods: {
loadUsers() {
// load the users from an API or something
this.users = response.data;
},
}
}
</script>
./pages/users/list.vue
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
<script>
export default {
props: ['users'],
// the rest of the component
}
</script>
我正在使用 vue-router 并且有一个关于 subRoutes 的问题。我想设置我的路线,所以主要路线是列表,子路线是 edit/add/etc.
我想要子路由组件替换父路由的<router-view>
。我理解文档的方式以及我测试过的内容,看起来我应该在父组件模板中定义另一个 <router-view>
以便子路径呈现到其中,但用户列表将保持可见。
示例路线:
'/users': {
name: 'user-list',
component(resolve) {
require(['./components/users.vue'], resolve)
},
subRoutes: {
'/add': {
name: 'add-user',
component(resolve) {
require(['./components/users_add.vue'], resolve)
}
}
}
}
主路由器视图:
<!-- main router view -->
<div id="app">
<router-view></router-view>
</div>
用户列表:
<template>
<a v-link="{ name: 'add-user' }">Add</a>
<ul>
<li>{{ name }}</li>
</ul>
</template>
添加用户:
<template>
<div>
<a v-link="{ name: 'user-list' }">back</a>
<input type="text" v-model="name">
</div>
</template>
当我点击 "Add" 时,我想填充添加用户模板。这可能吗?
另外,我可以在用户列表和添加用户组件之间建立父子关系吗?我希望能够将道具(用户列表)传递给添加组件并将事件分派回用户列表。
谢谢!
听起来那些 edit/add 路由不应该是子路由,就这么简单。
仅仅因为路径使它看起来像嵌套并不意味着您必须实际嵌套它们。
'/users': {
name: 'user-list',
component(resolve) {
require(['./components/users.vue'], resolve)
}
},
'users/add': {
name: 'add-user',
component(resolve) {
require(['./components/users_add.vue'], resolve)
}
}
所以我玩了很久,终于弄清楚了如何实现。诀窍是让列表也成为一个子路由,并让根级路由只提供一个 <router-view>
容器供所有子组件渲染到其中。然后,将 "list loading" 东西移动到父组件并将列表作为道具传递给列表组件。然后您可以告诉家长通过事件重新加载列表。
暂时就这些了,它就像一个魅力。唯一的缺点是我有另一个我并不真正需要的组件。我会在有时间的时候跟进一个例子。
编辑
按要求添加了示例。请注意:此代码来自 2016 年 - 它可能不适用于当前的 Vue 版本。他们更改了事件系统,因此 parent/child 通信方式有所不同。现在认为双向通信是不好的做法(至少我在这里这样做)。此外,这些天我会以不同的方式解决这个问题,并在商店中为每条路线提供自己的模块。
也就是说,这是我在 2016 年添加的示例: 让我们继续使用用户示例 - 我们有一个页面,您可以使用该页面 list/add/edit 用户。
这是路由定义:
'/users': {
name: 'users',
component(resolve) {
// this is what I meant with "root-level" route, it acts as a parent to the sub routes
require(['./pages/users.vue'], resolve)
},
subRoutes: {
'/': {
name: 'user-list',
component(resolve) {
require(['./pages/users/list.vue'], resolve)
}
},
'/add': {
name: 'user-add',
component(resolve) {
require(['./pages/users/add.vue'], resolve)
}
},
// etc.
}
},
users.vue
<template>
<div>
<router-view :users="users"></router-view>
</div>
</template>
<script>
/**
* This component acts as a parent and sort of state-storage for
* all user child components. It's the route that's loaded at /users.
* the list component is the actual component that is shown though, but since
* that's a sibling of the other child components, we need this.
*/
export default {
events: {
/**
* Update users when child says so
*/
updateUsers() {
this.loadUsers();
}
},
data() {
return {
users: []
}
},
route: {
data() {
// load users from server
if (!this.users.length) {
this.loadUsers();
}
}
},
methods: {
loadUsers() {
// load the users from an API or something
this.users = response.data;
},
}
}
</script>
./pages/users/list.vue
<template>
<ul>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
<script>
export default {
props: ['users'],
// the rest of the component
}
</script>