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 }})

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

  • 相关阅读:
    HTML ASCII 参考手册
    linux给用户赋予root权限
    Oracle系列教程之一软件安装与卸载
    Office VBA 参考
    Web API 接口参考
    maven setting.xml
    maven仓库网址
    The chance for love doesn't come around every day.
    webstrom使用vue-cli时 遇到的一些问题
    vue2.0 + webpack2.0 配置
  • 原文地址:https://www.cnblogs.com/linwenbin/p/13917564.html
Copyright © 2011-2022 走看看