# 基础使用
# 安装
npm install vue-router
# 配置
执行插件
// router/index.js import VueRouter from 'vue-router' Vue.use(VueRouter)插件原理参见文章:插件源码分析
创建实例
// router/index.js import VueRouter from 'vue-router' const routes = [ { path: '/home', component: Home } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router全部路由配置参见:路由配置选项
绑定根实例
// main.js import Vue from 'vue' import App from './App.vue' import router from './router' new Vue({ router, render: (h) => h(App) }).$mount('#app')
# 路由组件
<p>
<router-link to="/home">home1</router-link>
<router-link :to="{name: 'home'}">home2</router-link>
<router-link to="/home" replace>home3</router-link>
</p>
<router-view></router-view>
- router-link被渲染为a标签
- router-view用于容纳匹配到的组件
- to属性可以传入路径字符串,也可以传入location对象
- 使用replace替换掉当前history记录,而不是新增一条记录
# 导航方法
# router.push
router.push(location, onComplete?, obAbort?)
router-link组件内部调用该方法
该方法会在history栈添加一条新纪录
location可以是一个字符串路径,也可以是一个描述地址的对象
router.push('/home') router.push({path: '/home'}) // /home/1 router.push({name: 'home', params: {id: 1}}) // /home?id=1 router.push({path: '/home', query: {id: 1}})onComplete: 导航成功后回调
onAbort: 导航终止后回调
# router.replace
router.replace(location, onComplete?, obAbort?)
- 同router.push,只是不向history栈中添加记录、
- router-link组件中添加replace属性则调用该方法
# router.go
router.go(n)
- 在浏览器history记录中进行跳转
- router.go(-1):后退一步
- router.go(3): 前进三步
- 如果n超过了history记录数量则不会执行
# 嵌套路由
// App.vue
<template>
<div>
<router-link to="/user/profile"></router-link>
<!-- 根组件 -->
<router-view></router-view>
</div>
</template>
// User.vue
<template>
<div>
User
<!-- 路由组件User -->
<router-view></router-view>
</div>
</template>
// UserProfile.vue
<template>
<div>
<!-- 路由组件UserProfile -->
UserProfile
</div>
</template>
// router/index.js
const routes = [
{
path: '/uesr',
component: User,
children: [
{
path: 'profile', // 如果变成/profile则变为绝对路径,只能通过http://xxx/profile访问
component: UserProfile
}
]
}
]
- 如果被渲染的组件内还有
router-view则可以使用嵌套路由。 - 嵌套路由不同于路由组,不是简单的将一组路由归于一个BaseUrl之下,嵌套路由中的层级关系必须对应于组件中router-view的层级关系。比如User组件只能投射到App组件的router-view,而UserProfile只能投射到User组件的router-view。
# 动态路由
# 路径参数
const routes = [
{
path: '/user/:id',
component: User
}
]
- 路径参数用
:标记,参数值会被放到this.$route.params - 导航时使用
/user/1或{name: 'user', params: {id: 1}}作为参数
# 通配路由
使用通配符
*匹配任意路径const routes = [ { path: '/user-*', component: NotFound } ]- 通配符匹配的内容会传入this.$route.params.pathMatch字段
- 导航时可以使用
/user-123或{name: 'user', params: {pathMatch: 123}}作为参数
# 命名路由和视图
# 命名路由
const routes = [
{
path: '/user',
name: 'user',
component: User
}
]
- 命名路由可以帮助开发者通过路由名实现导航,如router.push({name: 'user'})
# 命名视图
<template>
<div>
<router-link to="/home"></router-link>
<router-view></router-view>
<router-view name="sidebar"></router-view>
</div>
</template>
const routes = [
{
path: '/home',
components: {
default: Main,
sidebar: SideBar
}
}
]
- router-view可以有多个,多个router-view之间通过命名加以区分
- 如果没有name属性,则默认名为default
# 重定向和别名
# 重定向
const routes = [
{
path: '/profile',
redirect: '/user/profile'
// redirect: {name: 'userProfile'}
// redirect: to => '/user' + to.path
}
]
- 重定向会将路由导航至新的地址,可以传入一个path,一个location对象,也可以传入函数
- 如果传入函数,函数中的to指向的是当前路由,不是调转后的目标路由,这里to.path 为 /profile
- 导航守卫不会作用在跳转路由上,而是作用在目标路由上,这里只会作用在/user/profile之上
# 别名
const routes = [
{
path: '/user',
name: 'user',
component: User,
children: [
{
path: 'profile',
name: 'userProfile',
component: UserProfile,
// 实际访问/user/profile
alias: '/userprofile',
},
],
},
]
- 别名用于路径重写,浏览器地址栏中会保留别名路径,包括this.$route对象中的路径也是别名
- 别名可用于自定义路径,不必拘束于嵌套关系
# 组件传参
通常在组件内获取路由参数需要通过this.$route.params等方式,这样使得组件和route对象强耦合。
vue-router支持向组件props传参,避免组件自己从route对象中获取。
<template>
<div>
User {{ name }}
</div>
</template>
<script>
export default {
props: {
name: String
}
}
</script>
const routes = [
{
path: '/user/:name',
component: User,
props: true // 默认将this.$route.params传递给props
// props: {name: 'zhuli'} // 静态传入
// props: route => ({name: route.query.name})
}
]
# 导航模式
# hash模式
vue-router默认使用hash模式:
http://localhost:8080/#/about/2
在hash模式下,前端路由被统一放在一个#后面,如此浏览器便不会重新发起请求
# history模式
hash模式不太好看,可以选择history模式:
const router = new VueRouter({
mode: 'history',
routes
})
history模式下的路径就和普通路径一样了:
http://localhost:8080/about/2
vue-router使用history.pushState方法更新history记录而不重新发起请求
但如果我们首次打开页面或者刷新页面,浏览器就会发起请求,不同于hash模式#前面的路径永远不变,history模式下的路径会整个传给后端服务器,比如nginx中配置:
location ^~ / {
root /usr/share/html;
index index.html;
}
那么当我们请求/home/user等路径时便会返回404,因为nginx下没有这个页面。(nginx会将路径名转换为文件路径进行文件查找)
所以为了防止这种404的情况,我们需要修改nginx的配置
location ^~ / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
在这种配置下,所有的路径都会优先去找相应的文件(比如各种css,js文件),如果没找到就会重定向到http://localhost:8000/index.html地址,于是就可以解决上述的404问题。
#
← RouterView 导航守卫 →