一.路由组件传参
router.js代码片段:
{
path: '/argu/:name',
name: 'argu',
//传入不同的参数可以进入同一个页面,实现组件的复用
component: () => import('@/views/argu.vue'),
props:true
},
组件内获取路由参数的代码片段
<template>
<div>
{{name}}
</div>
</template>
<script>
export default {
props:{
name:{
type:String,
// type: [String,Number]
default:'lison'
}
},
data () {
return {
};
}
}
</script>
如果不是像上面那样的动态路由写法,而是下面这样的路由写法,则
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
props:{
food:'banana'
}
},
组件内获取路由参数的代码片段:
<template>
<div class="about">
<h1>This is an about page</h1>
{{food}}
</div>
</template>
<script>
export default {
props:{
food:{
type:String,
default:'apple'
}
}
}
</script>
路由中是函数式的传参写法:
路由配置代码片段:
{
path: '/',
alias: '/home_page',
name: 'home',
component: Home,
props: route => ({
food:route.query.food
})
//函数式传参
},
组件内的使用:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<button @click="handleClick('back')">返回上一页</button>
<button @click="handleClick('push')">返回上一页</button>
<button @click="handleClick('replace')">替换到</button>
<b>{{food}}</b>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'home',
components: {
HelloWorld
},
props:{
food:{
type:String,
default:'apple'
}
}
}
</script>
二.html5 history模式
//创建路由实例
export default new Router({
mode:'history',
routes: routes
})
三.导航守卫
a.全局守卫
const router = new Router({
routes
})
const HAS_LOGINED = true;
// router.beforeEach()注册全局前置守卫
router.beforeEach((to,from,next)=>{
if(to.name !== 'login'){
if (HAS_LOGINED) next()
else next({name: 'login'})
// 如果已经登录 则继续执行;如果没有登录,则进入到登录页
}else{
//如果当前要访问的是login页
if(HAS_LOGINED) next({name: 'home'})
else next()
}
})
router.beforeResolve((to,form,next)=>{
console.log("before resolve invoked")
next();
})
//router.afterEach()定义路由后置(页面跳转之后)钩子
router.afterEach((to,from)=>{
//logining=false
})
export default router
b.路由独享守卫
//beforeEnter, 在beforeEach与beforeResolve中间执行
{
path: '/',
alias: '/home_page',
name: 'home',
component: Home,
props: route => ({
food:route.query.food
}),
beforeEnter: (to,from,next) => {
if(from.name==='login') alert('这是从登录页来的')
else alert('这不是从登录页来的')
next()//调用next函数 才会跳转页面
}
//函数式传参
},
c.组件内的守卫
export default {
name: 'home',
components: {
HelloWorld
},
props:{
food:{
type:String,
default:'apple'
}
},
beforeRouteEnter (to,from,next) {
console.log(from.name);
//此时页面还未渲染,用this的话是获取不到vue实例的
console.log(this) // 这里获取不到上下文
next(vm =>{
//可以在next里这样
//next里面有一个回调函数可以获取到上下文,把请求到的数据塞到vue对象中
console.log(vm)
})
},
beforeRouteLeave (to,from,next){
//用于如果用户在当前页面进行了编辑没保存,离开当前页面时要做提示,就用到了此路由
console.log(this) // 这里可以获取到上下文
const leave = confirm('您确定离开?')
if (leave) next()
else next(false)
},
beforeRouteUpdate (to,from,next) {
console.log(this) // 这里可以获取到上下文
console.log(to.name,from.name)
}
}
</script>
d.路由解析流程
1.导航被触发
2.在失活的组件(即将离开的页面组件)里调用离开守卫 beforeRouteLeave
3.调用全局的前置守卫beforeEach
4.在重用的组件里调用beforeRouteUpdate 或者beforeRouteEnter
5.调用路由独享的守卫 beforeEnter
6.解析异步路由组件
7.在被激活的组件(即将进入的页面组件)里面调用beforeRouteEnter
8.调用全局的解析守卫 beforeResolve
9.导航被确认
10.调用全局的后置守卫afterEach
11.触发DOM渲染
12.用创建好的实例调用beforeRouteEnter守卫里传给next的回调函数
四.路由元信息
//router/router.js代码片段
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'),
props:{
food:'banana'
},
meta: {
title: '关于'
}
}
//router/index.js:
import {setTitle} from '@/lib/util'
router.beforeEach((to,from,next)=>{
to.meta && setTitle(to.meta.title)
if(to.name !== 'login'){
if (HAS_LOGINED) next()
else next({name: 'login'})
// 如果已经登录 则继续执行;如果没有登录,则进入到登录页
}else{
//如果当前要访问的是login页
if(HAS_LOGINED) next({name: 'home'})
else next()
}
})
//lib/util.js:
// 与业务有关的方法代码
export const setTitle = (title) =>{
window.document.title = title || 'admin'
}
五.过渡效果
app.vue:
<!-- 如果要对多个视图做过渡效果要用到 transition group -->
<transition-group name="router">
<!-- name还可以设成动态绑定的值 :name="routerTransition" -->
<router-view key="default"/>
<!-- 命名路由——页面要展示多个不同的视图时 -->
<router-view key="email" name="email"/>
<router-view key="tel" name="tel"/>
</transition-group>
<script>
export default {
data(){
return{
routerTransition:''
}
},
watch:{
'$route'(to){
to.query&&to.query.transitionName&&(this.routerTransition=to.query.transitionName)
}
}
}
</script>
<style lang="less">
// router使用transition的name的值
// 页面进入时的效果
.router-enter{
opacity: 0;
}
.router-enter-active{
transition: opacity 1s ease;
}
.router-enter-to{
opacity: 1;
}
// 页面离开时的效果
.router-leave{
opacity: 1;
}
.router-leave-active{
transition: opacity 1s ease;
}
.router-leave-to{
opacity: 0;
}
</style>
注:vue路由传参query和params的区别:
https://blog.csdn.net/airdark_long/article/details/78272817
https://www.jianshu.com/p/45ee7a6bdc0c