路由(Vue Router)
用Vue + Vue Router
创建单页面应用非常简单。当加入Vue Router
时,需要将组件映射到路由上,让Vue知道在哪里渲染它们。
路由基本例子
<!-- 引入Vue 和 router -->
<script src="https://unpkg.com/vue@3"></script>
<script scr="https://unpkg.com/vue-router@4"></script>
<div id="app">
<p>
<!-- router-link类似a标签,最后访问的结果会放到router-view中 -->
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
</p>
<!-- 路由出口,路由匹配到的组件渲染在 <router-view> -->
<router-view></router-view>
</div
路由的第一个Demo
//1. 定义两个模版
const Home = {
template:'<div>Home</div>'}
const About = {
template:'<div>About</div>'}
//2. 自定义路由对象,也就是匹配模版所对应的路径配置
const routers = [
{
path:'/',component:Home},
{
path:'/about',component:About}
]
//3. 创建路由实例,并传递自定义的配置
const router = VueRouter.createRouter({
history:VoeRouter.createWebHashHistory(),
routers:routers
})
//4. 创建Vue实例,并且使用路由
const app = Vue.createApp({
})
//5.使用路由 , 任意组件中可以使用`this.$router`的形式访问router实例
app.use(router)
app.mount('#app')
动态路由
路由上可以添加动态字段来接受参数,称为路径参数
。redirect的时候可以省略component配置。嵌套路由例外,如果一个路由记录有children和redirect属性,它也应该有component属性。s
//1. 自定义模版
const User = {
template:"<div>User</div>"
}
//2. 动态路由参数:id , 匹配到 /users/1 , /users/qq 等
const router = [
//path可以匹配多个路径参数,/users/:id/details/:name
{
path:'/users/:id',compontent:User}
]
//3. 路由目标组件User中可以通过this.$route.params到形式获取参数,json格式{id:1,name:'zqq'}
const User = {
template:"{
{ $route.params.id }}"
}
响应路由参数的变化
可以对同一组件路由参数变化做出响应,简单的watch$route
对象上的任意属性
//模版中,created函数,用this.watch观察参数的变化
const User{
template:"<div>{
{ this.$route.params }}</div>",
created(){
this.$watch(
() => this.$route.params,
(toParams,previousParams) =>{
//路由参数变化的响应逻辑
}
);
}
}
捕获所有固定前缀路由或404 Not found路由
//定义404路由匹配组件
const NotFound = {
template:"<div>{
{ $route.params.pathMatch }}</div>"}
//定义user-* 路由匹配组件
const User = {
template:"<div>{
{ $route.params.users }}</div>"}
//定义路由
const routes = [
//匹配所有其它路由没有匹配到的路径,并且放在pathMatch下,通过$route.params.pathMatch访问匹配的所有路径,路径/a/b -> ["a","b"]
{
path:'/:pathMatch(.*)*',component:NotFound},
//匹配所有的user-前缀的路径,路径user-123 -> 123
{
path:'/user-:users(.*)',component:User}
]
嵌套路由
一些应用的UI由多层嵌套的组件组成,组件之中套着组件,可以使用嵌套路由表达这种关系,``children`关键字。
//1. 定义一个组件,组件中嵌套着路由模版 <router-view>
const home = {
template:'<div>home组件</div><router-view></router-view>'
}
//定义一个子组件
const child = {
template:'<div>子组件</div>'}
//2. 定义一个路由,包含子路由(嵌套路由)
const routes = [
{
path:'/home',
component:home,
children:[
{
path:'hello',
component:child
}
]
}
]
编程式导航
在Vue实例中,可以通过$router
访问路由实例,因粗可以通过编程式导航,调用$router
实现路由跳转。
//字符串路径
router.push('/user/detail')
//传入对象路
router.push({
path:'/user/detail'})
//命名的路由,并加上参数,让路由建立url
router.push({
name:'user',params:{
username:'zqq'}})
//带查询参数,结果是register?plan=private
router.push({
path:'register,query:{plan:'private'}'})
//带hash,结果是/about#team
router.push({
path:'/about',hash:'#team'})
命名路由
除了path
之外,可以为路由提供name
const routes = [
{
path:'/user/:username',
name:'user',
component:User
}
]
//导航到命名路由
//1. 声明式
<router-link :to="{name:'user',params:{username:'zqq'}}">
User
</router-link>
//2. 编程式
router.push({
name:'user',params:{
username:'zqq'}})
命名视图
有时候想同时展示同级多个视图,而不是嵌套,如页面的head、body、foot等。可以在界面拥有多个单独命名的视图router-view
,而不是只有一个单独的视图。
//组件
const About = {
template:'<div>This is about</div>'}
//创建多个路由视图,并命名
<router-view name="leftSidebar"></router-view>
//没有设置名词,默认为default
<router-view></router-view>
<router-view name="rightSidebar"></router-view>
//创建路由对象,指定渲染的视图
const routes = [
{
path:'/about',
components:[
leftSidebar:About
]
}
]
重定向和别名
重定向也是通过routes
配置来完成
//从 home重定向到about
const routes = [
{
path:'/home',
redirect:'/about'
}
]
//重定向到目标也可以是一个命名的路由
const routes = [
{
path:'/home',
redirect:{
name:'about'
}
}
]
//重定向到方法,动态返回重定向目标
const routes = [
{
path:'/search/:searchText',
redirect:to =>{
//触发的路由作为参数,to
return {
path:'/search',query:{
q:to.params.searchText}
}
},
//重定向这个路由
{
path:'/search'
component://组件
}
}
]
别名
可以为路由配置一个别名alias
,用户访问别名的地址相当于访问真实的path
。如果路由有参数,需要在别名中包含它们。
//这个路由在浏览器访问/user 或 /users都会渲染UserComponent组件
const routes = [
{
path:'/user',
component:UserComponent,
alias:'/users' //可以使用数组,['/users','/u']
}
]
路由组件传参
当路由的设置props
为true
的时候,参数会被设置到组件props
里。
//定义组件 ,这里直接用{
{ id }}获取路由的参数,而不是this.$roter.params
const home = {
props:['id'],
template:'<div>{
{ id }}</div>',
}
//路由配置
const routes = [
{
path:'/home/:id',
component:home,
//对于有命名的视图,需要为每个视图开启配置
//{default:true,other-view;true}
props:true
}
]
不同的历史模式
在创建路由器实例时,history
配置允许为们在不同的历史模式中进行选择。
- Hash模式
Hash模式时用createWebHashHistory
创建的,它是在内部传递的实际URL之前使用一个哈嘻字符(#)。由于这部分URL从未被发送到服务器,所有它不需要在服务器层面上进行任何特殊处理。不过URL类似这样https://127.0.0.1:8080/index.html#home
import (createRouter,createWebHashHistory) from 'vue-router' const router = createRouter({ history:createWebHashHistory(), routes:[ //...... ] });
- HTML5模式
用createWebHistory
创建HTML5模式,使用这种模式URL类似http://127.0.0.1:8080/user/id
。不过由于应用时一个单页面的客户端应用,需要有对应的服务端配置,否则会得到404
错误。const router = createRouter({ history:createWebHistory(), routes:[ //...... ] });