VueRouter爬坑第四篇-命名路由、编程式导航


VueRouter系列的文章示例编写时,项目是使用vue-cli脚手架搭建。

项目搭建的步骤和项目目录专门写了一篇文章:点击这里进行传送

后续VueRouter系列的文章的示例编写均基于该项目环境。


 VueRouter系列文章链接

  《VueRouter爬坑第一篇-简单实践

  《VueRouter爬坑第二篇-动态路由

  《VueRouter爬坑第三篇-嵌套路由

  《VueRouter爬坑第四篇-命名路由、编程式导航》


 阅读目录

一.前言

二.命名路由

三.编程式导航

四.命名路由+$router.push


一.前言

  前面三篇VueRouter系列文章,第一篇我们先是对路由做了一个简单的实践。

  第二篇实践了动态路由的使用;

  第三篇实践了嵌套路由的使用场景和用法;

  本篇文章将实践一下命令路由和编程式导航这两个名词所涵盖的技术点。

二.命名路由

  命名路由,字面意思就是给路由起个名字。

  那给路由起了名字有什么作用呢?

  前面几篇文章中,我们配置<router-link>的to属性值时,设置的是routes中的path。

  那么当我们给路由配置名称后,这个to属性的值就可以设置为路由的名称。

  我们接着上一节演示的那个场景示例,将其使用嵌套路由进行重写。

1.给路由配置名称

  首先呢,我们先在router.js中给路由添加名称

E:\MyStudy\test\VueDemo\src\router\router.js

 1 import Vue from "vue"
 2 import Router from "vue-router"
 3 Vue.use(Router)
 4 
 5 // 引入路由需要映射的组件
 6 import Content from '@/components/Content.vue'
 7 import ProductDetail from '@/components/ProductDetail.vue'
 8 const routes = [
 9     {
10         path: '/products',  
11         name: 'productsRoute',   // 给路由配置名称
12         component: Content, 
13         children:[
14             {
15                 path: '/productDetail/:id', 
16                 name: 'productDetailRoute',  // 给路由配置名称
17                 component: ProductDetail    
18             }
19         ]
20     }
21 ]
22 
23 const router = new Router({
24     routes: routes
25 })
26 
27 export default router

  新增的代码为:11行和16行。

  可以看到,为路由配置名称的语法就是在单条路由配置中添加name属性即可。

2.重写组件中的路由跳转代码

  给路由配置名称后,接着需要做的事情就是修改组件中路由跳转的代码。

  先修改App.vue组件中的路由跳转代码

E:\MyStudy\test\VueDemo\src\App.vue

 1 <template>
 2   <div id="app">
 3     <!-- 菜单  -->
 4     <ul>
 5       <li v-for='(item,index) in menuList' v-bind:key='index' >
 6           <router-link v-bind:to='{name: item.routeName}'>{{item.name}}</router-link>
 7       </li>
 8     </ul>
 9     <!-- 内容区 -->
10     <router-view />
11   </div>
12 </template>
13 
14 <script>
15 export default {
16   name: 'App',
17   data() {
18     return {
19       menuList: [
20         {
21           url: '/index',
22           name: '首页',
23           routeName: 'indexRoute',
24         },{
25           url: '/products',
26           name: '产品',
27           routeName: 'productsRoute',
28         }
29       ]
30     }
31   }
32 }
33 </script>
34 
35 <style>
36 #app {
37   font-family: 'Avenir', Helvetica, Arial, sans-serif;
38   -webkit-font-smoothing: antialiased;
39   -moz-osx-font-smoothing: grayscale;
40   color: #2c3e50;
41 }
42 ul {
43     display: inline-block;
44     width: 100px;
45     border: 1px solid #ddd;
46     padding: 100px 0px 100px 20px;
47     position: fixed;
48     top: -10px;
49     bottom: 0px;
50 }
51 a{
52   text-decoration: none;
53 }
54 </style>

 

  App组件中,修改的代码在第6行,同时新增了22行、26行两行代码。

  核心的代码如下:

<router-link v-bind:to='{name: item.routeName}'>{{item.name}}</router-link>

 

  接着是Content.vue组件

E:\MyStudy\test\VueDemo\src\Components\Content.vue

 1 <template>
 2     <div class='productContent'> 
 3         <div class="productList">
 4             <!-- 产品列表  -->
 5             <h1>产品列表</h1>
 6             <p v-for="(item,index) in productsList" v-bind:key='index'> 
 7                 <router-link v-bind:to="{name: item.routeName,params:{id:index+1}}">{{item.name}}</router-link>
 8             </p> 
 9         </div>
10         <!-- 产品详情 -->
11         <router-view />
12     </div>
13 </template>
14 <script>
15 export default {
16     name: 'Content',
17     data() {
18         return {
19             productsList: [
20                 {
21                     url: '/productDetail/1',
22                     name: '产品1',
23                     routeName: 'productDetailRoute'
24                 },{
25                     url: '/productDetail/2',
26                     name: '产品2',
27                     routeName: 'productDetailRoute'
28                 }
29             ]
30         }
31     }
32 
33 }
34 </script>
35 <style scoped>
36     .productContent{
37         margin-left: 150px;
38     }
39     .productList{
40         border:1px solid #ddd;
41         margin: 10px;
42     }
43 </style>

  Content.vue组件中,修改了第7行的代码,同时新增22行、26行两行代码。

  核心的代码如下:

<router-link v-bind:to="{name: item.routeName,params:{id:index+1}}">{{item.name}}</router-link>

  ProductDetail.vue组件没有修改。

 

  这里呢,总结一下:

  1.route.js中配置路由名称使用name选项

  2.route-link使用name时,需要使用字典{name: '路由名称'},而不能直接向使用path一样绑定一个字符串

  3.route-link编写动态路由的动态参数使用params设置

  

  代码修改完成,查看结果:

  

  可以看到,结果和之前的一样。

三.编程式导航

  在前面几篇VueRouter的学习过程中,我们一直使用的是<router-link>编写可跳转的URL。

  官方文档把这种方式成为声明式的导航

  而另外一种可以与之替代的就是编程式导航:使用router实例的push方法实现URL跳转

还是嵌套路由这个示例router.js不做修改,依然是前面的代码

1.将App组件中的route-link改为router.push实现

E:\MyStudy\test\VueDemo\src\App.vue

 1 <template>
 2   <div id="app">
 3     <!-- 菜单  -->
 4     <ul>
 5       <li v-for='(item,index) in menuList' v-bind:key='index' >
 6           <p v-on:click='menuHandler(item.url)'> {{ item.name }}</p>
 7       </li>
 8     </ul>
 9     <!-- 内容区 -->
10     <router-view />
11   </div>
12 </template>
13 
14 <script>
15 export default {
16   name: 'App',
17   data() {
18     return {
19       menuList: [
20         {
21           url: 'index',
22           name: '首页',
23           routeName: 'indexRoute',
24         },{
25           url: 'products',
26           name: '产品',
27           routeName: 'productsRoute',
28         }
29       ]
30     }
31   },
32   methods: {
33     menuHandler: function(url){
34       this.$router.push(url);   //或者$router.push(url);
35     }
36   }
37 }
38 </script>
39 
40 <style>
41 #app {
42   font-family: 'Avenir', Helvetica, Arial, sans-serif;
43   -webkit-font-smoothing: antialiased;
44   -moz-osx-font-smoothing: grayscale;
45   color: #2c3e50;
46 }
47 ul {
48     display: inline-block;
49     width: 100px;
50     border: 1px solid #ddd;
51     padding: 100px 0px 100px 20px;
52     position: fixed;
53     top: -10px;
54     bottom: 0px;
55 }
56 li{
57   cursor: pointer;
58 }
59 a{
60   text-decoration: none;
61 }
62 </style>

App.vue组件中修改了第6行的代码;同时新增了一个methods:menuHandler处理菜单点击的逻辑。

  menuHandler函数中的逻辑就是vue编程式导航的实现代码

  App组件中的修改总结一下:

    menuHandler方法中的this.$router.push(url)代码,它和$router.push(url)是等价的。

    而且当我们给push传入一个字符串参数时,默认是传递的值是url,匹配的就是routes中的path参数

    因此menuHandler方法中的逻辑也可以写成this.$router.push({path:url})或者$router.push({path:url}) 

 

2.Content组件中的route-link改为router.push实现

E:\MyStudy\test\VueDemo\src\Components\Content.vue

 1 <template>
 2     <div class='productContent'> 
 3         <div class="productList">
 4             <!-- 产品列表  -->
 5             <h1>产品列表</h1>
 6             <p v-for="(item,index) in productsList" v-bind:key='index' v-on:click='productHandle(index)'> 
 7                 {{item.name}}
 8             </p> 
 9         </div>
10         <!-- 产品详情 -->
11         <router-view />
12     </div>
13 </template>
14 <script>
15 export default {
16     name: 'Content',
17     data() {
18         return {
19             productsList: [
20                 {
21                     url: '/productDetail/1',
22                     name: '产品1',
23                     routeName: 'productDetailRoute'
24                 },{
25                     url: '/productDetail/2',
26                     name: '产品2',
27                     routeName: 'productDetailRoute'
28                 }
29             ]
30         }
31     },
32     methods: {
33         productHandle: function(index) {
34             var id = index+1;
35             this.$router.push('/productDetail/'+id); //或者$router.push('/productDetail/'+id);
36         }
37     }
38 
39 }
40 </script>
41 <style scoped>
42     .productContent{
43         margin-left: 150px;
44     }
45     .productList{
46         border:1px solid #ddd;
47         margin: 10px;
48     }
49     p{
50         cursor: pointer;
51     }
52 </style>

     Content.vue组件编程式导航写法为:this.$router.push('/productDetail/'+id);

  其中默认传递的字符串参数匹配的是路由配置中的path

  因此this.$router.push('/productDetail/'+id)也可以是如下写法:

    this.$router.push({path: '/productDetail/'+id);

  注意:

  当使用path去匹配路由的时候,params这个参数是不生效的。

  因此this.$router.push({path: 'productDetail',params:{id:id})这种写法是无效的。

  

  代码修改完成,我们还是来看下结果对不对

  

  可以看到,和前面命令式写法、路由命名这两个是相同的结果。

四.命令路由+$router.push

  vuerouter系列的前三篇文章中,我们使用路由配置的path选项结合声明式导航<router-link>实现路由跳转。

  本篇中先是使用路由配置中的name结合声明式导航<router-link>实现路由跳转。

  接着实践了编程式导航$router.push并匹配路由配置中的path实现路由跳转。

  那么在排列组合一下,我们就在实践一下编程式导航$router.push结合命令路由实现路由跳转。

E:\MyStudy\test\VueDemo\src\App.vue

<template>
  <div id="app">
    <!-- 菜单  -->
    <ul>
      <li v-for='(item,index) in menuList' v-bind:key='index' >
          <p v-on:click='menuHandler(item.url)'> {{ item.name }}</p>
      </li>
    </ul>
    <!-- 内容区 -->
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      menuList: [
        {
          url: 'index',
          name: '首页',
          routeName: 'indexRoute',
        },{
          url: 'products',
          name: '产品',
          routeName: 'productsRoute',
        }
      ]
    }
  },
  methods: {
    menuHandler: function(url){
      //使用命名路由
      this.$router.push({name:'productsRoute'})
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}
ul {
    display: inline-block;
    width: 100px;
    border: 1px solid #ddd;
    padding: 100px 0px 100px 20px;
    position: fixed;
    top: -10px;
    bottom: 0px;
}
li{
  cursor: pointer;
}
a{
  text-decoration: none;
}
</style>

 

  核心代码如下:

menuHandler: function(url){
     //使用命名路由
    this.$router.push({name:'productsRoute'})
}

 

E:\MyStudy\test\VueDemo\src\Components\Content.vue

 1 <template>
 2     <div class='productContent'> 
 3         <div class="productList">
 4             <!-- 产品列表  -->
 5             <h1>产品列表</h1>
 6             <p v-for="(item,index) in productsList" v-bind:key='index' v-on:click='productHandle(index)'> 
 7                 {{item.name}}
 8             </p> 
 9         </div>
10         <!-- 产品详情 -->
11         <router-view />
12     </div>
13 </template>
14 <script>
15 export default {
16     name: 'Content',
17     data() {
18         return {
19             productsList: [
20                 {
21                     url: '/productDetail/1',
22                     name: '产品1',
23                     routeName: 'productDetailRoute'
24                 },{
25                     url: '/productDetail/2',
26                     name: '产品2',
27                     routeName: 'productDetailRoute'
28                 }
29             ]
30         }
31     },
32     methods: {
33         productHandle: function(index) {
34             var id = index+1;
35             //使用命令路由
36             this.$router.push({name:'productDetailRoute', params: {id: id}})
37         }
38     }
39 
40 }
41 </script>
42 <style scoped>
43     .productContent{
44         margin-left: 150px;
45     }
46     .productList{
47         border:1px solid #ddd;
48         margin: 10px;
49     }
50     p{
51         cursor: pointer;
52     }
53 </style>

 

  核心代码如下:

productHandle: function(index) {
     var id = index+1;
      //使用命令路由
      this.$router.push({name:'productDetailRoute', params: {id: id}})
}

  关于这两个组件的核心代码我已分别贴出,比较简单这里就不多说了。

  最后的结果也和前面一致。

  

  到此本篇文章完!

 


posted @ 2020-01-15 18:50  小土豆biubiubiu  阅读(733)  评论(0编辑  收藏  举报