vue 是 Vue Router 是 Vuejs 官方的路由器,他和 Vue.js 深度集成,是用于单页应用中组件之间的导航,本质上就是通过 components 和 router 进行映射绑定,使用 router-link 传入指定的组件地址,通过 router-view 渲染已经和组件地址绑定好的组件。
<template> <div> <router-link to="/index/login">login</router-link> <router-link to="/index/search">search</router-link> <router-view></router-view> </div> </template>
再实际的项目的开发中,肯定是有多层级的页面。配置多层级的路由就是给上一级路由增加 children 在参数,在 children 添加新的路由信息
routes: [ { path: "/index", component: renderView, children: [ { path: "index", name: "name", component: Index, children:[ { path: "product", name: "product", component: Product, } ] }, { path: "login/:user/comic/:age", name: "name", component: Login, }, { path: "search", name: "search", component: Search, }, { path: "*", name: "rank", component: Rank, }, ], }, ],
一个路由就是一个 Object ,如果有下一层级,就在里面加上一个 children 数组。
获取 URL 的参数是 router 的 path 里面加上 : 号,用来区分是一个动态的参数。在 render 组件的时候,执行 this.$route.params 就可以获取到动态传递的参数。
// router.js { path: "comic/:id/chapter/:id", name: "name", component: Comic, }, // component.vue console.log(this.$route.params); //{ comic:123, chapter:456 }
而默认路由地址,这个一般会是设置成主页或者 404 的情况,就是在找不到 URL 的地址是映射到什么组件的情况下,跳转到 404 页面或者是统一跳转到首页。一般情况下,是会跳转到 404 。然后把这个配置的映射放在了 router 的最后一项。
// router.js ...... { path: "search", name: "search", component: Search, }, { path: "*", name: "rank", component: Rank, },
JavaScript 执行路由跳转这个是我自己的说法,官网给出的说法是叫作编程式路由 。一开始看到这个词逼格很高,但看完解释就是代码操作路由跳转。最后,还是按我自己的理解来把这个标题定为 JavaScript 执行路由跳转。在 Vue Router 中,有两种执行路由跳转的方式,第一种是声明式,第二种是编程式。
声明式:
<router-link to="/index/login">login</router-link>
通过 router-link 标签执行指定跳转。
编程式:
// vue this.$router.push() this.router.push({ name: 'user', params: { userId }}) // -> /user/123 this.router.push({ path: `/user/${userId}` }) // -> /user/123 // router router.push(...);
在 vue 实例中,可以通过 $router 访问路由,可以直接使用 this.$router.push() 进行操作。在使用的时候需要注意的一点就是,当有 path 的时候, params 会被忽略。所以需要像上面一样以字符串形式拼接 URL。
与 router.push 相似的还有 router.replace,他们之间唯一不同的地方就是, router.replace 会替换掉当前的历史记录。这个和 location.href 和 location.replace 是类似的。而官网最后也提到了,router.push、 router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go (opens new window)好像, 实际上它们确实是效仿 window.history API 的。
路由命名只需要在 router 中在 path 同级下增加一个 name,之后使用 router.path ( name: index ,..)
即可。
// set routes: [ { path: '/index/:Id', name: 'index', component: Index } ] // link router.push({ name: 'index', params: { Id: 123 } })
多视图展示 ,实质上就是增加 router-view 的标签,再通过 router 的 component 增加视图的名称。
<div> <router-view class="one" name="one"></router-view> <router-view class="two" name="two"></router-view> </div>
routes: [ { path: '/', components: { default: Index, one: Search, two: Details, } } ]
使用 redirect 参数,对 URL 进行替换 , 重定向的场景一般适用于兼容的情况下,比如项目改造升级,原有的 URL 如果希望保持不变,那么就可以用重定向指向新的 URL 。
routes: [ { path: '/index', redirect: '/index/index' } ]
还有一个方法是叫别名,但是这个一般我没有使用,总感觉这样的方法会留下一些潜规则,所以一直不会使用这个方法,他的原理就是 URL 不变,但却走了另一个映射。
在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
以对象模式通过 props 进行解耦
routes: [ { path: '/user/:id', component: User, props: true }, { path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ]
以函数模式
routes: [ { path: '/search', component: Search, props: route => ({ query: route.query.name }) } ]
vue-router 的钩子函数也叫导航守卫。这里有三种守卫类型,第一种是全局前置守卫
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { console.log(to) })
导航在出发的时候它都会执行。这里有一点要注意是,确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。
// BAD router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) // 如果用户未能验证身份,则 `next` 会被调用两次 next() })
// GOOD router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) else next() })
第二种是全局解析守卫,这个和全局前置守卫差不多,唯一的区别就是在导航确认之前所有的守卫和异步路由组件被解析后执行。
最后一种是全局后置钩子,这个和前面不同的是,这个钩子没有 next 函数体。
router.afterEach((to, from) => { console.log(to) })
除了全局守卫之外还有路由独享的路由,他的用法就是在 routes 里面加上 beforeEnter。
routes: [ { path: '/index', component: Index, beforeEnter: (to, from, next) => { // ... } } ]
还有一个组件内的守卫,他的方法是写在组件里面的。他也有三个方法,后面会有一个具体例子。
const Index = { template: `...`, beforeRouteEnter(to, from, next) { }, beforeRouteUpdate(to, from, next) { }, beforeRouteLeave(to, from, next) { } }
像以往获取数据的方法一般是写在了组件的函数里面,也就是导航完成后,执行数据的拉取。那么,还有另一种方法就是,在导航之前加载数据。
它的原理就是我们在组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后只调用 next 方法。
import { ajax } from '../../js/common/ajax-helper'; export default { data() { return { num: 1 } }, // 方法一 beforeRouteEnter(to, from, next) { console.log(to) console.log(window.location.href) ajax(to.params.id, (err, post) => { next(vm => vm.setData(err, post)) }) }, // 方法二 beforeRouteUpdate (to, from, next) { this.post = null ajax(to.params.id, (err, post) => { this.setData(err, post)}); next(); }, methods: { setData(err, num){ this.num = num; console.log(this.num) } } }
vm 是当前实例,在进入这个路由之前获取 to.params.id ,发送请求拿到数据之后,通过 next 执行将数据挂载。
方法二是已经到了路由更新之前的阶段,可以直接通过 this 执行组件代码。执行完毕再执行下一步
我们需要将不同路由对应的组件分割成不同的模块,然后在路由在被访问的时候才加载对应的组件,这样能够大大降低页面性能的损耗。
const Index = () => import(/* webpackChunkName: "Index" */ './Index.vue'); const Search = () => import(/* webpackChunkName: "Search" */ './Search.vue'); const Details = () => import(/* webpackChunkName: "Details" */ './Details.vue') const router = new VueRouter({ routes: [{ path: '/Details', component: Details }] });
这里其实也是 vue 和 webpack 结合使用的功能,到了新的 vite 工具可能会使用新的一些方法可以后面再了解下。
这里引用一段 DEMO 的代码,也是比较简单。
import VueRouter from 'vue-router' const { isNavigationFailure, NavigationFailureType } = VueRouter router.push('/admin').catch(failure => { if (isNavigationFailure(failure, NavigationFailureType.redirected)) { showToast('Login in order to access the admin panel') } })
使用 vue-router 最好的方法还是阅读文档,若换一个 React 又有属于它的插件,虽说,大致的逻辑不会相差太远,但肯定是另外一套写法。所以,在理解了一个插件的实现功能之后去理解下一个类似的插件就可以带着一些问题去了解它,理解起来就会更容易上手也能对插件之间进行对比和选型。
在下次接触 react 的路由插件可以从这几个点去思考
PHP虚拟主机 哪个品牌的好?php 虚拟主机 就是支持PHP程序语言的虚拟主机,不同...
随着我们建站的深入,有些站长、有些网站单纯的 虚拟主机 已经不能满足我们网站...
美国前邮政部长,美国百货商店之父,约翰华纳梅克(John Wanamaker)感叹到:「我...
正值“十四五”开局之年,金融行业立足新发展阶段、贯彻新发展理念,守正创新,...
客户介绍 新浪微博(Sina Weibo)是基于用户关系的社交媒体平台,用户可以通过 P...
如何将FSS对象存储挂载到lWindows服务器?如果是用的 TOP云 的FSS对象存储的话,...
数据分析师的工作中最离不开的就是数据,业务中所有的情况都离不开数据这个载体...
4月15日,2021 GIDC全球互联网数据大会在深圳隆重召开。在本次大会同步的“金Dat...
在创建VPC之前,您需要根据具体的业务需求规划VPC的数量、子网的数量、IP网段划...
{"index":{"_id":4}}{"title":"四轮电动车_ 电动汽车报价_阿里巴巴采购批发_超多...