Vue学习13之vue-router(下)
动态路由:某些情况下,一个页面的path的路径可能是不一样的,例如进入/user的时候希望跟上一个/id。
如果想配置这样一个组件怎么做呢,首先我们得有一个user组件,创建一个:User.vue。然后还是要在router中的index配置路由。import 包完然后:
{path:'/user',
component:User}
这回我们增加一个信息:userId,直接在index的routes数组中添加信息:
{
path:'/user/:userId',
component:User
}
这里意思是/user/后面需要加入一个userId,加啥不管反正显示User组件。
那么我们回到User组件添加一下我们要显示UserId:
<template>
<div>
<h2>我是用户界面</h2>
<p>我是用户相关信息</p>
<h2>{{userId}}</h2>
</div>
</template>
<script>
export default {
name: 'User',
computed:{
userId(){
return this.$route.params.userId
}
}
}
</script>
可以看到这里有个陌生的this.$route.params.userId,route之前代表这个组件的路由,params.userId来自App.vue中的userId变量。所以我们在App.vue中加入这个变量:

默认名字是zhangsan,那么顺便在这个App.vue界面中显示出来:
<router-link :to="'/user/'+userId">用户</router-link>
<router-view></router-view>
这里使用v-bind,目的是将to的内容绑定成字符串/user/和变量userId的组合形式,这样实际上router-link在这里绑定成了/user/zhangsan.这样就完成了:

手动更改url中的zhangsan变成lisi,整体显示的内容也会跟着改变:

路由的懒加载:把import代码重构一下使得我们在需要路由的时候再动态加载。
//import Home from '../components/Home'
//import About from '../components/About'
//import User from '../components/User'
const Home = () => import ('../components/Home')
const About = () => import ('../components/About')
const User = () => import ('../components/User')
这样以后我们所有写的路由都要这样写,打包之后更小效率也更好。
嵌套路由:又称为路由套娃。干什么用呢,例如这个效果:

上面是首页上面我们用到了路由来切换,当切换到首页那一栏的时候下面的新闻和消息也应该是可以切换的。怎么做呢?
首先我们要定义新闻和消息的组件,和前面一样这里就上个图得了:

别忘了在index中引包:
const HomeNews =() => import ('../components/HomeNews')
const HomeMessage =() => import ('../components/HomeMessage')
然后有了两个组件我们就注册一下组件,这里要注意的是注册的位置:

是在主页home下面新建了一个children选项然后又添加了一次路由,里面分别是默认情况下重定向news,news的时候显示HomeNews,和message的时候显示HomeMessage。然后我们也要把router-link和router-view写在home里而不是Vue里,因为它是home底下的路由。
home内容:
<template>
<div>
<h2>我是首页</h2>
<p>我是首页内容</p>
<router-link to='/home/news'>新闻</router-link>
<router-link to='/home/message'>消息</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
<style>
</style>
之后我们就实现了上述效果了。
路由的参数传递:
1.params的类型:配置路由格式/router/:id,传递的方式通过path后面跟上对应的值,传递后为/router/abc
2.query路由格式:/router,传递方式为对象中使用query的key作为传递方式,传递后为/router?id=abc
URL:协议://主机:端口/路径?查询
为了传递参数我们在App.vue里应该这样使用控件:(假设路由已经配置好)
<router-link :to="{path:'/profile',query:{name:'frank',age:'18'}}">档案</router-link>
这里效果是这个样子:

这里传进去一个query对象,里面带有一个name和一个age,我们在这个组件定义的地方就可以使用这个参数了。

可以看到通过$route.对象.属性 这样的方式就可以拿到我们想要的东西了。
区分好了一个是route一个router!!!!!
this.$route代表的是当前活跃路由,当你配置好你的路由后,其他的必要代码是后来框架添加上去的,哪一个路由活跃中就是哪个对象。
this.$router实际上就是index.js中的router对象,export给了App.vue。他们是一个东西,所以才可以做push replace等操作。
总结一句就是带R就是全局,不带R就是局部。
导航守卫:对跳转过程进行监听,从哪里跳到哪里。例如我们有一个需求,点到首页上面标题显示首页,点到消息就显示消息。
created声明周期函数:创建的组件的时候就回调一次。
mounted周期函数:template挂载Dom上的时候就回调一次。
updated周期函数:界面更新的时候回调一次
例如:


点击一次回调一次。那么问题就简单了,直接在这个函数里设置标题就可以了:
export default {
name: 'Home',
created(){
console.log('create')
document.title = '首页'
}
}
同理可以设置其他板块,就实现了这样的效果:点击首页显示首页,点击关于显示关于。


但是这样不是很合适,我们希望是路由跳转。所以引入这个全局导航守卫。
我们在routes里配置好每个界面我们的标题都显示什么:
{
path:'/profile',
component:Profile,
meta:{
title:'档案'
},
}
例如这里我们的profile点击后上面显示档案,所有的其他类别也可以这样配置,然后在下面单独添加一个router.beforeEach
router.beforeEach((to,from,next) => {
document.title = to.matched[0].meta.title,
next()
})
这是和routes同级的,这里注意一定要有next()方法,上面是设置标题为meta中的title。这样就可以了。ps:meta指的是描述数据的数据。这个也交前置守卫,意思是跳转前回调。后置守卫(也交后置钩子)不需要调用next。
上面我们每次点击都会创建一个新的内容,使得created方法在每次点击的时候都会触发因为每次都创建了一次,如何避免这种问题呢,通过在App.vue中这样使用
<keep-alive>
<router-view></router-view>
</keep-alive>
在router-view上下增加了keep-alive标签,这样就可以了。
为了使得我们在跳转后能够保留之前我们子组件的路由效果,应该怎么做呢?

例如当我点击用户再点击回来这里应该显示的事消息而不是新闻的内容。我们在Home里这样添加:
export default {
name: 'Home',
data(){
return{
patha:'/home/news'
}
},
activated(){
this.$router.push(this.patha);
},
beforeRouteLeave(to, from, next){
this.patha = this.$route.path;
next()
}
}
前面那个create函数我删掉了要不显得多余,在我们离开这个页面的时候用patha来保存现在的path是什么,然后等到我们回来的时候在用这个push到url上。


打印出来我们能看到leave之后记录了path内容是/home/message,回来的时候active后这个path被添加给patha了。成功了。
keep-alive则是Vue的一个内置组件,可以使被包含的组件保留状态或者避免重新渲染。有两个重要的属性:include-字符串或正则表达,只有匹配的组件才会被缓存,exclude-字符串或正则表达,任何匹配的组件都不会被缓存。
<keep-alive exclude='Profile,User'>
<router-view></router-view>
</keep-alive>
这样就表示Profile和User不被缓存。



浙公网安备 33010602011771号