Vue-route学习

160 阅读3分钟

单页面应用(SPA)

  1. 整个项目只有一个完整的页面
  2. 只做局部的刷新,相较于传统的多页面做整个页面的刷新
  3. 数据通过ajax请求进行获取
    优点:拥有更好的用户体验,前后端分离开发,更加灵活高效
    缺点:初次加载所有资源,内存花费较大

route and router

  1. route是用来获取路由信息router是用来操作路由
  2. route是一个跳转的路由对象(路由信息对象),每一个路由都会有一个$route对象,是一个局部的对象
  3. router包含了所有的路由,包括路由的跳转方法,钩子函数等,是VueRouter的一个实例

嵌套路由(多级路由)

index.js路由配置文件
    export default new VueRouter({
        mode:history,// 区别于hash工作模式
        routes:[
            {
                name:'aboutName', // 路由名称可简化多级路径
                path:'/about',    // 路径
                component:About,  // 组件
                meta:{name:'zs', title:'aaa'} // 可以携带自定义数据
                children:[
                    {
                        // 子路由配置
                        path:'abc' // 子路由可不带 '/'
                    }
                ]
                
            }
        ]
    })
    
    页面触发:<router-link to="/about">About</router-link>
    页面的<router-link>最后会翻译成<a>标签进行点击后跳转

路由传参

路由的传参有两种方式:query 和 params

query

字符串写法
<router-link :to="`/home/messages/detail?id=${m.id}`">{{abc}}</router-link>
对象写法:
<router-link :to="{
    path: '/home/messages/detail',
    query: {
        id: m.id,
        title: m.title
    }
}">{{ abc }}</router-link>

接收{{ $route.query.id }}

query传参不涉及路由器的更改,可以使用name配置简化路由路径配置

params

字符串配置
<router-link :to="`/home/messages/detail/${m.id}/${m.title}`">{{abc}}</router-link>
跳转配置
<router-link :to="{
    name: 'messagesName',   必须用name,不能用params
    params: {
        id: m.id,
        title: m.title
    }
}">{{ abc }}</router-link>

一定需要和router联合配置:声明参数,不能使用path,一定使用name
    children:[
        {
        name:'messagesName',
        path:'detail/:id/:title',
        component:Detail
        }
    ]

总结:

query形式:
  to='字符串写法' key=value的形式传参  
  :to={对象写法} 可使用path或者name指定路径
params形式:
  to='字符写法' /value/value的形式传参,需要路由path:'detail/:id/:title'指定格式
  :to='对象写法' 只能使用name指定路径
接收参数: $route.query.id 或者 $route.params.title 

route的props配置项

通过$route获取数据展示比较繁琐
                <li>消息编号{{ $route.params.id }}</li>
                <li>消息标题{{ $route.params.title }}</li>
                <li>消息编号{{ $route.query.id }}</li>
                <li>消息标题{{ $route.query.title }}</li>
使用computed:{}计算属性实现出来,页面简洁,但是代码量也相差不大

使用props更加简便
    children:[
        {
            name:'messagesName',
            path:'detail/:id/:title',  params形式
            path:'detail',             query形式
            component:Detail,
            一共有三种方式,第一种主要是传递不变的数据,第二种通过params传递数据,第三种通过函数传递
            props:{a:1, b:2}   props:['','']  直接在组件中通过props:['','']接收
            props:true,        props:通过params的方式传入到组件
            props($route){     // props:通过函数操作传入的数据,query的方式传入组件
                return {id:$route.query.id, title:$route.query.title}
            }
        }
    ]
    接收数据只需要在组件中设置:props:['id','title']
    页面展示:
        <li>消息编号{{ id }}</li>
        <li>消息标题{{ title }}</li>       

replace and push

路由对于浏览器的历史记录的影响  
    replace模式:替换当前的历史记录
        <router-link replace class="list-group-item active" to="/about">About</router-link>  
    push模式(默认):追加当前的历史记录

编程式路由

之前都是通过实现路由跳转,现在通过$router的实例方法,进行跳转

通过.push跳转:以push模式 追加的方式跳转
通过.replace跳转:以replace模式 替换之前历史记录跳转
通过.go:能够跳转之前和之后或者刷新go(0)

    this.$router.push({
        name: 'detailName',
        query: {
            id: m.id,
            title: m.title
        }
    })


    this.$router.replace({
        name: 'detailName',
        query: {
            id: m.id,
            title: m.title
        }
    })


    this.$router.go(-3)

路由缓存

组件切换的时候,上一个组件会被销毁掉,这个时候可以缓存数据,以便下次切换查看数据

    缓存填入的信息,指定组件的名称,让不展示的路由组件保持挂载,不被销毁
    两种写法,缓存一个或者多个,include填写组件名称
    <keep-alive include="MyNews">  
        <router-view></router-view>
    </keep-alive>
    或者
    <keep-alive :include="['MyNews', 'MyMessage']">
        <router-view></router-view>
    </keep-alive>

问题:有缓存的组件,不会被销毁,那么就会涉及到激活和失活的两种状态,对应了两个函数的调用
    
两个新的声明周期钩子:

        activated(){
            组件激活执行
        }

        deactivated(){
            组件失活执行
        }
    不要忘记还有一个:
        this.$nextTick(){
            当修改了数据,页面挂载完毕后执行
        }

路由守卫

概念:守卫路由的跳转,可作为跳转前后的判断。
分类:全局守卫,独享守卫,组件内的守卫。

        添加全局 前置 路由守卫,第一次加载页面执行,每次切换路由之前执行
        router.beforeEach((to, from, next) =>{
            // to 目标路由信息
            // console.log(to);
            // from 来自其路由信息
            // next 是否跳转
            // meta 路由元信息,用来配置自定义信息,可配置查看是否需要权限
            if (to.meta.isAuth === true) {
                if(localStorage.getItem('stu') === '1233') {
                    next()
                } else {
                    alert("没有权限")
                }
            } else {
                next()
            }
        })

        添加全局 后置 路由守卫,第一次加载页面执行,每次切换路由之后执行
        router.afterEach((to) =>{
            document.title = to.meta.title ? to.meta.title : 'gogo'
        })

       export default router
独享路由守卫
        某一个路由单独使用的限制
        beforeEnter(to, from, next){

        }
        没有 独享后置路由 守卫,可以配合 全局后置路由 守卫一起使用
组件内路由守卫
        能够写组件单独的逻辑
        export default {
            name: 'MyAbout',
            beforeRouteEnter(to, from, next){
                // 通过路由规则进入该组件之前被调用
            },
            beforeRouteLeave(to, from, next){
                // 通过路由规则离开该组件之前被调用
            }
        }

路由两种工作模式

路由器的两种工作模式:体现在地址栏上
    
    hash模式,兼容性强
    localhost:8080/#/myBoot/student ====> hash#号开始,到结束,都叫做hash
        hash不会作为路径随着http请求发送给服务器

    history模式,简洁
        localhost:8080/myBoot/student
        
    上线问题
        history模式404问题(后端解决,可以使用nginx:分辨到底是后端路由还是前端路由)
        上线就使用hash模式,history模式好看,一刷新就完蛋了,需要解决,通过后端解决

element-ui 按需引入

全部引入
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css' // 引入所有样式所有的组件
文件太大,没有必要全部引入

按需引入 + cli配置
    npm i babel-plugin-component -D

修改babel.config.js 预设包
    module.exports = {
    presets: [
        '@vue/cli-plugin-babel/preset',
        [旧"es2015"或者新"@babel/preset-env", { "modules": false }],
    ],
    plugins: [
        [
        "component",
        {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
        }
        ]
    ]
    }

main.js按需引入插件
    import { Button, Row, DatePicker } from 'element-ui';    样式会自动引入
    Vue.use(Button)
    Vue.use(Row)
    Vue.use(DatePicker)