zoukankan      html  css  js  c++  java
  • Vue路由(vue-router)详细讲解指南

    转自:https://www.cnblogs.com/dengyao-blogs/p/11562257.html

    中文文档:https://router.vuejs.org/zh/

    Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。路由实际上就是可以理解为指向,就是我在页面上点击一个按钮需要跳转到对应的页面,这就是路由跳转;

    首先我们来学习三个单词(route,routes,router):

      route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;

      routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;

      router:译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由;

    我们结合一个小demo来看(文章有点长,耐心慢慢看,学得慢才能进步的快,当然可以跟着一起敲):

      首先需要安装vue-cli来构建一个vue的开发环境(怎么安装这里不讲,自己百度去,如果这种问题自己都解决不了的话,后面的知识可能对你来说收益不大)

      安装完vue-cli之后,我们的项目目录结构如下:

       

       然后我们在命令行中输入npm install vue-router -g来安装vue-router,安装完之后我们可以打开package.json文件,在package.json文件中可以看到vue-router的版本号;

     到这一步我们的准备工作就完成了,要进行写demo了;

    我们在src目录下新建三个文件,分别为page1.vue和page2.vue以及router.js:

    page1.vue:

    <template>
        <div>
            <h1>page1</h1>
            <p>{{msg}}</p>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {
                    msg: "我是page1组件"
                }
            }
        }
    </script>

     page2.vue:

    <template>
        <div>
            <h1>page2</h1>
            <p>{{msg}}</p>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {
                    msg: "我是page2组件"
                }
            }
        }
    </script>

    router.js

    //引入vue
    import Vue from 'vue';
    //引入vue-router
    import VueRouter from 'vue-router';
    //第三方库需要use一下才能用
    Vue.use(VueRouter)
    //引用page1页面
    import page1  from './page1.vue';
    //引用page2页面
    import page2  from './page2.vue';
    
    //定义routes路由的集合,数组类型
    const routes=[
        //单个路由均为对象类型,path代表的是路径,component代表组件
        {path:'/page1',component:page1},
        {path:"/page2",component:page2}
    ]
    
    //实例化VueRouter并将routes添加进去
    const router=new VueRouter({
    //ES6简写,等于routes:routes
        routes
    });
    
    //抛出这个这个实例对象方便外部读取以及访问
    export default router

    这里我们再修改一下main.js

    import Vue from 'vue'
    import App from './App'
    //引用router.js
    import router from './router.js'
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
    //一定要注入到vue的实例对象上
      router,
      components: { App },
      template: '<App/>'
    })

    修改App.vue

      

    <template>
      <div id="app">
        <img src="./assets/logo.png">
        <div>
    //router-link定义页面中点击触发部分  
          <router-link to="/page1">Page1</router-link>
          <router-link to="/page2">Page2</router-link>
        </div>
    //router-view定义页面中显示部分
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    就这样,我们的页面就可以进行路由跳转和切换了,路由的基本使用就完成了;但是有个问题就是我们第一次进去是看不到路由页面的,这是因为我们没有设置默认值,我们首次进入的时候路径是为空的,那么我们可以这么解决:

    router.js

    import Vue from 'vue';
    import VueRouter from 'vue-router';
    Vue.use(VueRouter)
    import page1  from './page1.vue';
    import page2  from './page2.vue';
    import user   from './user.vue'
    
    const routes=[
        {path:'/page1',component:page1},
        {path:"/page2",component:page2},
        //可以配置重定向
        {path:'',redirect:"page1"}
        //或者重新写个路径为空的路由
        {path:"",component:page1}
    ]
    
    const router=new VueRouter({
        routes
    });
    
    export default router

    上面的两种解决方案都是可以解决的,配置重定向的意思就是当匹配到路径为空的时候,就会重定向到page1,执行page1的路由;或者我们也可以重新配置个路由,路径为空的时候router-view展示page1的页面;

    用重定向和单独配置路由的区别:

      重定向实际上是当匹配到路径符合条件的时候去执行对应的路由,当然这个时候的url上面的地址显示的是对应的路由,页面也是对应的路由页面;

      重新配置路由是当匹配到路径符合条件的时候,router-view页面展示部分负责拿符合条件路由的页面来展示,实际上url是没有发生变化的;

    那么还有些复杂情况,是基本路由实现不了的;我们来接着往下看

    动态路由匹配:

      其实我们的生活中有很多这样的例子,不知道大家留意没有?比如一个网站或者后台管理系统中,在我们登录之后,是不是通常会有一个欢迎回来,XXX之类的提示语,这个我们就可以通过动态路由来实现这个效果;

    首先在src目录下新建一个user.vue文件:

    <template>
        <div>
            <h1>user</h1>
           //这里可以通过$route.params.name来获取路由的参数
            <p>欢迎回来,{{$route.params.name}}</p>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {
                    msg: "我是page1组件"
                }
            }
        }
    </script>

    然后我们修改App.vue文件的代码:

    <template>
      <div id="app">
        <img src="./assets/logo.png">
        <div>
          <router-link to="/page1">Page1</router-link>
          <router-link to="/page2">Page2</router-link>
        </div>
    
    //添加两个router-link标签
        <div>
          <router-link to="/user/xianyu">动态路由咸鱼</router-link>
          <router-link to="/user/mengxiang">动态路由梦想</router-link>
        </div>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    修改我们的router.js

    import Vue from 'vue';
    import VueRouter from 'vue-router';
    Vue.use(VueRouter)
    import page1  from './page1.vue';
    import page2  from './page2.vue';
    import user   from './user.vue'
    
    const routes=[
        {path:'/page1',component:page1},
        {path:"/page2",component:page2},
        // {path:'',redirect:"page1"}
        {path:"",component:page1},
     //使用冒号标记,当匹配到的时候,参数值会被设置到this.$route.params中
        {path:"/user/:name",component:user}
        
    ]
    
    const router=new VueRouter({
        routes
    });
    
    export default router

    配置好了,不出意外是能正常运行的,我们来看一下效果:

     动态路由匹配给我们提供了方便,使得我们通过配置一个路由来实现页面局部修改的效果,给用户造成一种多个页面的感觉,是不是很酷!!!

    酷的同时也会给我们带来一些问题,因为使用路由参数时,从/user/xianyu导航到/user/mengxiang,原来的组件实例会被复用,两个路由都渲染同个组件,比起销毁再创建,显示复用显得效率更高,带来的的只管问题就是生命周期钩子函数不会再被调用,也就是不会再被触发;但是办法总比问题多,我们可以通过监听$route对象来实现;

    修改user.vue的代码

    <template>
        <div>
            <h1>user</h1>
            <p>欢迎回来,{{msg}}</p>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {
                    // msg: "我是page1组件"
                    msg:""
                }
            },
            watch:{
    //to表示即将要进入的那个组件,from表示从哪个组件过来的
                $route(to,from){
                    this.msg=to.params.name; 
                    console.log(111);
                }
            }
        }
    </script>

    效果图如下:

     我们可以很明显的看到我们监听的$route对象被触发了,控制台也输出了;

    下面我们来一起看一下嵌套路由:

      嵌套路由:

        很多时候我们的页面结构决定了我们可能需要嵌套路由,比如当我们进入主页之后有分类,然后当选择其中一个分类之后进入对应的详情,这个时候我们就可以用到嵌套路由;官方文档中给我们提供了一个children属性,这个属性是一个数组类型,里面实际放着一组路由;这个时候父子关系结构就出来了,所以children属性里面的是路由相对来说是children属性外部路由的子路由;

    好记性不如烂代码,让我们通过代码来看一看:

      首先在我们的src目录下新建两个vue文件,分别是phone.vue和computer.vue

      phone.vue

    <template>
        <div>
            <p>{{msg}}</p>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {
                    msg: "嵌套手机组件"
                }
            }
        }
    </script>

      computer.vue

    <template>
        <div>
            <p>{{msg}}</p>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {
                    msg: "嵌套电脑组件"
                }
            }
        }
    </script>

    然后我们再修改我们的App.vue文件:

    <template>
      <div id="app">
        <img src="./assets/logo.png">
        <div>
          <router-link to="/page1">Page1</router-link>
        </div>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
    #app {
      font-family: 'Avenir', Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>

    通过上面的App.vue文件我们可以看到,我们此时页面只有一个page1的标签了;

    我们再来修改router.js

    import Vue from 'vue';
    import VueRouter from 'vue-router';
    Vue.use(VueRouter)
    import page1  from './page1.vue';
    import page2  from './page2.vue';
    import user   from './user.vue';
    import phone  from './phone.vue';
    import computer from './computer.vue'
    
    const routes=[
        {
            path:'/page1',
            component:page1,
            children: [
                {
                    path: "phone",
                    component: phone
                },
                {
                    path: "computer",
                    component: computer
                },
            ]
        },
        // {path:"/page2",component:page2},
        // // {path:'',redirect:"page1"}
        // {path:"",component:page1},
        // {path:"/user/:name",component:user}
        
    ]
    
    const router=new VueRouter({
        routes
    });
    
    export default router

    为了大家看的直观点,其他路由全部注释了,页面只剩下/page1这一个路由了;

    上面说到了,children属性其实就是一个子路由集合,数组结构里面放着子路由;

    效果图如下:

     路由导航两种方式:

      标签导航:标签导航<router-link><router-link>是通过转义为<a></a>标签进行跳转,其中router-link标签中的to属性会被转义为a标签中的href属性;

    //跳转到名为user路由,并传递参数userId
    <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

      编程式导航:我们可以通过this.$router.push()这个方法来实现编程式导航,当然也可以实现参数传递,这种编程式导航一般是用于按钮点击之后跳转

    router.push({ name: 'user', params: { userId: 123 }})

    这两者都会把路由导航到user/123路径

    命名路由:

      有的时候,通过一个名称来标识一个路由显得更方便一些,所以官方为了方便我们偷懒,又给我们在路由中添加了一个name属性,命名这个属性之后我们访问这个属性就等于直接访问到路由;

      普通路由:

    router.push({ path: '/user/:userId', params: { userId: 123 }})

      命名路由:

    router.push({ name: 'user', params: { userId: 123 }})

    其实两者并没有什么区别,只是提供了两种方式来访问路由,可以通过路径来匹配也可以通过别名来匹配;

  • 相关阅读:
    [译文] 实体与值对象到底是不是一回事?
    实现 WebApi 自托管服务宿主于 WinForms 及其交互
    [译文] C# 8 已成旧闻, 向前, 抵达 C# 9!
    [译文] 为什么你在 C# 里总是应该使用 "var" 关键字
    通过设置iis在局域网中访问网页
    windows 10 安装使用kafka
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 2) 定义命名化和类型化的客户端
    Asp.net Core 2.0 OpenId Connect Handler缺失Claims?
  • 原文地址:https://www.cnblogs.com/linwenbin/p/13917564.html
Copyright © 2011-2022 走看看