主题列表:浅谈VUE-Router
What?
官方的说法:ue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。
其实本质就是: 建立起url和页面之间的映射关系。
Why?
为了让大家更好更快的构建一个单页面应用而出现的。
How:
VueRouter使用模型:将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。
- 在项目根目录下创建Router文件夹,专门存放路由逻辑。
- 在文件夹内创建一个入口文件:index.js。
//首先安装vurRouter,在终端执行命令 npm i vue-router -s 然后在导入
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from "../views/Home.vue";
//初始化我们的Router
Vue.use(VueRouter)
//url -->视图(组件)的映射关系
const router = new VueRouter({
//信息
routers:[
{
//路径
path:"/",
//渲染的组件,必须先将组件导入
component: Home
}
]
})
- 然后在mian.js中导入router
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
new Vue({
router,
render: h => h(App)
}).$mount("#app");
- 最后配合router-view或者router-link 在对应的位置展示即可
<router-view> <router-view/>
动态路由 路由对象 $router
// 可以通过$router.params拿到对应的参数,如果有过个参数,则可以通过$router.query获取
// 动态路由匹配优先级: 谁先定义,谁的优先级就搞
//src/Router/index.js
const router = new VueRouter({
routers:[
{
path:"user/:id",
//Home组件内通过this.$router.params拿到id
component: Home
}
]
})
- 但是动态路由存在一个问题,当我访问的id(动态的值)发生变化后,user组件是不会重新去加载的。
- 解决办法,利用watch监听$router里面的值。或者利用beforeRouteUpdate()
watch: {
$route(val) {
console.log(val);
// 请求后端数据 来获取最新的数据
},
},
beforeRouteUpdate() {
console.log("router- update");
console.log(this.$route);
},
路由组件传参 props
- 在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
- 我们可以通过 props 向组件内传递参数即可
//src/Router.index.js
const router = new VueRouter({
routers:[
{
path:"user/:id",
component: Home,
props:true//将props设置为true,动态id就会像组件间通信一样传递给user组件
//props 可以接受 boolean,object,function
}
]
}).
//src/components/user.vue
<template>
{{id}}
</template>
export default {
props: ["id"],
}
编程式路由 push() repleace()
//两则都可以完成跳转,但是push()具有返回上一级功能。而 repleace() 没有
function(){
this.$router.push({
path:'/user',
})
this.$router.repleace({
path:'/user',
})
}
路由导航
- 本质:钩子函数,类似于Vue生命周期
- 全局前置守卫 router.beforeEach(to,from,next),大多数在这里处理权限问题
const router = new VueRouter({
routers:[
{
path:"user/:id",
//Home组件内通过this.$router.params拿到id
component: Home
},
]
router.beforeEach(to,from,next){
to:是你要去的路由对象;
from:源头(从哪里来的);
next:是一个function,必须调用。如果不调用就会直接卡在beforeEach这里,页面就不会渲染,相当于下一步的意思。
}
})
- 路由独享的守卫 router.beforeEnter().
const router = new VueRouter({
routers:[
{
path:"user/:id",
//Home组件内通过this.$router.params拿到id
component: Home
},
beforeEnter(to,from,next){
}
]
})
- 组件内的守卫 beforeRouteEnter(),beforeRouteUpdate(2.2 新增),beforeRouteLeave()
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
//最好在这里发送接口请求
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
- 全局后置守卫
const router = new VueRouter({
routers:[
{
path:"user/:id",
//Home组件内通过this.$router.params拿到id
component: Home
},
]
//全局前置路由守卫
router.beforeEach(to,from,next){
to:是你要去的路由对象;
from:源头(从哪里来的);
next:是一个function,必须调用。如果不调用就会直接卡在beforeEach这里,页面就不会渲染,相当于下一步的意思。
}
//全局后置路由守卫,没有next参数
router.afterEach(to,from){
}
})
- 整体流程
1.导航被触发。
2.在失活的组件里调用 beforeRouteLeave 守卫。
3。调用全局的 beforeEach 守卫。
4。在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
5.在路由配置里调用 beforeEnter。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter。
8.调用全局的 beforeResolve 守卫 (2.5+)。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。