vue-router用subRoute替换父视图

Chr*_*tof 4 javascript vue.js vue-router

我正在使用vue-router,对子路由有疑问。我想设置路由,以便主要路由是列表,子路由是诸如edit / add / etc之类的东西。

我希望subRoute组件替换<router-view>父路由。从我对文档的理解以及经过测试的方式来看,我似乎应该<router-view>在父组件模板中为要呈现给subRoute的模板定义另一个,但是用户列表仍然可见。

路线示例:

'/users': {
    name: 'user-list',
    component(resolve) {
        require(['./components/users.vue'], resolve)
    },
    subRoutes: {
        '/add': {
            name: 'add-user',
            component(resolve) {
                require(['./components/users_add.vue'], resolve)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

主路由器视图:

<!-- main router view -->
<div id="app">
    <router-view></router-view>
</div>
Run Code Online (Sandbox Code Playgroud)

用户列表:

<template>
    <a v-link="{ name: 'add-user' }">Add</a>
    <ul>
        <li>{{ name }}</li>
    </ul>
</template>
Run Code Online (Sandbox Code Playgroud)

添加用户:

<template>
    <div>
        <a v-link="{ name: 'user-list' }">back</a>
        <input type="text" v-model="name">
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)

当我点击“添加”时,我想被添加用户模板所填充。这可能吗?

另外,我可以在用户列表和添加用户组件之间建立父子关系吗?我希望能够将道具(用户列表)传递给add组件,并将事件分派回用户列表。

谢谢!

Lin*_*org 5

听起来那些编辑/添加路由不应该是subRoutes,就这么简单。

仅仅因为该路径使它看起来像嵌套,并不意味着您必须实际嵌套它们。

'/users': {
    name: 'user-list',
    component(resolve) {
      require(['./components/users.vue'], resolve)
    }
},
'users/add': {
    name: 'add-user',
    component(resolve) {
      require(['./components/users_add.vue'], resolve)
    }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*tof 3

所以我对此进行了相当多的研究,终于弄清楚了如何实现这一点。技巧是让列表也成为子路由,并让根级路由只<router-view>为所有子组件提供一个容器来渲染。然后,将“列表加载”内容移至父组件,并将列表作为 prop 传递给列表组件。然后,您可以告诉父级通过事件重新加载列表。

现在就是这样,它就像一个魅力。唯一的缺点是我还有另一个我并不真正需要的组件。当我有时间的时候,我会继续举一个例子。

编辑

根据要求添加了一个示例。请注意:此代码来自 2016 年 - 它可能不适用于当前的 Vue 版本。他们改变了事件系统,因此父母/孩子的沟通方式有所不同。现在,双向沟通被认为是不好的做法(至少是我在这里这样做的方式)。另外,这些天我会以不同的方式解决这个问题,并在商店中为每条路线提供自己的模块。

也就是说,这是我在 2016 年添加的示例:让我们继续使用用户示例 - 我们有一个页面,您可以在其中列出/添加/编辑用户。

这是路线定义:

'/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.
    }
},
Run Code Online (Sandbox Code Playgroud)

用户.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>
Run Code Online (Sandbox Code Playgroud)

./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>
Run Code Online (Sandbox Code Playgroud)