Vue前端中的路由是多组映射关系(key-value),其中key是路径,value是组件,这些映射关系需要路由器(router)来进行管理。
我们可以通过Vue Router设定访问路径,并将路径和组件映射起来,实现局部刷新界面,不需要向服务器发送请求就能切换页面
基本配置
注意:vue-router@4版本对应vue3,vue-router@2版本对应vue2,千万不要弄错
main.js
在main.js中引入并使用插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import App from './App.vue' import Vue from 'vue' import store from './store' + import VueRouter from 'vue-router' + import router from './router' Vue.config.productionTip = false + Vue.use(VueRouter) new Vue({ el: "#app", render: h => h(App), store, + router, beforeCreate() { Vue.prototype.$bus = this }, })
|
./router/index.js
在src文件夹下创建一个router文件夹,然后在其中创建index.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
import VueRouter from 'vue-router'
import TodoList from '../components/TodoList'
const router = new VueRouter({ routes: [{ path: "/TodoList", component: TodoList }, ] })
export default router
|
路由的使用
router-link与router-viewer
由路由管理的地方 a标签转换成 router-link 标签 href=”相对路径” 变成 to=”路由路径”
要显示组件的地方需要用到router-view占位,当点击时显示About组件中的内容时就会替换掉**router-view
通常由路由管理的组件单独放在pages文件夹下,不需要在App组件中引入和注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <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标签在路由器中被router-link取代 --> <!-- 使用路由提供的标签 点击跳转到/about路径 显示哪个组件在路由中配置好--> <!-- active-class 点击时激活类名 --> <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"> <!-- 这里存放由路由分配 这里放显示的组件类似于slot--> <!-- 显示的组件会替换掉router-view --> <router-view></router-view> </div> </div> </div> </div> </div> </template> <script> // 自己引入的组件 由路由管理的组件成为路由组件,通常放在pages文件夹下面 // 和普通的组件分开 而且不需要引入和注册 import Banner from "./components/Banner"; export default { name: "App", // 组测组件 components: { Banner }, }; </script> <style> </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
import VueRouter from 'vue-router'
import About from '../pages/About' import Home from '../pages/Home'
export default new VueRouter({ routes: [ { path: "/about", component: About }, { path: "/home", component: Home } ] })
|
多级路由
多级路由用到了children属性,routes中的属性成为一级路由,一级路由中children属性中的路由成为二级路由,以此类推。
在一级路由中路径要写”/“ 二级路由和多级路由中的路径不写”/“
跳转多级路由时,to=”路由路径” 要写全!从一级路由开始写!(如: to=”/home/news”)
可以给路由配置name属性,传递参数的时候会用到,添加name属性后跳转就不用写全路径,可以直接写路由的name (:to=”{name:’msg’}”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| routes:[ { path:'/about', component:About, }, { path:'/home', component:Home, children:[ { name:'news' path:'news', component:News }, { name:'message' path:'message', component:Message, children: [ { name:'msg' path: 'msgdata', component: Msgdata, } ] } ]
|
路由的传参
query传参
写法一
1 2
| <!-- 跳转并携带query参数,to的字符串写法 --> <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
|
写法二
1 2 3 4 5 6 7 8 9 10 11
| <!-- 跳转并携带query参数,to的对象写法 --> <!-- name:'detail' 可以写路由的name 也可以直接写路径 --> <router-link :to="{ path:'/home/message/detail', query:{ id:666, title:'你好' } }" >跳转</router-link>
|
组件接收数据
使用$route.query
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <div> <h3>信息编号:{{ $route.query.id }}</h3> <h3>信息标题:{{ $route.query.title }}</h3> </div> </template> <script> export default { name: "Msgdata", }; </script> <style> </style>
|
当有多个需要传递的参数时,也可以在路由设置./router/index.js
中使用props进行获取,然后再传递到组件中
1 2 3 4 5 6 7 8 9
| { path: 'msgdata', component: Msgdata, props($route){ return {id:$route.query.id, title:$route.query.title} } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div> <h3>信息编号:{{ id }}</h3> <h3>信息标题:{{ title }}</h3> </div> </template> <script> //组件接收 export default { name: "Msgdata", props: ["id", "title"], }; </script> <style> </style>
|
params传参
路由设置
在路由设置中给想使用params传参定义path属性
1 2 3 4 5 6 7 8 9
| { name: 'shownews' path: 'shownews/:id/:name', component: ShowNews, props:true }
|
直接路径传参
给to
加上冒号变成:to
,并将路径写成模板字符串,然后用${}配合模板字符串。
1 2 3
| <router-link :to="`/home/news/shownews/${n.id}/${n.name}`"> {{ n.name }} </router-link>
|
写成对象形式
如果是写成对象形式的话,就不需要再路由设置中配置path属性了。
1 2 3 4 5 6 7 8 9 10 11 12
| <router-link :to="{ // 用params传递参数时用到他的对象写法中不可使用 path:'路径' name: 'shownews', params: { id: n.id, name: n.name, }, }" > {{ n.name }} </router-link>
|
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <ul> <!-- query里面写数据 --> <li>编号{{ id }}</li> <li>姓名{{ name }}</li> </ul> </template> <script> export default { name: "ShowNews", props: ["id", "title"], }; </script>
|
replace属性
** 不留下操作记录**1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 1. 作用:控制路由跳转时操作浏览器历史记录的模式 2. 浏览器的历史记录有两种写入方式:分别为```push```和```replace```,```push```是追加历史记录,```replace```是替换当前记录。路由跳转时候默认为```push``` 3. 如何开启```replace```模式:```<router-link replace .......>News</router-link>```
---
# 编程式路由导航
不借助```<router-link>``` 实现路由跳转,让路由跳转可以更灵活,其他标签也可以通过js函数实现路由跳转。
```javascript //$router的两个API //push:跳转并且有操作记录 this.$router.push({ name:'xiangqing', params:{ id: xxx, title: xxx } }) //replace:跳转没有操作记录 this.$router.push({ name:'xiangqing', params:{ id: xxx, title: xxx } }) this.$router.forward() //前进 this.$router.back() //后退 this.$router.go() //可前进也可后退
|
缓存路由组件
让不展示的路由组件保持挂载,不被销毁
其中组件如果有多个需要缓存的话,可以写成数组:"['组件1','组件2','组件']"
如果不配置include
属性,则缓存所有用到的组件
1 2 3
| <keep-alive include="要缓存的组件名"> <router-view></router-view> </keep-alive>
|
activated和deactivated
路由组件独有的两个新的生命周期钩子,与mounted、beforeDestroy等同级别
配置在需要用到的组件内,其中:
1)activated路由组件被激活时触发。
2)deactivated路由组件失活时触发。
路由守卫
作用:对路由进行权限管理,必须符合条件才能访问
全局守卫
在所有的路由发生前都执行,有三个参数to:去哪个路径,from:从哪个路径里来,next:是个函数调用的时候next()放行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| router.beforeEach((to,from,next)=>{ console.log('beforeEach',to,from) if(to.meta.isAuth){ if(localStorage.getItem('school') === 'atguigu'){ next() }else{ alert('暂无权限查看') } }else{ next() } }) router.afterEach((to,from)=>{ console.log('afterEach',to,from) if(to.meta.title){ document.title = to.meta.title }else{ document.title = 'vue_test' } })
|
独享守卫
放在需要进行权限设置的路由里面,参数语法和全局一样 当访问这个路径前才执行beforeEnter()
1 2 3 4 5 6 7 8 9 10 11 12 13
| beforeEnter(to,from,next){ console.log('beforeEnter',to,from) if(to.meta.isAuth){ if(localStorage.getItem('school') === 'atguigu'){ next() }else{ alert('暂无权限查看') } }else{ next() } }
|
组件守卫
放在组件里,和methods,components同级别 ,
必须是通过路由规则进入该组件才可以调用
beforeRouteEnter(),beforeRouteLeave()
1 2 3 4 5 6
| beforeRouteEnter (to, from, next) { }, beforeRouteLeave (to, from, next) { }
|
附录
参考文章:
道貌岸然304——Vue中的路由