1.路由基本结构 2.router-link 3.命名路由 4.路由参数规则 5.重定向和别名 6.$route 和 $router的区别 7.多视图 8.监听路由 9.导航守卫 10. 路由懒加载
1.容器
<router-view></router-view>2.路由表
let router=new VueRouter({ routes: [ {path, component}, {path, component}, {path, component}, ... ] });3.添加到vm对象
new Vue({ el, data, ..., router: router })编译完之后就是a标签。主要通过to属性来进行路由跳转
<router-link class="nav" :to="{name: 'news', params: {id: 98}}">页面1</router-link> <router-link class="nav" to="/b">页面2</router-link> <router-link class="nav" to="/c" tag="div">页面3</router-link>tag可以将默认的a标签改为你指定的标签,比如div
router-link-active 是router-link当前的选中自带class名称,自己可以通过这个class改变成你想要的效果。
router-link 也是遵守下面的路由参数规则
对路由设置name属性,为了方便路由的跳转,如果单纯的通过path跳转,一旦path的值过长,或者路由嵌套很深,会显的很乱维护也比较麻烦。 name属性是可选的。
<router-link class="nav" :to="{name: 'news'}">页面1</router-link> routes: [ { path: '/news', name: 'news', // look at here component: { template: '<div>新闻:{{$route.params.id}}</div>' } }当多个路由同时匹配到了,那么谁写在最前面就匹配谁的。
routes: [ { path: '/news/aaa/', component: { template: '<div>新闻2</div>' } }, { path: '/news/:id/', component: { template: '<div>新闻:{{$route.params.id}}</div>' } }如果路由输入为/news/aaa 上面的结果会匹配第一个 显示为新闻2。
路由可以通过name,path,params,query来进行参数的传递以及路由的跳转。那么应该如何合理的使用这么参数呢?
// 字符串 router.push('home') // 对象 router.push({ path: '/home' }) // 命名的路由 router.push({ name: 'user', params: { userId: '123' }}) // 带查询参数,变成 /register?plan=private router.push({ path: '/register', query: { plan: 'private' }})如果提供了 path,params 会被忽略(因为path是死路经,params是动态路径,query只是路径后的参数),上述例子中的 query 并不属于这种情况。
所以一般我们写路由的时候可以通过两种方式传参:
router.push({ path: ‘/register’, query: { plan: ‘private’ }}) (path +query) //register?plan=privaterouter.push({ name: ‘user’, params: { userId: ‘123’ }}) (name+params)// user/123重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:
const router = new VueRouter({ routes: [ { path: '/a', redirect: '/b' } ] })重定向的目标也可以是一个命名的路由:
const router = new VueRouter({ routes: [ { path: '/a', redirect: { name: 'foo' }} ] })甚至是一个方法,动态返回重定向目标:
const router = new VueRouter({ routes: [ { path: '/a', redirect: to => { // 方法接收 目标路由 作为参数 // return 重定向的 字符串路径/路径对象 }} ] })注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在下面这个例子中,为 /a 路由添加一个 beforeEach 或 beforeLeave 守卫并不会有任何效果。
“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,那么“别名”又是什么呢?
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
const router = new VueRouter({ routes: [ { path: '/a', component: A, alias: '/b' } ] })“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。
$route.path :字符串,等于当前路由对象的路径,会被解析为绝对路径,如 “/home/news” 。 $route.params :对象,包含路由中的动态片段和全匹配片段的键值对。 $route.query :对象,包含路由中查询参数的键值对。例如,对于 /home/news/detail/01?favorite=yes ,会得到$route.query.favorite = ‘yes’ 。
$route.router :路由规则所属的路由器(以及其所属的组件)。 $route.matched :数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。 $route.name :当前路径的名字,如果没有使用具名路径,则名字为空。
this.$router.push( string|object);
fn1(){ this.$router.push('/news/19'); string this.$router.replace({name: 'news', params: {id: Math.random()}}); object },history其实是一个栈,所以路由需要push/replace来操作这个栈。
push(string|object) 入栈
replace(string|object) 替换最后一个历史纪录(当前)
go(int) 就是前进后退
1.watch 简单——只能看不能干预
watch: { $route(value, old_value){ console.log(value, old_value); } }2.路由守卫 ---- 可以阻止路由的跳转 也能控制。
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。
你可以使用 router.beforeEach 注册一个全局前置守卫:
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to, from) => { // ... })你可以在路由配置上直接定义 beforeEnter 守卫:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })这些守卫与全局前置守卫的方法参数是一样的。
最后,你可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnterbeforeRouteUpdate (2.2 新增)beforeRouteLeave const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 }, beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。 不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) { next(vm => { // 通过 `vm` 访问组件实例 }) }注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteUpdate (to, from, next) { // just use `this` this.name = to.params.name next() }这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
beforeRouteLeave (to, from , next) { const answer = window.confirm('Do you really want to leave? you have unsaved changes!') if (answer) { next() } else { next(false) } }全局的前置守卫: beforeEach beforeResolve 全局的后置钩子: afterEach (钩子函数 这里没有 next) 路由独享的守卫: beforeEnter 组件内的守卫: beforeRouterEnter、beforeRouterUpdate、beforeRouteLeave
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。
首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):
const Foo = () => Promise.resolve({ /* 组件定义对象 */ })第二,在 Webpack 2 中,我们可以使用动态 import语法来定义代码分块点 (split point)
import('./Foo.vue') // 返回 Promise如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法。
结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
const Foo = () => import('./Foo.vue')在路由配置中什么都不需要改变,只需要像往常一样使用 Foo:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] }) 可在路由中简写 { path:'/foo', name:'foo', component: () => import('@/components/foo') }有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。
/* webpackChunkName: “group-foo” */ 是打包后文件名称,后面是文件路径。
‘./Foo.vue’ 是文件路径。
(可配置或者不配置)在build目录下找到webpack.prod.conf.js文件,将output修改为
output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'),//文件格式,文件名.文件哈希 chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')//文件切割后的文件名称。这里的name对应的就是路由中引入文件时候的webpackChunkName }还有一种形式: 也是实现懒加载的方法。
vue-router相关的内容就先介绍到这里了,希望对您有所帮助~。