持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
SPA与前端路由
SPA指的是一个web网站只有唯一的一个HTML页面,所有组件的展示与切换都在唯一的一个页面完成,此时,不同组件之间的切换需要通过前端路由来实现
总结:在SPA的项目中,不同功能之间的切换,要依赖于前端路由来完成
前端路由
路由就是对应关系(地址和组件的对应关系,不同的地址展示不同的组件)
通俗易懂:hash地址(地址栏里#开头的地址)和组件之间的对应关系
前端路由的工作方式;
- 用户
点击了页面上的路由链接(本质就是a链接) - 导致了
URL地址栏中的hash值发生了变化 前端路由监听到了hash地址的变化前端路由把当前hash地址对应的组件渲染到浏览器中
总结:用户点击链接导致hash地址变化,hash地址的变化被前端路由监听到,然后前端路由匹配到对应组件并展示出来
后端路由:请求方式和请求地址与function处理函数之间的对应关系
前端路由:hash地址和组件之间的对应关系
vue-router的基本使用
是vue项目中路由包,react项目中不能用
步骤:
- 下载vue-router模块到当前项目
npm i vue-router
- 在main.js中引入vue-router
import VueRouter from 'vue-router'
- 使用Vue.sue()方法给vue安装插件-
Vue.sue(VueRouter) //内部自动帮我们注册注册全局RouterLink(链接)和RouterView(占位符)组件
- 创建路由规则数组-路径和组件名对应关系
const routes=[
{path:'/find',component:Find},
{path:'/my',component:My},
{path:'/part',component:Part},
]
- 用规则生成路由对象
const router=new VueRouter({
routes:routes //可简写
})
- 把路由对象注入到new Vue 实例中
new Vue({
render: h => h(App),
router //注入到vue实例中
}).$mount('#app')
- 用router-view作为挂载点,切换不同的路由页面
<router-view></router-view> //占位符,将来组件切换显示的地方
1、导入组件和创建路由规则都在mani.js里
2、挂在点写在要显示地方的组件里
声明式导航
在vue中使用来声明路由链接
并使用来声明路由占位符
注意:这两个组件是下载的路由包帮我们提供的组件
<template>
<h1> APP组件</h1>
#声明路由链接
<router-link to="/home">首页</router-link> // 用to属性替代a链接的href属性
<router-link to="/move">电影</router-link>
<router-link to="/about">关于</router-link>
#声明路由占位符————匹配到什么组件,就在这个位置渲染什么组件
<router-view></router-view>
</template>
1、声明hash地址使用to来声明,不用#开头,vue-router渲染时自动生成#(替代a标签)
2、router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
3、router-link提供了声明式导航高亮的功能(自带激活时的类名,可以做高亮)
编程式导航
通过调用API实现导航的方式,叫做编程式导航
与之对应,通过点击链接实现导航的方式,叫做声明式导航
#可用在点击按钮 事件里 实现跳转
this.$router.push('hash地址') //跳转到指定hash地址,从而展示对应的组件
this.$router.push({
path:'路由路径',
name:'路由名',//首先要在路由规则里添加name属性
//path和name都可以进行传参,二选一即可
query:{
参数名:值
},
params:{
参数名:值
}
})
#因为传参path会忽略params,所以可以规定以后使用编程式跳转时使用name跳转,以免bug
#可用在点击按钮 事件里 实现前进后退
this.$router.go(数值 n)//实现导航历史的前进、后退
使用编程式跳转,传参不需要在规则里传参数
使用声明式跳转,传参有时需要在规则里传参数名
路由传参
在跳转路由时, 可以给路由对应的组件内传值
#在router-link上的to属性传值, 语法格式如下
<router-link> to="/home?参数名=值">首页</router-link> //URL?a=1&b=2
<router-link> to="/home/值">首页</router-link> // URL/:id (需在路由规则里配置/path/:参数名)
#对应页面组件接收传递过来的值
$route.query.参数名 接收字符串格式的参数(查询参数)
$route.params.参数名 接收动态路由格式的参数(路由参数)
重定向
用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面
#在路由规则最前面添加,页面一打开就显示重定向的组件
//其中path表示 需要被重定向指定的原地址,redirect表示将要被重定向的新地址
{path:'/',redirect:'/home'} //网页打开url默认hash值是/路径(页面一打开就访问home)
路由模式切换
修改路由在地址栏的模式
#hash路由例如: http://localhost:8080/#/home
const router=new VueRouter({
routes,
mode:'hash'
})
#history路由例如: http://localhost:8080/home (以后上线需要服务器端支持, 否则找的是文件夹)
const router=new VueRouter({
routes,
mode:'history'
})
访问路径不存在
找不到路径给个提示页面
#路由规则最后, path匹配*(任意路径) – 前面不匹配就命中最后这个
//先导入显示页面不存在的组件
improt NotFound from "@/views/NotFound"
//在数组规则最后一个里定义这个规则
{path:'*',component:NotFound},
在数组最后一个位置, 插入匹配*的规则, 展示404页面
嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由
通过children属性声明子路由规则,子路由规则里
routers:[
{//父级路由规则
path:'/about',
component:about,
children:[ //通过children 属性嵌套子级路由规则
{path:'tab1',component:Tab1},//访问/about/tab1时,展示Tab1组件
{path:'tab2',component:Tab2},//访问/about/tab2时,展示Tab2组件
]
}
]
# 在子路由path里不要/开头,不加/会自动和about连接,/表示目录
动态路由匹配
一个路由规则能够匹配到多个路由的链接
动态路由:把hash地址中可变的部分定义为参数,从而提高路由规则的复用性
在vue-router中使用:来定义路由的参数项
//路由中的动态参数以:进行声明,冒号后面的是动态参数的名称
{path:'/movie/:id',component:Movie}
//将以下3个路由规则,合并成了一个,提高了路由规则的复用性
{path:'/move/1',component:Movie}
{path:'/move/2',component:Movie}
{path:'/move/3',component:Movie}
导航守卫
导航守卫用来控制路由的访问权限
#声明导航守卫:全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制
1、调用路由实例对象的beforeEach函数,声明全局前置守卫
2、fn必须是一个函数,每次拦截到路由请求,都会调用fn进行处理
3、因此fn叫做守卫方法
router.beforeEach(fn)//路由跳转之前执行这个函数,来决定要不要跳转
守卫方法的三个形参
router.beforeEach((to,from,next)=>{
//to目标路由对象
//from 当前导航正要离开的路由对象
//next 是一个函数,表示放行
})
在守卫方法中如果不声明next形参,则默认允许访问每一个路由
在守卫方法中如果声明了next形参,则必须调用next()函数,否则不允许用户访问任何一个路由
next三种调用方式
直接放行:next()
强制其停留在当前页面:next(false)
强制其跳转到登录页面:next('/login')
结合token控制后台主页的访问权限
要return
动态组件的使用
动态组件指的是动态切换的组件显示与隐藏:多个组件使用同一个挂载点,并动态切换
vue提供了一个内置的组件,专门用来实现动态组件的渲染
引入组件并且注册组件后,使用变量接受来承载要动态显示的组件
import user from '组件路径' //1、导入组件
export default {
components:{
user //2、注册组件
},
data(){
retuen{
user:'user' //3、使用变量接收要动态显示的组件
}
}
}
#在要动态显示组件的地方设置挂载点<component>,使用is属性来设置要显示哪个组件
# is="接收组件的变量名"
<div>
<component :is="user"></component> //is指定当前占位符显示哪个组件
</div>
注意:is属性的值一定是变量,只有是变量才能动态切换
设置动态组件被缓存
目的:使用动态组件时,每一次发生组件切换时,被隐藏的的组件会销毁,展示出来的组件会被重新创建,重新初始化
需求:将隐藏时的组件不被销毁(使用keep-alive 保持状态)
原理:使用 标签可以将隐藏的组件缓存起来而已,不必销毁
拓展: 标签的include属性可设置哪些标签被缓存
exclude属性可设置哪些标签不被缓存
#需要设置name属性
export default {
name:"xxx" //设置name:组件名更改为被设置的名字,调试工具里也变成name的值
//不设置name:组件名就是文件名,调试工具里显示的就是文件名
}
<keep-alive include="组件name名1,组件name名2..." >
<router-view ></router-view>
</keep-alive>
include属性可设置哪些标签被缓存
exclude属性可设置哪些标签不被缓存(不被设置的就会被缓存)
两者不能同时使用,二选一
监听组件切换的动态
需求:能够监听到组件被缓存时和激活是的状态
原理:vue提供了对应的声明周期函数
- 当组件
被缓存时,会自动出发组建的deactivated生命周期函数 - 当组件
被激活时,会自动触发组件的activated生命周期函数