快速链接
这篇文章记录的是学习Vue2.x时的VueRouter的用法,部分使用方式可能过时,以官方文档为准。
基础配置
// /src/router/index.js
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '@/components/Home'
import About from "@/components/About"
// 1. 通过Vue.use(插件) 来安装这个插件
Vue.use(VueRouter)
// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
}
]
// 2. 创建一个路由对象
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
})
// 3. 将router对象传递给Vue实例
export default router
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router/index'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// router: router
router
}).$mount('#app')
<!-- App.vue -->
<template>
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-view></router-view>
</template>
<script>
// ...
</script>
router-link
会被默认渲染成a标签
history模式
默认情况下是hash模式, 要改成history模式, 需要在index.js里进行设置
hash模式:
url: localhost:8080/#/home
history模式:
url: localhost:8080/home
// /src/router/index.js
// 2. 创建一个路由对象
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
mode: 'history'
})
router-link的其他属性
<!--App.vue-->
<template>
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-view></router-view>
</template>
-
to
: 到哪儿 -
tag
: 渲染成什么组件, 不用的话是<a>
-
replace
: 如果使用了replace, 就不能用浏览器的前进和后退 -
active-class
: 当<router-link>
对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active
的class, 设置active-class
可以修改默认的名称-
在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类.
.router-link-acitve{ 'color': 'red' }
-
但是通常不会修改类的属性,会直接使用默认的
router-link -active
即可.
修改方式:
<router-link to="/home" active-class="active">首页</router-link>
// /src/router/index.js // 2. 创建一个路由对象 const router = new VueRouter({ // 配置路由和组件之间的应用关系 routes, mode: 'history', linkAcitveClass: 'active' })
-
通过事件实现路由跳转
<!--App.vue-->
<template>
<button @click="toHome">首页</button>
<button @click="toAbout">关于</button>
<router-view></router-view>
</template>
<script>
export default{
name: 'App',
methods:{
toHome(){
// 不要这样做: 跳过了Vue
// history.pushState();
this.$router.push('/home'); // <--------
// 或
this.$router.replace('/home');
},
toAbout(){
this.$router.push('/about');
}
}
}
</script>
动态路由
处理一些path不确定的情况, 如:
/user/16656
/user/65455
// /src/router/index.js
// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/user/:userId',
component: User
}
]
<!--App.vue-->
<template>
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-link :to="''/user'+userId" tag="button" replace>用户</router-link>
<h2></h2>
<router-view></router-view>
</template>
<script>
export default{
name: 'App',
data(){
return{
userId: '123',
}
}
}
</script>
获取一些url里的参数:
<!--User.vue-->
<template>
<h2>{{userId}}</h2>
</template>
<script>
export default{
name: 'User',
computed:{
userId(){
return this.$route.params.userId
}
}
}
</script>
路由懒加载
解决打包时单个js文件过大的问题
方式一: 结合Vue的异步组件和Webpack的代码分析. (能看懂就行)
const Home = resolve => { require. ensure([ '../components/Home.vue' ], () => { resolve( require('../components/Home.vue'))})};
方式二: AMD写法
const About = resolve => require(['../components/About.vue'], resolve);
方式三: 在ES6中,我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.(常用)
// /src/router/index.js
// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/home',
component: ()=>import('../components/Home') // <--- 懒加载
}
]
嵌套路由
实现类似如下的功能:
/home/news
/home/message
步骤:
- 创建对应子组件, 在路由映射中配置对应子组件
- 在组件内部使用
<router-view>
标签
// /src/router/index.js
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '@/components/Home'
import About from "@/components/About"
import News from '@/components/News'
import Message from "@/components/Message"
// 1. 通过Vue.use(插件) 来安装这个插件
Vue.use(VueRouter)
// 写一些配置路径
const routes = [
{
path: '', //或'/'
redirect: '/home' //重定向, 直接跳转到/home下
},
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [
{
path: '',
redirect: News
},
{
path: 'news',
components: News
},
{
path: 'message',
components: Message
}
]
}
]
// 2. 创建一个路由对象
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes,
})
// 3. 将router对象传递给Vue实例
export default router
<!--Home.vue-->
<template>
<router-link to="/home/news">新闻</router-link>
<router-link to="/home/message"消息</router-link>
<router-view></router-view>
</template>
(注意路径为: /home/news
, 而不是/news
)
路由参数传递
参数传递主要有两种方式: params和query
-
params类型(之前提到过)
- 配置路由格式:
/router/:id
- 传递的方式: 在path后跟上对应的值
- 传递后形成的路径:
/router/123
- 获取:
route.params.id
- 配置路由格式:
-
query类型:
- 配置路由格式:
/router
(普通配置) - 传递方式: 在对象中使用query的key作为传递方式
- 传递后形成的路径:
/router?id=123
- 配置路由格式:
-
获取:
route.query.id
<!--App.vue--> <!--也可以在方法中跳转--> <template> <router-link :to="{path: '/home', query:{name:'123', age:18}}" >首页</router-link> <router-view></router-view> </template>
全局导航守卫
-
一种利用生命周期函数实现监视页面变化
created(){ // 界面创建时 } mouted(){ // 界面挂载时 } updated(){ // 界面更新时执行 }
-
全局守卫 -- 监听路由跳转 -- hook
// /src/router/index.js // 写一些配置路径 const routes = [ { path: '', //或'/' redirect: '/home' //重定向, 直接跳转到/home下 }, { path: '/about', component: About, meta: { title: '关于' } }, { path: '/home', component: Home, meta: { title: '首页' } ] } ] // 2. 创建一个路由对象 const router = new VueRouter({ // 配置路由和组件之间的应用关系 routes, }) // 前置守卫(guard) router.beforeEach((to, from, next)=>{ // 必须调一次next() document.title = to.meta.title; // document.title = to.matched[0].meta.title // 如果有路由嵌套 next(); }) // 后置钩子(hook) router.afterEach((to, from)=>{ })
next()用法很灵活
- 这里只展示了全局守卫, 其实还有路由独享守卫和组件内的守卫
keep-alive
keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
router-view也是一个组件,如果直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存:
<keep-alive>
<router-view/>
</keep-alive>
// 只有该组件被保持了keep-alive时, 才是有效的
activated(){
//,..
}
deactivated(){
//...
}
两个重要的属性
填写字符串或正则表达式, 只有匹配的组件才会/不会被缓存
<keep-alive include="About">
<router-view/>
</keep-alive>
<keep-alive exclude="About,User"> <!--这里不能随便加空格-->
<router-view/>
</keep-alive>
评论区