Vue-Router 嵌套路由(多级路由)

应用场景:应用中组件存在多层嵌套组合的关系。

by logan70

HTML

<script src="https://cdn.bootcss.com/vue/2.5.17/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>

<div id="app">
  <h1>Vue-Router 嵌套路由(多级路由)</h1>
  <input type="text" v-model="userId">
  <button @click="$router.push(`/user/${userId}`)">查询用户</button>
  <p>
    <!-- 路由导航,to属性决定导航地址 -->
    <!-- router-link编译后默认渲染为a标签 -->
    <router-link to="/user/1">1号用户</router-link>
    <router-link to="/user/2">2号用户</router-link>
  </p>
  <!-- 路由渲染出口 -->
  <router-view></router-view>
</div>

JavaScript

const User = {
	// 在渲染组件内插入嵌套的<router-link>及<router-view>
	template: `
  	<div>
    	<p>这是User组件。</p>
      <p>用户ID:{{$route.params.id}}</p>
      <p v-html="msg"></p>
      <p>
        <router-link :to="'/user/' + $route.params.id + '/a'">嵌套组件A</router-link>
        <router-link :to="'/user/' + $route.params.id + '/b'">嵌套组件B</router-link>
      </p>
      <router-view></router-view>
    </div>`,
  data() {
  	return {
    	nameDB: {
      	1: '乌木喂喂威 恩耶吞温威 乌温穆补 欧萨斯',
        2: '布里秋秋 迪不利多'
      },
      msg: ''
    }
  },
  // 路由独享的导航守卫
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`,通过传回调给 next并把组件实例作为回调方法的参数来访问组件实例
    next(vm => {
      vm.getUserName(to.params.id)
      vm.msg += '<br/>路由进入前(beforeRouteEnter)触发'
    })
  },
  // 路由独享的导航守卫
  beforeRouteUpdate(to, from, next) {
  	// 在当前路由改变,但是该组件被复用时调用
  	this.getUserName(to.params.id)
  	this.msg += '<br/>路由更新前(beforeRouteUpdate)触发'
    next()
  },
  methods: {
  	getUserName(id) {
    	this.msg = this.nameDB[id] ? ('用户名:' + this.nameDB[id]) : id + '号用户用户名未设置'
    }
  }
}

// 嵌套组件
const ChildA = {template: '<div><p>这是{{$route.params.id}}号用户的嵌套组件A。</p></div>'}
const ChildB = {template: '<div><p>这是{{$route.params.id}}号用户的嵌套组件B。</p></div>'}

const router = new VueRouter({
  routes : [
    {
    	path: '/user/:id',
      component: User,
      children: [
      	{path: 'a', component: ChildA},
      	{path: 'b', component: ChildB},
      ]
    },
    { path: '/', redirect: '/user/1'}
  ]
})

const app = new Vue({
  router,
  data() {
  	return {
    	userId: 1
    }
  },
  methods: {
    queryUser(id) {
    	this.$router.push(`/user/${id}`)
    }
  }
}).$mount('#app')