Vue前端路由
路由
路由是一个比较广义的概念, 路由的本质就是对应关系
后端路由 : 根据不同的URL请求返回不同的内容 , 本质就是 URL请求地址 和 服务器资源之间的对应关系
SPA ( Single Page Application)
- 后端渲染(存在性能问题)
- Ajax前端渲染 (前端渲染提高性能 , 但是不支持浏览器的前进后退操作)
- SPA 单页面应用程序 : 整个网站只有一个页面 , 内容的变化通过Ajax局部更新时间 , 同时支持浏览器地址栏的前进回退操作
- SPA 实现原理之一 : 基于URL地址的hash (hash 的变化会导致浏览器记录访问历史的变化 , 但是 hash 的变化不会触发新的URL请求)
- 在实现SPA过程中 , 最核心的技术点就是前端路由
前端路由 : 根据不同的用户事件 , 显示不同的页面内容 , 本质就是用户事件与事件处理函数之间的对应关系
Vue Router
https://router.vuejs.org/zh/ 它和 vue.js 的核心深度集成 , 可以非常方便的用于 SPA 应用程序的开发
- 支持HTML5历史模式或hash模式
- 支持嵌套路由
- 支持路由参数
- 支持编程式路由
- 支持命名路由
Router 基本使用步骤
引入相关包
<!-- 依赖于vue -->
<script src="./vue-router.js"></script>
创建路由连接
<!-- router-link 是 Vue 中提供的标签 默认会被渲染为 a 标签
to 属性默认会被渲染为 href 属性
to 属性的值默认会被渲染为 # 开头的 hash 地址 -->
<router-link to="/user">user</router-link>
<router-link to="/register">register</router-link>
添加路由占位符
<!-- 将来通过路由规则匹配到的组件, 将会被渲染到 router-view 所在的位置 -->
<router-view></router-view>
创建路由组件
const User = {
template: '<h1>User 组件</h1>''
}
const Register = {
template: '<h1>Register 组件</h1>'
}
创建路由实例对象
const router = new VueRouter({
// 所有路由规则
routes: [
// path 就是 router-link 的 to 属性
// component 就是路由组件的名称
{ path: '/user', component: User},
{ path: '/register', component: Register }
]
})
挂载实例对象
var vm = new Vue({
el: '#app',
// router: router
router
})
路由重定向
用户在访问地址A的时候, 强制用户跳转的地址C, 从而展示特定的组件页面
const router = new VueRouter({
routes: [
// path 原路径 redirect 目标路径
{ path: '/', redirect: '/user' },
{ path: '/user', component: User },
{ path: '/register', component: Register }
]
})
嵌套路由
- 点击父路由链接显示模板内容
- 模板内容中又有子级路由模板
- 点击子路由链接显示子级模板内容
// 定义子路由模板
const Register = {
template: `
<div>
<h1>Register 组件</h1>
<!-- 子路由规则标签 -->
<router-link to="/register/tab1">tab1</router-link>
<router-link to="/register/tab2">tab2</router-link>
<!-- 子路由占位符 -->
<router-view></router-view>
</div>
`
}
// 定义子路由内容
const Tab1 = {
template: '<h2>tab1</h2>'
}
const Tab2 = {
template: '<h2>tab2</h2>'
}
// 定义子路由规则
const router = new VueRouter({
routes: [
{ path: '/user', component: User },
{
path: '/register',
component: Register,
children: [
{ path: '/register/tab1', component: Tab1 },
{ path: '/register/tab2', component: Tab2 }
]
}
]
})
动态路由匹配基本使用
应用场景 : 通过动态路由参数的模式进行路由匹配
<!-- 模拟动态路由 -->
<router-link to="/user/1">user1</router-link>
<router-link to="/user/2">user2</router-link>
<router-link to="/user/3">user3</router-link>
// 获取路由参数
const User = {
template: `<div><h1>User 组件</h1> -- {{ $route.params.id }}</div>`
}
const router = new VueRouter({
routes: [
// id 匹配规则
{ path: '/user/:id', component: User },
{ path: '/register', component: Register }
]
})
路由组件传递参数
$route 与对应的路由高度耦合, 不够灵活 , 所以可以使用props将组件和路由解耦
props 是布尔值
const router = new VueRouter({
routes: [
// 如果props设置为true route.params 将会被设为组件属性
{ path: '/user/:id', component: User, props: true},
]
})
const User = {
props: ['id'],
template: `<div><h1>User 组件</h1> -- {{ id }}</div>`
}
props 是对象
const router = new VueRouter({
routes: [
// 如果 props 设置为 {} 那么 id 就不能被使用了
{ path: '/user/:id', component: User, props: {uname: 'zs', age: 23} },
]
})
const User = {
props: ['uname', 'age'],
template: `<div><h1>User 组件</h1> -- {{ uname }} -- {{ age }}</div>`
}
props 是函数
const router = new VueRouter({
routes: [
// 如果 props 设置为 函数 那么函数返回的内容都是可以使用的
{ path: '/user/:id', component: User, props: route => ({uname: 'zs', age: 23, id: route.params.id}) },
]
})
const User = {
props: ['uname', 'age', 'id'],
template: `<div><h1>User 组件</h1> -- {{ uname }} -- {{ age }} -- {{ id }}</div>`
}
命名路由的配置规则
为了更方便的表示路由的路径, 可以给路由起一个别名, 即为 命名路由
<!-- 命令路由通过属性绑定调用 -->
<router-link :to="{ name: 'user', params: { id: 3 } }">user3</router-link>
const router = new VueRouter({
routes: [
// 命名路由就是给路由规则加上name属性
{ name: 'user', path: '/user/:id', component: User, props: route => ({uname: 'zs', age: 23, id: route.params.id}) },
]
})
页面导航的两种方式
- 声明式导航, 通过点击链接的方式叫做声明式导航
- 普通网页中的 a 链接, 或 vue 中的
<router-link></router-link>
- 普通网页中的 a 链接, 或 vue 中的
- 编程式导航 , 通过调用 JavaScript形式的 API 实现当行方式, 叫做编程式导航
- 普通中
location.href = ""
- 普通中
Vue 中的编程式导航
this.$router.push('hash 地址')
this.$router.go(n)
1 , -1
const User = {
props: ['uname', 'age', 'id'],
template: `<div>
<h1>User 组件</h1> -- {{ uname }} -- {{ age }} -- {{ id }}
<button @click="goRegister">跳转到register</button>
</div>`,
methods: {
goRegister() {
this.$router.push('/register')
}
},
}
const Register = {
template: `<div>
<h1>Register 组件</h1>
<button @click="goUser">回退</button>
</div>`,
methods: {
goUser() {
this.$router.go(-1)
}
},
}
router.push()
方法的参数规则
// 字符串(路径名称)
this.$router.push('/user')
// 对象
this.$router.push({path: '/home'})
// 命令路由
this.$router.push({name: 'user', params: {userId: 123}})
// 带查询参数, 变成 /register?uname=zs
this.$router.push({path: '/register', query: {uname: 'admin'}})