单页面应用(SPA)
- 整个项目只有一个完整的页面
- 只做局部的刷新,相较于传统的多页面做整个页面的刷新
- 数据通过ajax请求进行获取
优点:拥有更好的用户体验,前后端分离开发,更加灵活高效
缺点:初次加载所有资源,内存花费较大
route and router
- route是用来获取路由信息,router是用来操作路由
- route是一个跳转的路由对象(路由信息对象),每一个路由都会有一个$route对象,是一个局部的对象
- router包含了所有的路由,包括路由的跳转方法,钩子函数等,是VueRouter的一个实例
嵌套路由(多级路由)
index.js路由配置文件
export default new VueRouter({
mode:history,// 区别于hash工作模式
routes:[
{
name:'aboutName', // 路由名称可简化多级路径
path:'/about', // 路径
component:About, // 组件
meta:{name:'zs', title:'aaa'} // 可以携带自定义数据
children:[
{
// 子路由配置
path:'abc' // 子路由可不带 '/'
}
]
}
]
})
页面触发:<router-link to="/about">About</router-link>
页面的<router-link>最后会翻译成<a>标签进行点击后跳转
路由传参
路由的传参有两种方式:query 和 params
query
字符串写法
<router-link :to="`/home/messages/detail?id=${m.id}`">{{abc}}</router-link>
对象写法:
<router-link :to="{
path: '/home/messages/detail',
query: {
id: m.id,
title: m.title
}
}">{{ abc }}</router-link>
接收{{ $route.query.id }}
query传参不涉及路由器的更改,可以使用name配置简化路由路径配置
params
字符串配置
<router-link :to="`/home/messages/detail/${m.id}/${m.title}`">{{abc}}</router-link>
跳转配置
<router-link :to="{
name: 'messagesName', 必须用name,不能用params
params: {
id: m.id,
title: m.title
}
}">{{ abc }}</router-link>
一定需要和router联合配置:声明参数,不能使用path,一定使用name
children:[
{
name:'messagesName',
path:'detail/:id/:title',
component:Detail
}
]
总结:
query形式:
to='字符串写法' key=value的形式传参
:to={对象写法} 可使用path或者name指定路径
params形式:
to='字符写法' /value/value的形式传参,需要路由path:'detail/:id/:title'指定格式
:to='对象写法' 只能使用name指定路径
接收参数: $route.query.id 或者 $route.params.title
route的props配置项
通过$route获取数据展示比较繁琐
<li>消息编号{{ $route.params.id }}</li>
<li>消息标题{{ $route.params.title }}</li>
<li>消息编号{{ $route.query.id }}</li>
<li>消息标题{{ $route.query.title }}</li>
使用computed:{}计算属性实现出来,页面简洁,但是代码量也相差不大
使用props更加简便
children:[
{
name:'messagesName',
path:'detail/:id/:title', params形式
path:'detail', query形式
component:Detail,
一共有三种方式,第一种主要是传递不变的数据,第二种通过params传递数据,第三种通过函数传递
props:{a:1, b:2} props:['',''] 直接在组件中通过props:['','']接收
props:true, props:通过params的方式传入到组件
props($route){ // props:通过函数操作传入的数据,query的方式传入组件
return {id:$route.query.id, title:$route.query.title}
}
}
]
接收数据只需要在组件中设置:props:['id','title']
页面展示:
<li>消息编号{{ id }}</li>
<li>消息标题{{ title }}</li>
replace and push
路由对于浏览器的历史记录的影响
replace模式:替换当前的历史记录
<router-link replace class="list-group-item active" to="/about">About</router-link>
push模式(默认):追加当前的历史记录
编程式路由
之前都是通过实现路由跳转,现在通过$router的实例方法,进行跳转
通过.push跳转:以push模式 追加的方式跳转
通过.replace跳转:以replace模式 替换之前历史记录跳转
通过.go:能够跳转之前和之后或者刷新go(0)
this.$router.push({
name: 'detailName',
query: {
id: m.id,
title: m.title
}
})
this.$router.replace({
name: 'detailName',
query: {
id: m.id,
title: m.title
}
})
this.$router.go(-3)
路由缓存
组件切换的时候,上一个组件会被销毁掉,这个时候可以缓存数据,以便下次切换查看数据
缓存填入的信息,指定组件的名称,让不展示的路由组件保持挂载,不被销毁
两种写法,缓存一个或者多个,include填写组件名称
<keep-alive include="MyNews">
<router-view></router-view>
</keep-alive>
或者
<keep-alive :include="['MyNews', 'MyMessage']">
<router-view></router-view>
</keep-alive>
问题:有缓存的组件,不会被销毁,那么就会涉及到激活和失活的两种状态,对应了两个函数的调用
两个新的声明周期钩子:
activated(){
组件激活执行
}
deactivated(){
组件失活执行
}
不要忘记还有一个:
this.$nextTick(){
当修改了数据,页面挂载完毕后执行
}
路由守卫
概念:守卫路由的跳转,可作为跳转前后的判断。
分类:全局守卫,独享守卫,组件内的守卫。
添加全局 前置 路由守卫,第一次加载页面执行,每次切换路由之前执行
router.beforeEach((to, from, next) =>{
// to 目标路由信息
// console.log(to);
// from 来自其路由信息
// next 是否跳转
// meta 路由元信息,用来配置自定义信息,可配置查看是否需要权限
if (to.meta.isAuth === true) {
if(localStorage.getItem('stu') === '1233') {
next()
} else {
alert("没有权限")
}
} else {
next()
}
})
添加全局 后置 路由守卫,第一次加载页面执行,每次切换路由之后执行
router.afterEach((to) =>{
document.title = to.meta.title ? to.meta.title : 'gogo'
})
export default router
独享路由守卫
某一个路由单独使用的限制
beforeEnter(to, from, next){
}
没有 独享后置路由 守卫,可以配合 全局后置路由 守卫一起使用
组件内路由守卫
能够写组件单独的逻辑
export default {
name: 'MyAbout',
beforeRouteEnter(to, from, next){
// 通过路由规则进入该组件之前被调用
},
beforeRouteLeave(to, from, next){
// 通过路由规则离开该组件之前被调用
}
}
路由两种工作模式
路由器的两种工作模式:体现在地址栏上
hash模式,兼容性强
localhost:8080/#/myBoot/student ====> hash
从#号开始,到结束,都叫做hash
hash不会作为路径随着http请求发送给服务器
history模式,简洁
localhost:8080/myBoot/student
上线问题
history模式404问题(后端解决,可以使用nginx:分辨到底是后端路由还是前端路由)
上线就使用hash模式,history模式好看,一刷新就完蛋了,需要解决,通过后端解决
element-ui 按需引入
全部引入
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css' // 引入所有样式所有的组件
文件太大,没有必要全部引入
按需引入 + cli配置
npm i babel-plugin-component -D
修改babel.config.js 预设包
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
[旧"es2015"或者新"@babel/preset-env", { "modules": false }],
],
plugins: [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
main.js按需引入插件
import { Button, Row, DatePicker } from 'element-ui'; 样式会自动引入
Vue.use(Button)
Vue.use(Row)
Vue.use(DatePicker)