路由
路由的简单理解
1.理解: 一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理。
2.前端路由: key是路径,value是组件。
Vue-Router的理解
vue的一个插件库,专门用于当前的SPA应用程序
对SPA应用的理解
1.单页Web应用程序(SPA)
2.整个应用只有一个完整的页面。
3.点击页面中的导航链接不会刷新页面,只会做页面的局部更新。
4.数据需要通过ajax请求获取
基本使用
1.安装vue-router, 命令npm i vue-router
2.应用插件:Vue.use(VueRouter)
3.编写router配置项:(在src下新建一个文件夹router,router下创建文件index.js)
index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from "vue-router"// 引入组件
import AboutInfo from "../components/AboutInfo"
import HomeInfo from "../components/HomeInfo"// 创建并暴露路由
export default new VueRouter({routes:[{path:"/aboutinfo",component:AboutInfo},{path:"/homeinfo",component:HomeInfo}]
})
main.js
import Vue from 'vue'
import App from './App.vue'// 引入vue-Router
import VueRouter from "vue-router"// 引入路由器
import router from "./router"Vue.config.productionTip = false// 应用插件:
Vue.use(VueRouter)new Vue({el:"#app",render: h => h(App),router:router
})
App.vue
<!-- vue中借助router-link标签实现路由的切换 -->
<!-- active-class可配置高亮样式-->
<router-link class="list-group-item" active-class="active" to="/aboutinfo">About</router-link>
<router-link class="list-group-item" active-class="active" to="/homeinfo">Home</router-link>
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
效果:
ps:在这里,App.vue中不需要导入子组件
路由的几个注意点
1.路由组件通常存放在pages文件夹, 一般组件通常存放在components文件夹
2.通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
3.每个组件都有自己的$route
属性,里面存储着自己的路由信息。
4.整个应用只有一个router,可以通过组件的$router
属性获取到。
多级路由(嵌套路由)
配置路由规则,使用children配置项
{path:"/homeinfo",component:HomeInfo,children:[ //通过children配置子级路由{path:"messageinfo", //注意:没有/,直接写component:MessageInfo},{path:"newsinfo",component:NewsInfo}]}
跳转(要写完整路径)
<ul class="nav nav-tabs"><li><router-link class="list-group-item" active-class="active" to="/homeinfo/newsinfo">News</router-link></li><li><router-link class="list-group-item" active-class="active" to="/homeinfo/messageinfo">Message</router-link></li>
</ul>
<router-view></router-view>
效果图:
路由的query参数
- 传递参数
基础写法(不灵活)
<!-- 传入的数据写死了 -->
<!-- <router-link to="/homeinfo/messageinfo/detailinfo?id=666&title=你好啊">{{msg.title}}</router-link> -->
跳转并携带query参数,to的字符串写法
<!-- 跳转并携带query参数,to的字符串写法 -->
<!-- <router-link :to="`/homeinfo/messageinfo/detailinfo?id=${msg.id}&title=${msg.title}`">{{msg.title}}</router-link> -->
跳转并携带query参数,to的对象写法
<!-- 跳转携带query参数,to的对象写法 -->
<router-link :to="{path:'/homeinfo/messageinfo/detailinfo',query:{id:msg.id,title:msg.title}}">{{msg.title}}
</router-link>
- 接收参数
DetailInfo.vue
<ul><li>消息编号:{{$route.query.id}}</li><li>消息标题:{{$route.query.title}}</li>
</ul>
路由的命名
首先给路由命名:
children:[{name:"xiangqing", //给路由命名path:"detailinfo",component:DetailInfo}]
<!-- 如果通过name给路由命名名字,则可以简化为: --><!-- 简化(通过name跳转) --><!-- <router-link :to="{name:'xiangqing'}">{{msg.title}}</router-link> --><!-- 简化传参的方法(通过name跳转) --><router-link :to="{name:'xiangqing',query:{id:msg.id,title:msg.title}}">{{msg.title}}</router-link>
路由的params参数
路由携带params参数时,若使用to的对象写法,不能使用path,只能使用name配置项,且需要占位。而携带query参数时,path和name都可以,且不需要占位
接收参数
DetailInfo.vue:
<!--路由的params参数,需要从$route.params.id中接收参数 -->
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>
使用params时,需要占位
index.js
children:[{name:"xiangqing",path:"detailinfo/:id/:title", //路由的params参数component:DetailInfo}]
传递参数
<!-- 传递params参数 -->
<!-- <router-link to="/homeinfo/messageinfo/detailinfo/666/你好啊">{{msg.title}}</router-link> --><!-- 跳转携带params参数,to的对象写法 -->
<router-link :to="{name:'xiangqing', //不能使用path,必须用nameparams:{id:msg.id,title:msg.title}}">{{msg.title}}
</router-link>
路由的props配置
下面分别是路由的query和params参数,DetailInfo.vue:接收参数的代码
<li>消息编号:{{$route.query.id}}</li><li>消息标题:{{$route.query.title}}</li>
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>
当需要接收很多参数时,这样写就比较麻烦,所以我们应该来优化一下。
其实,我们很容易想到用计算属性来写:
<li>消息编号:{{id}}</li> <li>消息标题:{{title}}</li>......computed:{id(){return this.$route.params.id},title(){return this.$route.params.title}}
可是这样并没有简化代码,反而更加复杂,因此,我们需要借助props配置:
props第一种写法:值为对象,该对象中所有的key-value都会以props的形式传给DetailInfo组件
index.js
children:[{name:"xiangqing",path:"detailinfo/:id/:title", //路由的params参数component:DetailInfo,props:{a:1,b:2} //注意写法 //这样是死数据}]
DetailInfo.vue:
接收从index.js中的props传过来的数据
props:["a","b"]
props第二种写法:值为布尔值,若布尔值为真,就会把该路由收到的所以params参数,以props形式传递给DetailInfo组件
index.js
props:true //针对这个案例,根据path:"detailinfo/:id/:title"可知传递的就是id和title
DetailInfo.vue:
// 第二种:props:["id","title"]
但是这种方法只适用于接收params参数,因此,我们有了第三种方法:
首先需要把传递数据都改为用query的形式
props第三种写法:值为函数 (重要!!!)
index.js
props($route){return {id:$route.query.id,title:$route.query.title}}// 或者使用解构赋值// props({query}){// return {// id:query.id,// title:query.title// }// }//或者:// props({query:{id,title}}){// return {id, title}// }
DetailInfo.vue:
<li>消息编号:{{id}}</li>
<li>消息标题:{{title}}</li>
......
props:["id","title"]
效果图:
router-link的push和replace属性
1.作用:控制路由跳转时操作浏览器历史记录的模式
2.浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录。路由跳转时默认为push
3.如何开启replace模式:<router-link replace......>News</router-link>
编程式路由导航
作用:不借助router-link实现路由跳转,让路由跳转更加灵活。
<button @click="forward">前进</button><button @click="back">后退</button><button @click="go">测试go</button>......
<script>
export default {name:"BannerInfo",methods:{ //三个控制前进后退的APIforward(){this.$router.forward()},back(){this.$router.back()},go(){this.$router.go(-2) //负数表示后退两步}
<button @click="pushShow(msg)">push查看</button>
<button @click="replaceShow(msg)">replace查看</button>......methods:{// 使用两个router里的API:push和replace,追加历史记录和替换历史记录pushShow(msg){ //这里用的是路由器(router)this.$router.push({name:'xiangqing',query:{id:msg.id, //这里没有msg,所以需要从上边传递过来参数title:msg.title}})},replaceShow(msg){this.$router.replace({name:'xiangqing',query:{id:msg.id, //这里没有msg,所以需要从上边传递过来参数title:msg.title}})}}}
缓存路由组件
要求: 想要实现在timu后边加上表单,并且当切换组件之后,表单中的内容不会消失
理解: 在切换组件后,NewsInfo组件就会被销毁,这样原本表单中的内容也就不见了;当切回到NewsInfo组件中,又会生成新的DOM,替换掉原本的表单,所以展现的是没有任何输入的表单
分析: 如果想要切回后保持原来输入的样子,需要保持挂载,不被销毁
做法: 综上分析,需要给表单添加一些内容使它可以保持挂载。表单所在的位置是HomeInfo的内容,所以要在HomeInfo里操作
首先添加表单:
NewsInfo.vue
<ul><li v-for="n in news" :key="n.index">{{n.timu}}<input type="text"></li></ul>
保持挂载,不被销毁:
HomeInfo.vue
<keep-alive include="NewsInfo"> <router-view></router-view></keep-alive>
使include中指定的组件不被销毁,include中写的是name配置项中对应的组件名
ps:如果不写 include=“NewsInfo” 就表示所有的组件都不会被销毁,但一般都是指定某个组件不被销毁
缓存一个路由组件:
<keep-alive include="NewsInfo"> ......
缓存多个路由组件
<keep-alive :include="['NewsInfo','MessageInfo']"> ......