(生产)vue-router:路由
参考:https://router.vuejs.org/zh-cn/
安装
直接下载 / CDN
https://unpkg.com/vue-router/dist/vue-router.js
使用:
<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>
NPM
npm install vue-router
使用:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
使用:
动态路由匹配
例子:
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
/user/foo
和/user/bar
都将映射到相同的路由一个『路径参数』使用冒号
:
标记。当匹配到一个路由时,参数值会被设置到this.$route.params
,可以在每个组件内使用
模式 匹配路径 $route.params /user/:username /user/evan { username: 'evan' }
/user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: 123 }
响应路由参数的变化
从
/user/foo
导航到user/bar
,原来的组件实例会被复用 , 意味着组件的生命周期钩子不会再被调用复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch(监测变化)
$route
对象watch: { '$route' (to, from) { // 对路由变化作出响应... } }
匹配优先级
有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高
嵌套路由
例子:
export default new Router({
routes: [
{
path: '/',//设置默认根页面
redirect: '/recommend'
},{
path: '/recommend',
component: component:require('../pages/login-common/login'),
children: [
{
path: ':id',
component: '组件'
}
]
}]
})
编程式的导航
使用:
除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
router.push(location) 点击 <router-link :to="..."> 等同于调用router.push(...)
方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL参数:
router.push('home') // 字符串
router.push({ path: 'home' }) // 对象
router.push({ name: 'user', params: { userId: 123 }}) // 命名的路由
router.push({ path: 'register', query: { plan: 'private' }}) // 带查询参数,变成 /register?plan=private
router.replace(location):
跟
router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录<router-link :to="..." replace> == router.replace(...)
router.go(n) :
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
命名视图
想同时(同级)展示多个视图,而不是嵌套展示 , 命名视图就派上用场了 , 如果
router-view
没有设置名字,那么默认为default
例子:
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>确保正确使用
components
配置(带上 s):const router = new VueRouter({
routes: [{
path: '/',
components: {default: Foo,
a: Bar,
b: Baz
}
}]
})
导航钩子
vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的
全局钩子有三个,分别是beforeEach、beforeResolve和afterEach,在路由实例对象注册使用
beforeEach:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => { })
三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 执行效果依赖 next 方法的调用参数
next(): 进行管道中的下一个钩子
next(false): 中断当前的导航
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航
确保要调用 next 方法,否则钩子就不会被 resolved
afterEach:
不像
before
钩子那样,after
钩子没有next
方法,不能改变导航例子:
router.beforeEach((to,from,next)=>{
console.log('global beforeEach')
next();
});router.beforeResolve((to,from,next)=>{
console.log('global beforeResolve')
next();
});router.afterEach((to,from,next)=>{
console.log('global afterEach')
});
某个路由独享的钩子 beforeEnter
在路由配置上直接定义
beforeEnter
钩子const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {}
}]
})
组件内的钩子
beforeRouteEnter
beforeRouteUpdate
(2.2 新增)beforeRouteLeave
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`, 因为当钩子执行前,组件实例还没被创建
//传一个回调给 next来访问组件实例
next(vm => {
// 通过 `vm` 访问组件实例
})
},beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用//
beforeRouteLeave
中直接访问this
。这个leave
钩子通常用来禁止用户在还未保存修改前突然离开。可以通过next(false)
来取消导航
}
执行时机
由首页进入user页面:
global beforeEach > router beforeEnter > component beforeRouteEnter > global beforeResolve > global afterEach > mounted
由user回到首页:
component beforeRouteLeave => global beforeEach => global beforeResolve => global afterEach
排除beforeRouteUpdate,其余六个导航钩子的执行时机其实很好理解。大体按照leave、before、enter、resolve、after的顺序并全局优先的思路执行。beforeRouteUpdate的触发是在动态路由情形下,比如 path: '/user/:userName' 这条路由,当页面不变更只动态的改变参数userName时,beforeRouteUpdate便会触发
总结:
使用vue组件拼凑成整个应用,每个页面是独立的,路由依靠链接跳转,会刷新页面。使用vue-router则可以不刷新页面加载对应组件,hash和history模式模拟路径变化,不刷新页面
数据获取
导航完成之后获取:
先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示
created () {
// 组件创建完后获取数据,此时 data 已经被 observed 了
// 基于
$route.params.id
获取文章数据fetchData();
},
watch: {
// 如果路由有变化,会再次执行该方法
'$route': 'fetchData'
},
导航完成之前获取:
导航完成前,在路由的
enter
钩子中获取数据,在数据获取成功后执行导航beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) =>
if (err) {
next(false)
} else {
next(vm => {vm.post = post })
}
})
},
路由懒加载
打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
Vue 的 异步组件 和 Webpack 的 code splitting feature , 实现路由组件的懒加载
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}使用 AMD 风格的 require , 实现路由组件的懒加载
const Foo = resolve => require(['./Foo.vue'], resolve)
使用 es6 风格的 import, 实现路由组件的懒加载
const Recommend = (resolve) => {
import('components/recommend/recommend').then((module) => {
resolve(module)
})
}
API
<router-link>
支持用户在具有路由功能的应用中(点击)导航, 默认渲染成带有正确链接的 <a>
标签,可以通过配置 tag
属性生成别的标签 ,
目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名
to :
被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象
<router-link to="home">Home</router-link> <!-- 字符串 -->
<router-link v-bind:to="'home'">Home</router-link> <!-- 使用 v-bind 的 JS 表达式 -->
<router-link :to="'home'">Home</router-link> <!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="{ path: 'home' }">Home</router-link>
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link> <!-- 命名的路由 -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link> <!-- 结果为 /register?plan=private -->relpace :
调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录
append :
设置 append 属性后,则在当前(相对)路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
<router-link :to="{ path: 'relative/path'}" append></router-link>tag :
默认值: "a"
<router-link to="/foo" tag="li">foo</router-link>
<li>foo</li><!-- 渲染结果 -->active-class :
类型: string
默认值:"router-link-active"
设置 链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置events:
类型: string | Array<string>
默认值:'click'
声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组将"激活时的CSS类名"应用在外层元素:
我们要让 "激活时的CSS类名" 应用在外层元素,而不是 <a> 标签本身,那么可以用 <router-link> 渲染外层元素,包裹着内层的原生 <a> 标签:
<router-link tag="li" to="/foo">
<a>/foo</a>
</router-link>
在这种情况下,<a> 将作为真实的链接(它会获得正确的 href 的),而 "激活时的CSS类名" 则设置到外层的<li>
<router-view>
渲染路径匹配到的视图组件。
<router-view>
渲染的组件还可以内嵌自己的<router-view>
,根据嵌套路径,渲染嵌套组件属性 name: 类型: string ; 默认值: "default"
如果 <router-view>设置了名称,则会渲染对应的路由配置中 components 下的相应组件
可以配合 <transition> 和 <keep-alive> 使用 ,确保在内层使用 <keep-alive>
<transition>
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition
路由信息对象
route object(路由信息对象) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的 route records(路由记录)
route object 是 immutable(不可变) 的,每次成功的导航后都会产生一个新的对象
route object 出现在多个地方:
- 组件内的 this.$route 和 $route watcher 回调(监测变化处理);
- router.match(location) 的返回值
- 导航钩子的参数:
router.beforeEach((to, from, next) => {
// to 和 from 都是 路由信息对象
})路由信息对象的属性
- $route.path
类型: string
解析为绝对路径 : 如 "/foo/bar"。
- $route.params
类型: Object
一个 key/value 对象,包含了 动态片段 和 全匹配片段,如果没有路由参数,就是一个空对象。
- $route.query
类型: Object
一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。
- $route.hash
类型: string
当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。
- $route.fullPath
类型: string
完成解析后的 URL,包含查询参数和 hash 的完整路径。
- $route.matched
类型: Array<RouteRecord>
一个数组,包含当前路由的所有嵌套路径片段的 路由记录 。路由记录就是 routes 配置数组中的对象副本(还有在 children 数组)。const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{ path: 'bar', component: Bar }
]
}
]
})当 URL 为 /foo/bar,$route.matched 将会是一个包含从上到下的所有对象(副本)。
- $route.name
当前路由的名称,如果有的话。(查看 命名路由)
(生产)vue-router:路由的更多相关文章
- 前端MVC Vue2学习总结(八)——Vue Router路由、Vuex状态管理、Element-UI
一.Vue Router路由 二.Vuex状态管理 三.Element-UI Element-UI是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是 Mint U ...
- Vue系列:Vue Router 路由梳理
Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌.包含的功能有: 嵌套的路由/视图表 模块化的.基于组件的路由配置 路由参数. ...
- 04 Vue Router路由管理器
路由的基本概念与原理 Vue Router Vue Router (官网: https://router.vuejs.org/zh/)是Vue.js 官方的路由管理器. 它和vue.js的核心深度集成 ...
- Vue Router路由管理器介绍
参考博客:https://www.cnblogs.com/avon/p/5943008.html 安装介绍:Vue Router 版本说明 对于 TypeScript 用户来说,vue-router@ ...
- Vue Router 路由守卫:完整的导航解析流程
完整的导航解析流程 1 导航被触发. 2 在失活的组件里调用离开守卫. 3 调用全局的 beforeEach 守卫. 4 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+). ...
- Vue Router路由守卫妙用:异步获取数据成功后再进行路由跳转并传递数据,失败则不进行跳转
问题引入 试想这样一个业务场景: 在用户输入数据,点击提交按钮后,这时发起了ajax请求,如果请求成功, 则跳转到详情页面并展示详情数据,失败则不跳转到详情页面,只是在当前页面给出错误消息. 难点所在 ...
- Vue Router 路由实现原理
一.概念 通过改变 URL,在不重新请求页面的情况下,更新页面视图. 二.实现方式 更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式: 1.Hash ...
- Vue - Router 路由
路由的注册 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- vue router路由(三)
当环境搭建及Vue语法与指令都有所了解,该说下router. build目录是打包配置文件 (不建议动) config是vue项目基本配置文件 dist是构建后文件 js 手动创建 (根据需要) no ...
- vue router路由跳转了,但是页面没有变(已解决)
小白学习 router.js:两个组件之间跳转 但是路由变了,页面没有改变的原因是因为app.vue里面没有router-view(很关键)
随机推荐
- window.performance
利用window.performance查看网页性能 一般我们可以通过浏览器的调试工具-网络面板,或者代理工具查看网页加载过程中的各个阶段的耗时.而利用window.performance属性则可以获 ...
- docker 部署net core程序 curl访问地址 提示 Connection reset by peer
最近研究netcore 部署到docker上.在参考https://www.cnblogs.com/subendong/p/8992285.html教程之后,部署成功.但是curl访问对应的主机端口地 ...
- vs 部署SharePoint项目时, package丢失
bug描述:vs部署sharepoint项目时报错:重启iis应用池失败,未将对象设置引用到实例. 解决方案:查看项目文件(包括隐藏文件),发现package文件不见了,在回收站内能找到被删除的pac ...
- 如何查看mysql执行的所有SQL
在程序调试中,有时需要看到最终在DB执行的SQL文,而默认mysql此功能是关闭的,开启的方法如下: set global general_log='ON'; 然后用如下命令查看log文件所在路径即可 ...
- Problem03 水仙花数
题目:打印出所有的"水仙花数"."水仙花数"是指一个三位数,其各位数字立方和等于该数本身. 例如:153是一个"水仙花数",因为153=1的 ...
- Unable to verify your data submission.加入了_csrf也报400错误的解决
<input type="hidden" name="_csrf" value="<?=Yii::$app->request-> ...
- 搭建hadpoot平台(集群式分布)
1.先下载VMware1.2,然后安装. 2.下载ubuntu-1.4.05-desktop-amd64.iso.下载地址:http://mirrors.aliyun.com/ubuntu-relea ...
- docker 安装的centos7.4中无法识别文件中的中文
在容器内执行命令: 命令: yum -y install kde-l10n-Chinese && yum -y reinstall glibc-common 命令: localedef ...
- Maven 错误 Failure to transfer ...was cached in the local repository...
Maven 错误 Failure to transfer ...was cached in the local repository... 我解决的时候多了两步才解决 1. mvn clean ins ...
- derby
/** * @Title: T.java * @Package test * @Description: TODO please write your description <BR> * ...