zoukankan      html  css  js  c++  java
  • vue-router详解

    路由(vue-router)


    现在的应用都流行SPA应用(single page application)

    传统的项目大多使用多页面结构,需要切换内容的时候我们往往会进行单个HTML文件的跳转,这个时候网络、性能影响,浏览器会出现不定时间的空白界面,用户体验不好

    单页面应用就是用户通过某些操作地址栏url之后,动态的进行不同模板内容的无刷新切换,用户体验好。

    Vue中会使用官方提供的vue-router插件来使用单页面,原理就是通过检测地址栏变化后对应的路由组件进行切换(卸载和安装)
     

    简单路由实现

    cnpm install vue-router -S  or yarn add vue-router

    在Vue中,$router指向的是大路由,routes是路由配置数组, $route指向的是当前活跃的路由。

    1.引入vue-router,如果是在脚手架中,引入VueRouter之后,需要通过Vue.use来注册插件
    router/index.js文件

    import Vue from 'vue'
    import Router from 'vue-router'
    Vue.use(Router)

    2.创建router路由器

    new Router({
        routes:[
            {path:"/home",component:Home}
        ]
    })

    3.创建路由表并配置在路由器中

    var routes =[
        {path,component}//path为路径,component为路劲对应的路由组件
    ]

    var router = new Router({
        routes
    })

    export default router

    4.在根实例里注入router,目的是为了让所有的组件里都能通过this.$router、this.$route来使用路由的相关功能api

    import router from "./router"
    new Vue({
        el:"#app",
        router, //注册一下  让组件可以通过this.$router or this.$route 使用路由相关的api属性或方法
        template:"<App/>",
        components:{App}
    })

    5. 利用router-view来指定路由切换的位置
    6. 时候router-link来创建切换的工具,会渲染成a标签,添加to属性来设置更改的path信息,且会根据当前路由的变化为a标签添加对应的router-link-active/router-link-exact-active(完全匹配成功)类名

    <router-link to="/main">main</router-link>
    <router-link to="/news">news</router-link>

    .router-link-active{
        color:red;
    }

    路由的懒加载


    懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,坚守首页加载用时。

    非按需加载则会把所有的路由组件块的js打包在一起。当业务包很大的时候建议用路由的按需加载(懒加载)。
    按需加载会在页面第一次请求的时候,把相关路由组件块的js添加上:

    {
        path:'/about',
        name:'about',
        component:()=>import('@/views/About') //采用了路由懒加载方式
    }

    多级路由

    在创建路由表的时候,可以为每一个路由对象创建children属性,值为数组,在这个里面又可以配置一些路由对象来使用多极路由,注意:一级路由path前加“/"

    const routes =[
        {path:"/main",component:AppMain},
        {path:"/news",component:AppNews,children:[
            {path:'inside',component:AppNewsInside},
            {path:'outside',component:AppNewsOutside}
        ]},
    ]

    二级路由组件的切换位置依然由router-view来指定(指定在父级路由组件的模板中)

    <router-link to='inside'>inside</router-link>
    <router-link to='outside'>outside</router-link>

    <router-view></router-view>

    默认路由和重定向


    当我们进入应用,默认想显示某一个路由组件,或者当我们进入某一级路由组件的时候其某一个子路由组件,我们可以配置路由:

    {path:'',component:Main}

    当我们需要进入之后进行重定向到其他路由的时候,或者url与路由表不匹配的时候:

    {path:'/',redirect:'/main'}
    ///...放在最下面
    {path:'*',redirect:'/main'}

    命名路由


    我们可以给路由对象配置name属性,这样的话,我们在跳转的时候直接写name:main就会快速的找到此name属性对应的路由,不需要写大量的url path路径了

    <router-link
    v-for="nav in navs"
    :key="nav.id"
    :to="{name:nav.name}"
    >
    {{nav.title}}</router-link>

    //router/index.js的配置
    var router= new VueRouter({
        routes:[
            {
                path:"xxx",
                component:xxx,
                children:[
                    {path:"guonei",component:()=>import("@/views/Guonei"),name:"guonei"},          
                    {path:"guoji",component:()=>import("@/views/guoji"),name:"guoji"},  

                ]
            }
        ]
    })

    <script>
        export default {
            data(){
                return {
                    navs:[
                        {id:1,title:"国内新闻",name:'guonei'},
                        {id:2,title:"国际新闻",name:'guoji'}
                    ]
                }
            }
        }
    </script>

     动态路由匹配

    有时候我们需要在路由跳转的时候跟上参数,路由传参的参数主要有两种:路由参数、queryString参数。
    路由参数需要在路由表里设置
    {path:'/user/:id',component:User}
    上面的代码就是给User路由配置接收id的参数,多个参数继续在后面设置
    在组件中可以通过this.$route.params来使用
    queryString参数不需要在路由表设置接收,直接设置 ? 后面的内容,在路由组件中通过this.$route.query接收

    <div class="nowplaying">
    正在热映...
    <!-- <ul>
        <li
        v-for="data in datalist"
        :key="data"
        @click="toDetail(data)"
        >{{data}}</li>
    </ul> -->

    <!-- <ul>
    <router-link
    v-for="data in datalist"
    :key="data"
    :to="'/detail/'+data+'?title=文章一'"
    tag="li"
    >
    {{data}}
    </router-link>
    </ul> -->

    <ul>
    <router-link
        v-for="data in datalist"
        :key="data"
        :to="{
            name:'detail',
            params:{id:data},
            query:{title:'文章二'}
        }"
        tag="li"
    >
    {{data}}
    </router-link>
    </div>

    <script>
    data(){
        return{
            datalist:['11','22','33']
        }
    }
    </script>

    router.js

    {
        name:"detail",
        path:"/detail/:id",
        component:Detail
    }

    prop将路由与组件解耦


    在组件中接收路由参数需要this.$route.params.id代码冗余,现在可以在路由表里配置props:true
    {path:'detail/:id',component:AppNewsDetail,name:'detail',props:true}
    在路由自己中可以通过props接收id参数去使用了
    props:['id']

    声明式导航router-link


    <router-link>组件支持用户在具有路由功能的应用中(点击)导航。通过to属性指定目标地址,默认渲染成带有超链接的<a>标签,可以通过配置tag属性生成别的标签。另外,当目标路由成功激活时,链接元素自动设置一个表激活的css类名。

    router-link的to属性,默认写的是path(路由的路径),可以通过设置一个对象,来匹配更多

    :to='{name:"detail",params:{id:_new.id},query:{content:_new.content}}'

    name是要跳转的路由的名字,也可以写path来指定路径,但是path的时候就不能使用params传参,params是传路由参数query传queryString参数
    replace属性可以控制router-link的跳转不被记录
    active-class属性可以控制路径切换的时候对应的router-link渲染的dom添加的类名

    编程是导航


    有的时候需要在跳转前进行一些动作,router-link直接跳转,需要在方法里面使用$router的方法
    this.$router.push()

    #### 路由模式
    为了构建SPA(单页面应用),需要引入前端路由系统,这也就是Vue-router存在的意义。前端路由的核心,就在于---改变视图的同时不会向后端发出请求。

    路由有两种模式:hash、history,默认会使用hash模式,但是如果url里面不想出现丑陋hash值,在new VueRouter的时候配置mode值为history来改变路由模式,本质使用H5的history.pushState方法来更改url,不会引起刷新。

    history模式,会出现404的情况,需要后台配置
    因为我们的应用是个单页客户端应用,如果后台没有正确的配置当用户浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。
    所以要在服务端增加一个覆盖所有情况的候选资源:如果URL匹配不到任何静态资源,则应该返回同一个index.html页面,这个页面就是你app的依赖页面

    路由原理:
    hash路由 ====> window.onhashchange监听路径的切换
    history路由 ====> window.onpopstate监听路径的切换

    #### 路由守卫
    在某些情况下,当路由跳转前或跳转后、进入、离开某一个路由前、后,需要做某些操作,就可以使用路由钩子来监听路由的变换

     全局路由钩子


    //进入到某个路由组件之前
    router.beforeEach((to,from,next)=>{
        //会在任意路由跳转前执行,next一定要记着执行,不然路由不能跳转了
    console.log('beforeEach')
    console.log(to,from)
    next()
    })

    //进入到某个路由组件之后
    router.afterEach((to,from)=>{
        //会在任意路由跳转后执行
        console.log('afterEach')
    })

     单个路由钩子:


    只有beforeEnter,在进入前执行,to参数就是当前路由

    routes:[
        {
            path:'/foo',
            component:Foo,
            //当进入到foo路由之前,就会触发
            beforeEnter:(to,from,next)=>{
                //...
                next()//必须执行next之后,对应的Foo组件才可以正常显示出来
            }
        }
    ]

    路由组件钩子:


    //进入到某个组件之前的拦截,获取不到组件内部的this
    beforeRouteEnter(to,from,next){
        //在渲染该组件的对应路由被 confirm前调用
        //不能获取组件实例`this`
        //因为当守卫执行前,组件实例还没有被创建
    },

    beforeRouteUpdate(to,from,next){
        //在当前路由改变,但是该组件被复用时调用
        //举例来说,对于一个带有动态参数的路径/foo/:id,在/foo/1和/foo/2之间跳转的时候,
        //由于会渲染同样的Foo组件,因此组件实例会被复用,而这个钩子就会在这个情况下被调用。
        //可以访问组件实例`this`
    },
    //离开某个组件前的拦截,获取到组件内部的this
    beforeRouteLeave(to,from,next){
        //导航离开该组件的对应路由时调用
        //可以访问实例`this`
    }

  • 相关阅读:
    访问者模式
    中介者模式
    策略模式
    迭代器模式
    责任链模式
    contentProvider模板
    android studio常用快捷键(不断补充)
    jqgrid表格列动态加载的实现
    Android View.onMeasure方法的理解(转载)
    activity的生命周期
  • 原文地址:https://www.cnblogs.com/huayang1995/p/12632398.html
Copyright © 2011-2022 走看看