Vue_Router

作者: learninginto | 来源:发表于2020-02-19 23:52 被阅读0次

    Vue_Router

    Vue Router 和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。根据用户请求的路径不同的页面,并返回不同的数据

    一、路由的分离

    • 前端路由

    根据用户请求不同的url来展示不同的页面或者数据,前端路由不会涉及到后端请求,页面不会刷新。用户体验较好,一般用来做单页面开发(SPA)。

    前端路由的底层原理:hashchange和H5中history API中的popState和replaceState来进行实现的。

    • 后端路由

    根据用户请求的路径来返回不同的数据或者页面,后端路由一般情况下都是用来做接口的,通过ajax请求的路径来返回相对应的数据。

    二、Vue中路由的常用配置项

    • mode

    配置路由的模式,可选择:"hash"(默认) | "history" | "abstract"

    • routes数组

    数组中有N多个对象,每个对象都是一个路由的配置项

    path : 匹配路由的路径

    component : 路由路径匹配成功以后会显示相应的组件

    redirect : 路由重定向

    children:路由嵌套

    meta : 路由元信息(路由携带的一些独有信息)

    • Vue路由的内置组件

    当VueRouter挂载到vm实例上时,会多出两个内置组件:

    1. router-view : 渲染路由匹配的组件,可结合其他组件使用:
    <transition>
      <keep-alive>
        <router-view></router-view>
      </keep-alive>
    </transition>
    
    1. router-link : 路由的跳转导航,底层原理用a标签实现的,属性内置组件。具有如下属性:

      to属性指向目标地址,tag指定渲染之后的标签

    注:一般情况下,当router-view写在根组件中时,这些页面都是一级路由。

    三、Vue中使用插件的流程

    • 安装
    cnpm install vue-router -S
    
    • 创建router文件夹并创建index.js文件

    • 引入Vue和vue-router进行配置使用

    import Vue from "vue";
    import VueRouter from "vue-router";
    Vue.use(VueRouter);
    let router = new VueRouter({
    
    })
    export default router
    
    • 在入口文件main.js中引入,并挂载到vue上
    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router"
    
    new Vue({
       router,
       render:h=>h(App)
    }).$mount("#app")
    

    四、路由跳转的方式有哪些?

    1. hash路由调整<a></a>
    2. router-link
    3. 编程式导航(JS)

    五、路由传值

    不同的页面之间需要相互传递数据进行数据的请求或数据的渲染,因此需要路由传值。

    • 动态路由传值
    1. 在定义路由的时候,在path路径处通过/:属性的方式来定义传递参数的属性。

      eg : path:"/detail/:goodsName/:goodsPrice"

    2. 在路径跳转的地方通过/值传值

      eg : <router-link :to="'/detail/'+item.name+'/'+item.price">{{item.name}}</router-link>

    3. 在接收参数的页面,通过this.$route.params的方式接收

    created(){
        var { goodsName, goodsPrice } = this.$route.params;
        this.goodsName = goodsName;
        this.goodsPrice = goodsPrice;
    }
    
    • query传值

    通过url地址进行拼接,将数据传递给另一个路由

    1. 在路由跳转的时候,通过路径?key=value&key=value的方式将数据进行传值

      <router-link :to="'/detail?goodsName='+item.name+'&goodsPrice='+item.price">{{item.name}}</router-link>
      //或
      <router-link :to="{name:'detail',query:{goodsName:item.name,goodsPrice:item.price}}">{{item.name}}</router-link>
      
      
    2. 在需要接收参数的页面,通过this.$route.query的方式进行接收

      created(){
          var { goodsName, goodsPrice } = this.$route.query;
          this.goodsName = goodsName;
          this.goodsPrice = goodsPrice;
      }
      
    • 动态路由和query传值之间的区别
    1. 动态路由传值,值是必须传递的 ; 而query传值,值是非必须的

    2. 动态路由在url中只会显示属性值(eg:detail/lxc/18),而query则会显示属性值和属性名(eg:detail?userName=lxc&age=18

    • 路由解耦(只使用于动态路由)
    1. 在定义路由的时候,添加一个props属性为true,在path路径处通过/:属性的方式来定义传递参数的属性。

      {
          path:"/detail/:goodsName/:goodsPrice",
          component:Detail,
          name:"detail",
          props:true
      }
      
    2. 在路径跳转的地方通过/值传值

      <router-link :to="{name:'detail',params:{goodsName:item.name,goodsPrice:item.price}}">{{item.name}}</router-link>
      
    3. 在接收参数的页面,通过this.$route.params的方式进行接收

    4. 在需要接收参数的页面,通过props来进行接收

      eg : props: ["goodsName", "goodsPrice"]

    • 编程式导航传值

    通过JS的方式进行路由的跳转

    1. this.$router.push()

      eg : this.$router.push("/detail/"+name+'/'+price)

    2. this.$router.go(n)

    3. this.$router.back()

    4. this.$router.forward()

    5. this.$router.replace()

    这里的前进后退方法要依赖于浏览器的浏览历史记录

    • 嵌套路由(二级路由)

    需要在base.config.js中配置文件别名:

    resolve: {
        extensions: [".vue", ".js"],
    
        //别名的配置
        alias: {
            "@": path.join(__dirname, "../src"),
            "@views": path.join(__dirname, "../src/views"),
            "@assets": path.join(__dirname, "../src/assets"),
            "@common": path.join(__dirname, "../src/common"),
            "@components": path.join(__dirname, "../src/components"),
            "@pages": path.join(__dirname, "../src/pages"),
            "@router": path.join(__dirname, "../src/router"),
            "@store": path.join(__dirname, "../src/store"),
            "@utils": path.join(__dirname, "../src/utils"),
            "@api": path.join(__dirname, "../src/api"),
        }
    },
    
    • 配置二级路由
    export default {
        path: "/movie",
        component: () => import('@views/movie'),
        name: "movie",
        meta: {
            flag: true
        },
    
        children: [
            {
                path: "/movie",
                redirect: "/movie/nowPlaying"
            },
    
            {
                path: 'nowPlaying',
                component:(resolve)=>require(["@/components/nowPlaying"], resolve),
                name: "nowPlaying",
                meta: {
                    flag: true
                },
            },
    
            {
                path: 'comingSoon',
                component: () => import('@components/comingSoon'),
                name: "coming",
                meta: {
                    flag: true
                }
            },
        ]
    }
    
    • 异步组件

    Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。

    上面的例子中用到了require和import(推荐)两种方式。

    六、路由的生命周期

    路由守卫,路由跳转前后的一些验证

    1. 全局的路由生命周期
    • beforeEach

      注意:局部的路由守卫是在组件内部进行使用的,而全局的路由守卫是在路由的配置项中去使用的。

      eg : 在路由配置需要验证的页面,meta属性中添加配置:requiredAuth:true

      router.beforeEach((to,from,next)=>{
          document.title = to.meta.title;
          if(to.meta.requiredAuth){
              var token = localStorage.getItem("token");
              if(token){
                  next();
              }else{
                  next({name:"login",params:{toPath:to.path}})
              }
          }else{
              next();
          }
      })
      
    1. 局部的路由生命周期

      • beforeRouteEnter进入时(在beforeCreate创建之前)

      参数:

      1. to : 即将要进入的目标(路由要到哪里去)
      2. from : 当前导航正要离开的路由(路由从哪里来)
      3. next : 必须要调用,进行管道中的下一个钩子。否则路由对应的组件不会渲染。
      beforeRouteEnter(to,from,next){
          console.log("路由进入",to,from,next);
          next();
      }
      

      使用场景:

      1. 验证用户是否登录

        beforeRouteEnter(to,from,next){
            if(to.meta.requiredAuth){
                var token = localStorage.getItem("token");
                if(token){
                    next();
                }else{
                    //跳转到登录页面
                    next((vm)=>{
                        this.router.push("/login");
                    })
                }
            }else{
                next();
            }
        }
        
      2. 验证用户的VIP是否到期/剩余时间

      3. 用户权限

      4. 消息提示

      • beforeRouteUpdate更新时

      当路由更新的时候会触发的守卫,一般情况下,在组件没有经历创建和销毁,但是路由发生改变时之后

      beforeRouteUpdate(to,from,next){
             var {name} = to.params;
             this.goodsName = name;
             next();
      }
      
      • 通过watch的方式监听
      watch:{
             "$route":{
                 handle(){
                     var {name} = to.params;
                     this.goodsName = name;
                 }
             }
      }
      
      • beforeRouteLeave离开时

      使用场景:

      1. 用户未支付
      2. 答题系统
      3. 记录历史记录
      4. 注销、切换账号
      beforeRouterLeave(to,from,next){
          var flag = confirm("确定要离开当前页面吗?");
          if(flag){
              next();
          }
      }
      

    相关文章

      网友评论

        本文标题:Vue_Router

        本文链接:https://www.haomeiwen.com/subject/sfqtqhtx.html