目录
1.代码(Message.vue向Detail.vue传递参数)
props的第二种写法,值为布尔值(有限制,要想接收query参数传不过去)
props的第三种写法,值为函数(如果query 的话就改成$route.query.id)
六、编程式路由导航(不借助router-link实现路由跳转)
八、路由特有的生命周期钩子---activated、deactivated
一、相关理解
路由:一组key:value的对应关系 (key是路径,value可能是function或component),多个路由,需经过路由器的管理
后端路由:
理解:value是function,用于处理客户端提交的请求
工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
前端路由:
理解:value是component,用于展示页面内容
工作过程:当浏览器的路径改变时,对应的组件就会显示
vue-router的理解:vue的一个插件库,专门用来实现SPA应用的
SPA应用的理解:单页Web应用(single page web application),整个应用只有一个完整的页面,点击页面中的导航链接不会刷新页面,只会做页面的局部刷新,数据需要通过Ajax请求获取
二、基本使用
总结
指定展示位置类似于插槽,给她一个位置,她就往这里放东西
安装以及初步使用
引入vue-router (main.js)
// 引入vue-router
import VueRouter from 'vue-router'
// 使用
Vue.use(VueRouter)
创建src/router/index.js文件
// 该文件专门用于穿件整个应用的路由器
import VueRouter from 'vue-router'
import About from '../pages/About'
import Home from '../pages/Home'
// 创建一个路由器
export default new VueRouter({
routes:[
{
// 如果路径是 /about 我们就展示About这个名字的组件
path:'/about',
component: About
},
{
path:'/home',
component: Home
},
{},
]
})
在main.js中引入路由器
// 该文件是整个项目的入口文件
// 引入vue,这个vue不能解析template配置项
import Vue from 'vue'
// 下面这个是引入完整版的vue。这个vue能解析template配置项
// import Vue from 'vue/dis/vue'
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
// 引入vue-router
import VueRouter from 'vue-router'
// 使用
Vue.use(VueRouter)
// 引入路由器
import router from './router'
// 关闭vue的生产提示
Vue.config.productionTip = false
// 创建vue实例对象---vm
new Vue({
el:'#app',
render: h => h(App),
// 全新配置项router
router:router
})
App.vue
<template>
<div>
<div class="row">
<Banner></Banner>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始做法 -->
<!-- <a class="list-group-item active" href="./about.html">About</a> -->
<!-- <a class="list-group-item" href="./home.html">Home</a> -->
<!-- 路由做法 router-link标签最终也变成了a标签-->
<!-- active-class="active"表示,当点击的时候,active这个样式加载,当点击其他的时候就回复原装 -->
<!-- Vue中借助此标签实现路由的切换 -->
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Banner from './components/Banner.vue';
export default{
name:'App',
components: { Banner }
}
</script>
<style>
</style>
components
Banner.vue
<template>
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<h2>Vue Router Demo</h2>
</div>
</div>
</template>
<script>
export default{
name:'Banner'
}
</script>
<style>
</style>
pages
About.vue
<template>
<h2>我是About的内容</h2>
</template>
<script>
export default{
name:'About'
}
</script>
<style>
</style>
Home.vue
<template>
<h2>我是Home的内容</h2>
</template>
<script>
export default{
name:'Home'
}
</script>
<style>
</style>
三、嵌套路由(多级路由)
总结
代码
给Home.vue创建二级路由
Home.vue
<template>
<div>
<h2>我是Home的内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<!-- 因为是二级路由,得写父亲的 -->
<router-link class="list-group-item " active-class="active" to="/home/news">News</router-link>
</li>
<li>
<router-link class="list-group-item " active-class="active" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default{
name:'Home'
}
</script>
<style>
</style>
Message.vue
<template>
<div>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message/3">message003</a>
</li>
</ul>
</div>
</template>
<script>
export default{
name:'Message'
}
</script>
<style scoped>
</style>
News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default{
name:'News'
}
</script>
<style scoped>
</style>
index.js
{
path:'/home',
component: Home,
children:[
{
// 二级路由不加斜杠
path:'news',
component:News
},
{
// 二级路由不加斜杠
path:'message',
component:Message
}
]
},
四、路由传参
总结
1.代码(Message.vue向Detail.vue传递参数)
Message.vue(发送参数,使用query方式)
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<!-- 加了冒号之后,`/home/message/detail?id=${m.id}&title=${m.title}`解析这一块 -->
<!-- <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>
</li>
</ul>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default{
name:'Message',
data(){
return{
messageList:[
{id:'001',title:'消息001'},
{id:'002',title:'消息002'},
{id:'003',title:'消息003'},
]
}
}
}
</script>
<style scoped>
</style>
Detail.vue(接受参数,使用query方式)
<template>
<div>
<ul>
<li>消息编号:{{$route.query.id}}</li>
<li>消息标题:{{$route.query.title}}</li>
</ul>
</div>
</template>
<script>
export default {
name:'Detail'
}
</script>
<style>
</style>
2.重要的路由命名问题:name(简化路由跳转)
3.路由的params参数(对照query学习)
在配置路由的时候,多了“使用占位符生命接收params参数”(query没有)
路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置
这个 地方和query一个样
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>
把query的配置项改成params配置项,删除path配置项,增加name配置项
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title
}
}">
{{m.title}}
</router-link>
3.接收参数
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>
在开发中用query可以。用params也可以,都是可以的!!!!!
4.路由的props配置
props第一种写法:对象(用的少,传递的是死数据)
props的第一种写法,值为对象 所有key-value都会一props的形式传给Detail组件
children:[
{
name:'xiangqing',
path:'detail/:id/:title',
component:Detail,
// props的第一种写法,值为对象 所有key-value都会一props的形式传给Detail组件
props:{a:1,b:'hello'}
}
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> -->
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title
}
}">
{{m.title}}
</router-link>
<template>
<div>
<ul>
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>
<li>a:{{a}}</li>
<li>b:{{b}}</li>
</ul>
</div>
</template>
<script>
export default {
name:'Detail',
props:['a','b']
}
</script>
<style>
</style>
props的第二种写法,值为布尔值(有限制,要想接收query参数传不过去)
props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件
children:[
{
name:'xiangqing',
path:'detail/:id/:title',
component:Detail,
// props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件
props:true
}
]
这个地方我们就直接可以使用 在index.js中的/:id/:title
<template>
<div>
<ul>
<li>消息编号:{{id}}</li>
<li>消息标题:{{title}}</li>
</ul>
</div>
</template>
<script>
export default {
name:'Detail',
props:['id','title']
}
</script>
<style>
</style>
props的第三种写法,值为函数(如果query 的话就改成$route.query.id)
// 三级路由
children:[
{
name:'xiangqing',
path:'detail/:id/:title',
component:Detail,
e
// props的第三种写法,值为函数
props($route){
return{
id:$route.params.id,
title:$route.params.title,
}
}
}
]
其他两个文件不改变
五、router-link的replace属性
一般来说我们使用router-link,多次点击不同的目录之后,浏览器不会帮我们保存上一次的浏览记录(说白了我们点击网页的后退按钮,后退不到我们的上一步),其实就是一种替换的动作
那怎么开启这种模式?
添加 :replace="true"标签
简写:
六、编程式路由导航(不借助router-link实现路由跳转)
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> -->
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title
}
}">
{{m.title}}
</router-link>
<!-- push查看可以留下浏览记录 -->
<button @click="pushShow(m)">push查看</button>
<button @click="replaceShow(m)">replace查看</button>
</li>
</ul>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default{
name:'Message',
data(){
return{
messageList:[
{id:'001',title:'消息001'},
{id:'002',title:'消息002'},
{id:'003',title:'消息003'},
]
}
},
methods:{
pushShow(m){
this.$router.push({
name:'xiangqing',
params:{
id:m.id,
title:m.title
}
})
},
replaceShow(m){
this.$router.replace({
name:'xiangqing',
params:{
id:m.id,
title:m.title
}
})
}
}
}
</script>
<style scoped>
</style>
七、缓存路由组件
因为当我们切换组件的时候,之前那个组件就被销毁掉了,如果存在数据的话,这些数据也没了,所以我们需要缓存路由组件,让数据有所保存
<!-- 如果不指定include的话。默认都会缓存(来着不拒) 如果指定的话,仅仅是指定的进行缓存,其实也说明了在include的组件在切走时不会被销毁 -->
<!-- 下面的这个News是组件名,就是我们name的那个 -->
<keep-alive include="News">
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</keep-alive>
同时缓存多个的话,就下面这个形式
八、路由特有的生命周期钩子---activated、deactivated
我们在上面学习了缓存,但是也有一个坏处,比如说我们要是在上面News组件中添加一个定时器,当我们切换到News以外的其他组件时,News组件并没有被销毁,这个定时器依然在使用,非常影响我们的效率,所以接下来我们要学习两个新的钩子
<li :style="{opacity}"> 欢迎学习Vue</li>
// mounted(){
// this.timer=setInterval(()=>{
// this.opacity -=0.01
// if(this.opacity<=0)
// this.opacity=1
// } )
// },
// beforeDestroy(){
// clearInterval(this.timer)
// }
// 被激活的
activated(){
this.timer=setInterval(()=>{
this.opacity -=0.01
if(this.opacity<=0)
this.opacity=1
} )
},
// 取消激活的
deactivated(){
clearInterval(this.timer)
}