Vue_Router

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();
        }
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容