vue-router
1.路由(vue的一个插件),就是一组映射关系;
2.key为路径,value可能是function或component
安装
vue-router
vue3 对应vue-router 4(npm i vue-router)
vue2 对应vue-router 3(npm i vue-router@3)
注意:
1.路由组件通常存放
pages文讲夹,一般组件通常存放在
components
文件夹。
2.通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
3.每个组件都有自己的$route 属性,里面存储着自己的路由信息。
4.整个应用只有一个router,可以通过组件的$router属性获取到。
基本路由使用
app.vue
<template> <div id="app"> <div class="app-con"> <ul class="nav nav-pills nav-stacked"> <li role="presentation" class="active"> <router-link to="/home" active-class="a-active">Home</router-link> </li> <li role="presentation"> <router-link to="/about" active-class="a-active">about</router-link> </li> </ul> <router-view></router-view> </div> </div> </template> <script> /* eslint-disable */ export default { name: "App", components: {}, data() { return {}; }, computed: {}, mounted() {}, methods: {}, }; </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; justify-content: flex-start; color: #2c3e50; margin-top: 60px; display: flex; flex-direction: column; .app-con { display: flex; flex-wrap: wrap; justify-content: space-around; .a-active { font-size: 20px; } } button { width: 80px; height: 38px; } } </style>
index.js(创建文件夹routes/index.js)
import vueRouter from 'vue-router' import About from '../components/About' import Home from '../components/Home' // 创建一个路由器 export default new vueRouter({ routes:[ { path:"/about", component:About, }, { path:"/home", component:Home, } ] })
mian.js
import Vue from 'vue' import App from './App' import vueRouter from 'vue-router' import router from './router' Vue.config.productionTip = false Vue.use(vueRouter) new Vue({ render: h => h(App), router:router }).$mount('#app')
嵌套路由(多级路由的使用)
路由的query参数
<li v-for="item in messageList" :key="item.id">
//方法1
<!-- <router-link :to='`/home/news/details?id=${item.id}`'>
{{ item.title }}
</router-link> -->
//方法2
<router-link
:to="{
path: '/home/news/details',
query: {
id: item.id,
},
}"
>{{ item.title }}</router-link>
</li>
details.vue
<template>
<div>
{{ this.$route.query.id }}//取值
</div>
</template>
//路由的配置
{
path:"/home",
component:Home,
children:[
{
path:"contants",
component:Contants,
},
{
path:"news",
component:News,
children:[
{
path:'details',
component:Details
}
]
},
]
}
命名路由
// 创建一个路由器
export default new vueRouter({
routes:[
{
name:'guanyu',
path:"/about",
component:About,
},
{
path:"/home",
component:Home,
children:[
{
path:"contants",
component:Contants,
},
{
path:"news",
component:News,
children:[
{
name:'xiangqing',
path:'details',
component:Details
}
]
},
]
}
]
})
<router-link :to="{ name: 'guanyu' }">about</router-link>
<router-link
:to="{
name: 'xiangqing',
query: {
id: item.id,
},
}"
>{{ item.title }}</router-link >
路由的params参数
{
path:"news",
component:News,
children:[
{
name:'xiangqing',
path:'details/:id/:title',//占位符
component:Details
}
]
},
使用
<router-link :to="`/home/news/details/${item.id}/${item.title}`">
{{ item.title }}
</router-link>
<router-link
:to="{
name: 'xiangqing',
params: {
id: item.id,
},
}"
>{{ item.title }}</router-link
>
特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!
获取
{{ this.$route.params.id }}
{{ this.$route.params.title }}
路由的props的配置
<template> <ul> <li>消息编号:{{id}}</li> <li>消息标题:{{title}}</li> </ul> </template> <script> export default name:'Detail', props:['id','title'], </script>
router-link的replace属性
编程式路由导航(即不借助router-link)
1.作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活
2.具体编码:
//$router的两个API
this.$router.push({
name:'xiangqing',
params :{
id:xxx,
title:xxx
}
})
this.$router.replace({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退this.$router.go(2)前进2,this.$router.go(-1)后退1
缓存路由组件(作用:让不展示的路由组件保持挂载,不被销毁。)
<keep-alive include="news">
//缓存多个的写法<keep-alive :include="['news1','news2']">,news1为组件name
//都缓存<keep-alive >
<router-view></router-view>
</keep-alive>
<template>
<div class="hello">
<p>Home</p>
<ul class="nav nav-pills nav-stacked">
<li role="presentation" class="active">
<router-link to="/home/news" active-class="a-active">news</router-link>
</li>
<li role="presentation">
<router-link to="/home/contants" active-class="a-active"
>contants</router-link>
</li>
</ul>
<keep-alive include="news">
<router-view></router-view>
</keep-alive>
</div>
</template>
两个新的生命周期钩子
1.作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
2.具体名字:
1.激活(Activated)路由组件被激活时触发。
2.停用路由组件失活时触发。
activated() {
console.log("News.vue激活");
},
deactivated() {
console.log("News.vue失活");
},
路由守卫
全局守卫
import vueRouter from 'vue-router'
import About from '../components/About'
import Home from '../components/Home'
import News from '../components/News'
import Contants from '../components/Contants'
import Details from '../components/Details'
// 创建一个路由器
const router= new vueRouter({
routes:[
{
name:'guanyu',
path:"/about",
component:About,
meta:{
title:"关于"
}
},
{
path:"/home",
component:Home,
meta:{
title:"主页"
},
children:[
{
path:"contants",
component:Contants,
},
{
path:"news",
component:News,
meta:{
isAuth:true //需要进行权限校验, isAuth自定义字段
},
children:[
{
name:'xiangqing',
path:'details/:id/:title',
meta:{
title:"详情"
},
component:Details,
// props:{
// "id":1,
//
"title":"hello"
// }
}
]
},
]
}
]
})
// 全局前置路由守卫--路由切换之前被调用
router.beforeEach((to ,from,next)=>{
console.log("@@@@@@@@@@@")
// if(to.path==='News'){
if(to.meta.isAuth){
if(localStorage.getItem("name")==="yes"){
// document.title=to.meta.title||"klltext" 在前置守卫要写两次,后置只用写一次
next()
}else{
alert("无权限 ")
}
}else{
// document.title=to.meta.title||"klltext"
next()
}
})
// 后置路由守卫
router.afterEach((to,from)=>{
console.log("后置路由守卫")
document.title=to.meta.title||"klltext"
})
export default router
独享守卫
routes:[
{
name:'guanyu',
path:"/about",
component:About,
meta:{
title:"关于"
},
beforeEnter(to ,from,next){
console.log("@@@@@@@@@@@")
// if(to.path==='News'){
if(to.meta.isAuth){
if(localStorage.getItem("name")==="yes"){
// document.title=to.meta.title||"klltext" 在前置守卫要写两次,后置只用写一次
next()
}else{
alert("无权限 ")
}
}else{
// document.title=to.meta.title||"klltext"
next()
}
},
},
]
组件内守卫
beforeRouteEnter (to, from, next) {
// console.log('TO:', to, 'FROM:', from, 'NEXT', next)
if (to.query.id !== undefined) {
localStorage.setItem('selFirstColName', '') // 存radio第一列选择的数据
localStorage.setItem('selColum', '') // 存储radio最后一项的索引
localStorage.setItem('projectTypeParent', '') // 存“接口返回”的radio第一列数据
localStorage.setItem('projectType', '') // 存“接口返回”的radio第二列或第三数据
localStorage.setItem('fromIdBP', '')
localStorage.setItem('firstProject_id', to.query.id) // 不存在参数时设置为空 解决新增计划时缓存造成第三环节表单有数据的问题
Axios({
url: '/serverapp/api/shghbzspxt/planfillingsteps/getstep/' + to.query.id,
method: 'get'
}).then(res => {
if (res.data.errorcode.message === '成功') {
console.log('调用获取当前规划接口返回的数据:', res)
localStorage.setItem('projectType', JSON.stringify({'selKey': res.data.data.project_type})) // 列表进入时获取规划类型小类 第四环节修改环节数时使用
localStorage.setItem('projectTypeParent', JSON.stringify({'selKey': res.data.data.project_type_parent})) // 列表进入时获取规划类型(第一步) 第三环节跳转表单的时候使用
localStorage.setItem('ptUrl', res.data.data.pt_url)
console.log('获取参数@@@@@@@@@@:', localStorage.getItem('projectType'))
let hasParm = res.data.data.last_step + ''
let name = hasParm === '3' ? 'allThreeLink' : (hasParm === '4' ? 'allFourLink' : '')
if (hasParm === '4') { // 跳转到第四环节
let cType = res.data.data.project_type
next({name: name, params: {'currentPlan': parseInt(hasParm), 'fromId': to.query.id, 'type': cType}})
} else { // 第三环节
next({name: name, params: {'currentPlan': parseInt(hasParm), 'fromId': to.query.id}})
}
}
})
} else {
next()
}
}
hash 和history模式
hash模式下,仅hash符号之前的url会被包含在请求中,后端如果没有做到对路由的全覆盖,也不会返回404错误。
history模式下,前端的url必须和实际向后端发起请求的url一致,如http://abc.com/user/id,后端如果没有对user/id的路由处理,将返回404错误。(后端开发可解决)
// 创建一个路由器
const router= new vueRouter({
mode:'hash',
routes:[
{
name:'guanyu',
path:"/about",
component:About,
meta:{
title:"关于"
},
beforeEnter(to ,from,next){
console.log("@@@@@@@@@@@")
// if(to.path==='News'){
if(to.meta.isAuth){
if(localStorage.getItem("name")==="yes"){
// document.title=to.meta.title||"klltext" 在前置守卫要写两次,后置只用写一次
next()
}else{
alert("无权限 ")
}
}else{
// document.title=to.meta.title||"klltext"
next()
}
},
},
]
})