vue路由

vue-router

理解:vue的一个插件库,专门用来实现SPA应用
SPA(single page web application):

  1. 单页web应用
  2. 整个应用只有一个完整的页面
  3. 点击页面中的导航连接不会刷新页面,只会被页面局部更新
  4. 数据是需要通过Ajax请求获取

路由的理解

什么是路由:

  1. 一个路由就是一组映射关系(key-value)
  2. key为路径,value为fuction或者component

路由分类:

1.前端路由:
  1. 理解:value就是component,用于展示页面
  2. 工作过程:当浏览器路径改变时,对应组件就会改变
2.后端路由:
  1. 理解:value就是function,用于处理客户端提交的请求
  2. 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来去处理请求,返回响应数据
基本使用:

1.安装vue-routernpm i vue-router
2.应用插件:Vue.use(VueRouter)
3.编写router配置项:

// 创建整个应用的路由器
import VueRouter from 'vue-router'
// 引入组件
import About from '../components/About'
import Home from '../components/Home'

// 创建并暴露一个路由器
export default new VueRouter({
    routes: [{
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home
        }
    ]
})

4.实现切换效果(router-link
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
5.指定展示位置
<router-view></router-view>

多级路由(嵌套路由)

1.配置路由规则,使用children配置项

// 创建并暴露一个路由器
export default new VueRouter({
    routes: [{
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [{
                    path: 'message',
                    component: Message
                },
                {
                    path: 'news',
                    component: News
                }
            ]
        }
    ]
})

2.跳转路径:<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
3.注意:children配置项中的路径不加 /

路由的query参数

1.传递参数:

<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>

<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
    path:'/home/message/detail',
    query:{
        id:m.id,
        title:m.title
    }

}">
{{m.title}}
</router-link>


//路由配置项
children: [{
 path: 'message',
    component: Message,
    children: [{
        name: 'xiangqing',
        path: 'detail',
        component: Detail
    }]
},

2.接收参数:

$route.query.id
$route.query.title
路由的params参数

1.传递参数:必须使用name,不能使用path

<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>

<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
    name:'xiangqing',
    query:{
        id:m.id,
        title:m.title
    }

}">
{{m.title}}
</router-link>


//路由配置项
children: [{
 path: 'message',
    component: Message,
    children: [{
        name: 'xiangqing',
        path: 'detail/:id/:title',//参数占位
        component: Detail
    }]
},

2.接收参数:

$route.params.id
$route.params.title
路由命名

通过name属性,在编写配置项时,起名字

routes: [{
     name: 'about',
        path: '/about',
        component: About
    },
    {
        path: '/home',
        component: Home,
        children: [{
                path: 'message',
                component: Message,
                children: [{
                    name: 'xiangqing',
                    path: 'detail',
                    component: Detail
                }]
            },
            {
                path: 'news',
                component: News
            }
        ]
    }
]

在使用名字时:

//第一种,直接通过名字跳转
<router-link class="list-group-item" active-class="active" :to="{name:about}">About</router-link>

//第二种,传参
<router-link :to="{
	name:'xiangqing',
	query:{
	     id:m.id,
	     title:m.title
	 }

}">
{{m.title}}
</router-link>
路由的props配置
{
    name: 'xiangqing',
    path: 'detail/:id/:title',
    component: Detail,

    // props第一种写法,对象,该对象中所有key-value都会以props的形式传给Detail
    // props:{a:1,b:2}

    // props第二种写法,布尔值,true则把路由接收到的所有params参数通过props传给Detail
    // props:true

    // props第三种写法,函数,该函数返回的对象中所有key-value都会以props的形式传给Detail
    props(){
        return{
            id:$route.query.id,
            title:$route.query.title
        }
    }
}
<router-link>的replace属性
  1. 作用:控制路由跳转时操作浏览器历史纪录的模式
  2. 浏览器的历史记录模式有两种:pushreplacereplace不可进行倒退或前进,默认为push,push模式下,浏览记录会逐层叠加,可以进行任意前进和后退,开启replace模式,不能可以进行前进和后退
  3. 开启replace模式: <router-link replace active-class="active" to="">About</router-link>
编程式路由导航

一般的路由跳转都是<router-link>来进行点击后跳转,但是一般都会转为a标签来实现,但是如果想实现点击按钮实现路由跳转,就不能用<router-link>,得用编程式路由导航跳转,使路由跳转更加灵活

$router的API
//路由跳转的历史模式:
this.$router.push()//保存路由历史
this.$router.replace()//不保存路由历史

//方法
this.$router.back()//路由后退
this.$router.forward()//路由前进
this.$router.go()//前进后退由参数控制,正数前进几次,负数后退几次
this.$router.push({
   name:'xiangqing',
    params:{
        id:m.id,
        title:m.title
    }
})
缓存路由组件

在实现路由跳转时,跳转后,前一个路由组件会被销毁,但如果想保存有输入框的路由组件内输入框的内容在跳转时不被销毁,需要使用缓存路由组件<keep-alive>,他其中可以用include设置缓存某个组件的内容,如果不设置,则每个路由组件都被缓存

<keep-alive include="News">
	<router-view></router-view>
</keep-alive>
两个新的生命周期钩子

activated(),激活,当访问组件时,激活该钩子
deactivated(),失活,不访问该组件,该钩子失效

activated(){//被激活的
  this.timer = setInterval(()=>{
        this.opacity -= 0.01
        if(this.opacity<=0) this.opacity = 1
    },50)
},
deactivated(){//失活
    clearInterval(this.timer)
}
路由守卫

主要作用是对路由进行权限控制,分为全局守卫,独享守卫,组件内守卫
全局守卫

//全局前置路由守卫,在每一次路由切换前都会调用
router.beforeEach((to, from, next) => {
    console.log('前置', to, from);
    if (to.meta.isAuth) { //判断是否需要权限
        if (localStorage.getItem('school') === 'atguigu') {//权限控制具体规则
            next()
        } else {
            alert('学校名不对')
        }
    } else {
        next()
    }
})

//后置路由守卫,在每一次路由切换后都会调用
router.afterEach((to, from) => {
    console.log('后置', to, from);
    document.title = to.meta.title || '主界面';
})
独享守卫

在某一个需要设置守卫的路由配置中,设置beforeEnter属性,只有前置路由守卫,没有后置路由守卫

{
   name: 'xinwen',
    path: 'news',
    component: News,
    meta: { isAuth: true, title: '新闻' },
    beforeEnter: (to, from, next) => {
        console.log('前置', to, from);
        if (to.meta.isAuth) { //判断是否需要权限
            if (localStorage.getItem('school') === 'atguigu1') {
                next()
            } else {
                alert('学校名不对')
            }
        } else {
            next()
        }
    }
}
组件内守卫
//通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
    console.log('about---beforeRouteEnter',to,from);
    if (to.meta.isAuth) { //判断是否需要权限
        if (localStorage.getItem('school') === 'atguigu') {
            next()                  
        } else {
            alert('学校名不对')   
        }
    } else {
        next()
        console.log(1111);
    }
},
//通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
    console.log('about---beforeRouteLeave',to,from);
    next();
}