【vue-router】动态路由、嵌套路由、守卫以及编程式导航
例如 : 有一个user组件,对于所有id不同的用户,都要使用这个组件来渲染,那么可以在vue-router的路由路径中使用动态路径参数来达到这个效果。使用$router.push()跳转到指定路由,会向history栈添加一个新的记录,当用户点击浏览器回退按钮的时候,可以回到跳转前的url。使用name与params结合的方式传递的参数时,参数是携带在$route中的,且传递的参数是一次性的,刷
目录
一、编程式导航
编程式导航是用来做页面跳转的。
使用 <router-link>
创建 a 标签来定义导航链接实现路由跳转的方式叫做声明式导航。
编程式导航是指借助 router 的实例方法,通过编写代码来实现。
⭕️实现页面跳转的方式
1、$router.push
使用$router.push()跳转到指定路由,会向history栈添加一个新的记录,当用户点击浏览器回退按钮的时候,可以回到跳转前的url。
this.$router.push({
path:'/aDetails',
query:{id}
})
2、$router.replace
使用$router.replace不会往浏览器添加历史记录
this.$router.replace({
path:"/aDetails",
query:{id}
})
3、$router.go
$router.go用来跳转到指定页面,前进或后退都可以
//前进一步记录
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 不传递参数或者参数为 0,表示刷新当前页面
router.go()
// 如果 history 记录不够用,则会报错
router.go(-100)
router.go(100)
4、使用<router-link>标签(本质上是a标签)
5、使用a标签
⭕️参数传递的方式
1、path-query传参
this.$router.push({
path:'/aDetails',
query:{id}
})
使用path与query结合的方式传递参数时,参数会被拼接在浏览器地址栏中,并且刷新页面后数据也不会丢失。
2、name-params传参
this.$router.push({
name:"ADetails",
params:{id},
})
使用name与params结合的方式传递的参数时,参数是携带在$route中的,且传递的参数是一次性的,刷新页面数据会丢失。
例子
写个小案例:
点击文章标题跳转文章详情页(在vue-cli中写)
在components下创建两个组件:Article.vue和ArticleDetails.vue
在router下的index.js配置路由:
App.vue
Article.vue
ArticleDetails.vue
this.$route打印的结果:
运行结果如下:
可以看出,使用query传参,参数是携带在地址栏上的。
二、嵌套路由
实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。
例子:
在components下创建三个组件:AboutOne.vue、AboutTwo.vue、AboutThree.vue
AboutOne.vue
<template>
<div>
about-one
</div>
</template>
AboutTwo.vue
<template>
<div>
about-two
</div>
</template>
AboutThree.vue
<template>
<div>
about-three
</div>
</template>
在router下的index.js 配置路由:
views下的AboutView.vue
<template>
<div class="about">
<div><router-link to='aboutone'>about1</router-link></div>
<div><router-link to='abouttwo'>about2</router-link></div>
<div><router-link to='aboutthree'>about3</router-link></div>
<div>
<router-view></router-view>
</div>
</div>
</template>
三、动态路由匹配
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。
例如 : 有一个user组件,对于所有id不同的用户,都要使用这个组件来渲染,那么可以在vue-router的路由路径中使用动态路径参数来达到这个效果。动态路径参数使用冒号进行标识。
index.js
App.vue
可以看到,当我们更改动态路径参数时,页面没有发生跳转,仍然是当前页面。
四、导航守卫
当路由发生改变的时候会触发导航守卫。导航守卫分为全局守卫、路由独享守卫和组件内守卫。
1、全局守卫
全局前置守卫
beforeEach((to,from,next)=>{
next();//手动调用向下执行
next(fale);//阻止路由向下执行
})
参数说明:
to:即将要进入的目标路有对象
from:当前导航正要离开的路由
next:是一个函数,一定要调用该方法来执行这个钩子。执行效果依赖 next 方法的调用参数,参数默认为true,表示向下执行,false表示阻止路由向下执行。
全局后置守卫
全局后置守卫没有next方法,它不需要调用next方法让路由向下执行
afterEach((to,from)=>{
})
2、路由独享守卫
路由独享守卫需要进入到当前路由才会触发。
beforeEnter((to,from,next)=>{
})
3、组件内守卫
//进入组件路由时触发
beforeRouteEnter(to,from,next){};
//组件路由更新时触发
beforeRouteUpdate(to,from,next){};
//离开组件路由时触发
beforeRouteLeave(to,from,next){};
beforeRouteEnter中的this指向window,
beforeRouteUpdate 和 beforeRouteLeave中的this指向组件实例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.5.4/vue-router.min.js"
integrity="sha512-zxWuRslhjyZyRAYInXTNl4vC/vBBwLQuodFnPmvYAEvlv9XCCfi1R3KqBCsT6f9rk56OetG/7KS9dOfINL1KCQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<div id="app">
<!-- 使用路由 to表示要去的路由-->
<router-link to="/article">去文章管理</router-link>
<router-link to="/column">去栏目管理</router-link>
<router-link to="/user/1">用户管理</router-link>
<!-- 路由出口 匹配路由对应的组件 -->
<router-view></router-view>
</div>
<script>
// 组件article
let article = {
template: `
<div>文章页面</div>
`,
};
// 组件user
let user = {
template: `
<div>用户页面---{{id}}</div>
`,
// 4、组件内守卫
beforeRouteEnter(to, from, next) {
console.log(this, 'beforeRouteEnter');
console.log(to, from);
next()
},
beforeRouteUpdate(to, from, next) {
console.log(this, 'beforeRouteUpdate');
},
beforeRouteLeave(to, from, next) {
console.log(this, 'beforeRouteLeave');
next()
},
data() {
return {
id: 0
}
},
};
// 组件column
let column = {
template: `
<div>栏目页面</div>
`
};
// 配置路由对象数组
let routes = [
{
path: '/article',
component: article
},
{
path: '/column',
component: column,
// 3、路由独享守卫 只有进入当前路由时才会触发
beforeEnter: (to, from, next) => {
console.log(to,from,next);
next();
}
},
{
path: '/user/:id',
component: user
}
];
// 创建路由器对象router
let router = new VueRouter({
routes,
});
// 1、全局前置守卫
router.beforeEach((to,from,next)=>{
console.log(to,from,next);
next()
// next(false);//阻断路由向下执行
});
// 2、全局后置守卫
router.afterEach((to,from)=>{
console.log(to,from);
})
new Vue({
router,
el: "#app",
data: {
}
})
</script>
</body>
</html>
五、监听路由url地址栏变化的方法
1、在created中监听
created(){
console.log(this.$route.params.xxx)
}
2、使用watch监听
watch:{
$route(to,from){
//to ---即将进入的路由
//from --上一个离开的路由
console.log(to.params)
}
}
3、使用组件内守卫监听 (组件更新时会触发的钩子)
beforeRouteUpdate(to,from,next){
console.log(to.params)
next()
}
通过监听地址栏变化,可以获取到携带在地址栏上的参数。
六、路由模式
路由模式有hash模式和history模式,默认是hash模式。
路由模式在路由器对象中设置:
let router = new VueRouter({
routes,
// 路由模式
mode: 'history'
// mode: 'hash'
});
hash模式的工作原理是hashchange事件,可以在window监听hash的变化。我们在url后面随便添加一个#xx触发这个事件。
window.onhashchange = function (event) {
console.log(event);
}
打印出一个HashChangeEvent事件对象,在该对象内有newURL和oldURL
把window.history对象打印出来,history对象内有back()、forword()、go()等方法:
两者的区别:
1、hash会在路由路径中携带#,history在路由路径不会携带#
2、hash刷新页面不会请求服务器,history刷新页面会请求服务器
3、hash工作原理是hashchange事件
4、history工作原理是利用go、back、forward
5、hash支持低版本的浏览器,history是h5新增api
更多推荐
所有评论(0)