vue-router导航守卫进阶&源码实现
栏目: JavaScript · 发布时间: 5年前
内容简介:前端路由实现起来其实很简单,本质就是监听URL的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。vue-router共有三种守卫,分别是全局守卫、路由独享守卫、组件内的守卫。效果等同于全局守卫ep:通过route设置document.title
前端路由实现起来其实很简单,本质就是监听URL的变化,然后匹配路由规则,显示相应的页面,并且无须刷新。vue-router共有三种守卫,分别是全局守卫、路由独享守卫、组件内的守卫。
导航守卫
-
全局守卫
你可以使用 router.beforeEach 注册一个全局前置守卫: ep:设置全局守卫,如果进入about页,没有登陆则重定向到login页
router.beforeEach((to,from,next) => { console.log(to.meta) // 判断是否登录 if (to.path === '/about' && !window.isLogin) { next('/login?redirect='+to.path); } else { next(); } }) 复制代码
- 路由独享守卫
{ path: "/about", name: "about", meta: {requireLogin:true}, // meta 取值就是to.meta beforeEnter(to,from,next) { // 判断是否登录 路由独享守卫 if (!store.state.isLogin) { next('/login?redirect='+to.path); } else { next(); } }, component: () => import(/* webpackChunkName: "about" */ "./views/About.vue") } 复制代码
效果等同于全局守卫
- 组件内的守卫
export default { beforeRouteEnter(to, from, next) {} beforeRouteUpdata(to, from, next) {} beforeRouteLeave(to, from, next) {} } 复制代码
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用离开守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫 (2.5+)。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
meta路由元信息
ep:通过route设置document.title
{ path: '/customer/new', name: 'NewCustomer', meta: {title: '新增客户'}, component: () => import('@/Views/CustomerNew') }, router.beforeEach(function (to, from, next) { if (to.meta && to.meta.title) { document.title = ((to.meta && to.meta.title)) } next() }) 复制代码
hash模式&&history模式
www.test.com/#/ 就是 Hash URL,当 # 后面的哈希值发生变化时,不会向服务器请求数据,可以通过 hashchange 事件来监听到 URL 的变化,从而进行跳转页面。
History 模式是 HTML5 新推出的功能,比之 Hash URL 更加美观
源码实现
应用页面
<router-link to="#/foo">foo</router-link> | <router-link to="#/bar">bar</router-link> 复制代码
router配置
const Foo = { render() { return <div>Foo</div>; } }; const Bar = { render() { return <div>Bar</div>; } }; export default new TRouter(Vue, { routes: [ { path: "/foo", component: Foo }, { path: "/bar", component: Bar } ] }); 复制代码
源码实现
import Vue from "vue"; class TRouter { constructor(Vue, options) { this.$options = options; this.routeMap = {}; // 全局的路由映射 key就是path(唯一的) this.app = new Vue({ // 对vue的强依赖 data: { current: "#/" // 当前路由 } }); this.init(); this.createRouteMap(this.$options); this.initComponent(Vue); } // 初始化 hashchange init() { // load事件在页面或某个资源加载成功时触发 window.addEventListener("load", this.onHashChange.bind(this), false); // hashchange事件在 URL 的 hash 部分(即#号后面的部分,包括#号)发生变化时触发。 window.addEventListener("hashchange", this.onHashChange.bind(this), false); } createRouteMap(options) { options.routes.forEach(item => { this.routeMap[item.path] = item.component; }); } // 注册组件 initComponent(Vue) { Vue.component("router-link", { // 全局注册 props: { to: String // 去哪个地址 }, render: function (h) { // 传入函数 h 就是createElement // <a :href="to"><slot></slot></a> // 返回的是虚拟dom return h("a", { attrs: { href: this.to } }, this.$slots.default); } }); const _this = this; // 全局this Vue.component("router-view", { // 占位符 render(h) { // 根据当前路由发生变化 渲染当前组件所匹配的组件 var component = _this.routeMap[_this.app.current]; return h(component); } }); } // 获取当前 hash 串 getHash() { return window.location.hash.slice(1) || "/"; } // 设置当前路径 onHashChange() { // 挂载的组件刷新 this.app.current = this.getHash(); // 获取最新hish赋值 console.log(this.app.current, 'this.app.current') } } 复制代码
总结
vue-router对vue也是强依赖关系,简单的也可以理解为是对history的封装,本质上还是实现根据路由不同,返回不同内容。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- angular 路由守卫
- Vue-router进阶:导航守卫
- Vue的路由动态重定向和导航守卫实例
- 在哪种感觉守卫比命令更好 – 如果? (haskell新手)
- 如何实现一个react-router路由拦截(导航守卫)
- 每天抵抗4000万次黑客访问,这个天猫双11,阿里巴巴如何守卫消费者权益?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Letting Go of the Words
Janice (Ginny) Redish / Morgan Kaufmann / 2007-06-11 / USD 49.95
"Redish has done her homework and created a thorough overview of the issues in writing for the Web. Ironically, I must recommend that you read her every word so that you can find out why your customer......一起来看看 《Letting Go of the Words》 这本书的介绍吧!