文章目录
1.Vuex
1-1.Vuex原理图
Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
1-2.Vuex环境搭建
- 安装vuex(vue2配vuex3)
npm i vue@3
- src下面创建store文件夹>创建index.js文件
- 在index.js中引入vue和vuex,并且应用vuex插件
// 引入vue
import Vue from "vue"
// 引入vuex
import Vuex from "vuex"
// 应用vuex
Vue.use(Vuex)
- 在index.js中准备action,mutations和state
// 配置action
const action = {}
// 配置mutations
const mutations = {}
// 配置state
const state = {}
- 创建store并且暴露store
// 创建store
const store = new Vuex.Store({
action,
mutations,
state
})
// 暴露store
export default store
- 打开main.js,导入store下的index
import store from './store/index'
- 在vue实例上配置store
new Vue({
el:'#app',
store,
render: h => h(App)
})
1-2-1.计数案例
Count.vue
<template>
<div>
<h1>当前求和为:{{sum}}</h1>
<h3>放大十倍后:{{$store.getters.bigSum}}</h3>
<h4>我在{{school}}学习{{subject}}</h4>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="addOne">+</button>
<button @click="lessOne">-</button>
<button @click="oddAddOne">奇数+</button>
<button @click="waitAddOne">待会儿加</button>
</div>
</template>
<script>
// 导入mapState
import {mapState} from 'vuex'
export default{
name:'App',
data(){
return {
n:1
}
},
computed:{
// sum(){
// return this.$store.state.sum
// },
// school(){
// return this.$store.state.school
// },
// subject(){
// return this.$store.state.subject
// }
...mapState({sum:'sum',school:'school',subject:'subject'})
},
methods:{
addOne(){
this.$store.dispatch('jia',this.n)
},
lessOne(){
this.$store.dispatch('jian',this.n)
},
oddAddOne(){
this.$store.dispatch('oddjia',this.n)
},
waitAddOne(){
this.$store.dispatch('waitjia',this.n)
}
},
mounted(){
// console.log(this);
}
}
</script>
<style>
.test1{
width: 200px;
height: 200px;
background: #ccc;
}
</style>
index.js
// 引入vue
import Vue from "vue"
// 引入vuex
import Vuex from "vuex"
// 应用vuex
Vue.use(Vuex)
// 配置action
const actions = {
jia(context,value){
console.log('action的jia被调用了');
context.commit('JIA',value)
},
jian(context,value){
console.log('action的jian被调用了');
context.commit('JIAN',value)
},
oddjia(context,value){
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
waitjia(context,value){
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
}
// 配置mutations
const mutations = {
JIA(state,value){
console.log('mutations的JIA被调用了',state,value);
state.sum += value
},
JIAN(state,value){
console.log('mutations的JIAN被调用了',state,value);
state.sum -= value
}
}
// 配置state
const state = {
sum:0,
school:'尚硅谷',
subject:'前端'
}
// 配置getter
const getters = {
bigSum(state){
return state.sum*10
}
}
// 创建store
const store = new Vuex.Store({
actions,
mutations,
state,
getters
})
// 暴露store
export default store
1-3.getter的使用
- 在Count.vue下,从state下面的getters下面拿到bigSum的返回值,就是放大十倍的效果
<h3>放大十倍后:{{$store.getters.bigSum}}</h3>
- 在index.js下
// 配置getter
const getters = {
bigSum(state){
return state.sum*10
}
}
1-4.mapState的使用
- sum:'sum’中,后者代表return this.$store.state.sum,前者就代表一个名字
1-5.mapGetters的使用
跟mapState一样替换掉了被注释的代码,或者说是用这个方法生成了别替换掉的代码
// bigSum(){
// return this.$store.getters.bigSum
// },
...mapGetters({bigSum:'bigSum'})
1-6.mapMutations的使用
点击事件后面的函数要传参数
<button @click="addOne(n)">+</button>
<button @click="lessOne(n)">-</button>
用mapMutations代替this.$store.commit()方法
commit传递的方法名和参数要在mutations里面操作所以这个方法叫做mapMutations
methods:{
// addOne(){
// this.$store.commit('JIA',this.n)
// },
// lessOne(){
// this.$store.commit('JIAN',this.n)
// },
...mapMutations({addOne:'JIA',lessOne:'JIAN'}), //模板里面的点击事件要穿value
}
1-7.mapActions的使用
<button @click="oddAddOne(n)">奇数+</button>
<button @click="waitAddOne(n)">待会儿加</button>
mapActions代替this.$store.dispatch()
dispatch传递的方法名和参数要在actions里面操作所以这个方法叫做mapActions
methods:{
// oddAddOne(){
// this.$store.dispatch('oddjia',this.n)
// },
// waitAddOne(){
// this.$store.dispatch('waitjia',this.n)
// }
...mapActions({oddAddOne:'oddjia',waitAddOne:'waitjia'})
},
1-8.vuex命令空间
1-9.vuex模块化
2.路由
2-1.路由的基本使用步骤
- 安装路由
npm i vue-router@3
- 配置路由
再src下面创建router文件夹,然后创建一个index.js文件
index.js
import VueRouter from 'vue-router'
import Home from '../pages/Home'
import About from '../pages/About'
export default new VueRouter({
routes:[
{
path:'/home',
component:Home
},
{
path:'/about',
component:About
},
]
})
- 注册路由
在main.js中引入路由并且注册路由,然后把router>index.js引入并且挂载
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
import VueRouter from 'vue-router'
import router from './router'
Vue.use(VueRouter)
new Vue({
el:'#app',
router:router,
render: h => h(App)
})
- 跳转路由
把要跳转的链接替换成< router-link to=‘路由地址’></ router-link >
<router-link class="list" active-class="active" to="/About">About</router-link>
<router-link class="list" active-class="active" to="/Home">Home</router-link>
- 路由视图
要展示哪个路由对应的组件的地方使用< router-view>< /router-view>
<router-view></router-view>
注意:
- 路由组件一般放在pages文件夹中
- 通过切换隐藏的路由组件是被销毁了,要使用,又被挂载回来
- 每个组件都有自己的$router属性,里面储存着自己的路由信息
- 整个应用只有一个router,可以通过$router获取
3.嵌套路由
创建相关组件引入,然后在一级路由下写二级路由,注意不用加/
index.js
import VueRouter from 'vue-router'
import Home from '../pages/Home'
import About from '../pages/About'
import News from '../pages/News'
import Message from '../pages/Message'
export default new VueRouter({
routes:[
{
path:'/home',
component:Home,
// 二级路由不用加/
children:[
{
path:'News',
component:News
},
{
path:'Message',
component:Message
},
]
},
// 一级路由
{
path:'/about',
component:About
},
]
})
使用的时候to后面要加完整的路径
<template>
<div>
我是Home组件
<ul>
<router-link class="news-item" active-class="active" to="/home/News">News</router-link>
<router-link class="news-item" active-class="active" to='/home/Message'>Message</router-link>
</ul>
<div class='content'>
<router-view></router-view>
</div>
</div>
</template>
4.路由的query传参
- to的字符串和对象写法
Message.vue
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 第一种写法:to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link> -->
<!-- 第二种写法:to的对象写法 -->
<router-link :to="{
path:'/home/message/detail',
query:{id:m.id,title:m.title}
}">
{{m.title}}</router-link>
</li>
<hr>
<router-view></router-view>
</ul>
</div>
</template>
<script>
export default{
name:'Message',
data(){
return {
messageList:[{
id:'001',title:'001消息'},
{id:'002',title:'002消息'},
{id:'003',title:'003消息'}
]
}
}
}
</script>
<style>
li{
list-style: none;
}
</style>
Detail.vue
2. Detail组件接收
<template>
<div>
<li>消息编号是:{{$route.query.id}}</li>
<li>消息标题是:{{$route.query.title}}</li>
<hr>
</div>
</template>
<script>
export default {
name:'About',
}
</script>
4-1.命名路由
5.路由的params参数
第一种to的字符串写法
第二种to的对象写法
6.路由的props配置
-
第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
-
第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
-
第三种写法:props值为函数该函数返回的对象中每一组key-value都会通过props传给Detail组件
7.router-link的push模式跟replace模式
- 默认开启push模式,可以实现网页的前进后退
- 开启replace模式过后,就不能实现后退了
- 直接在router-link标签添加:replace='true’或者直接写一个replace就开启了replace模式
8.编程式路由导航
8-1.back、forward、go
methods:{
back(){
this.$router.back()
},
forward(){
this.$router.forward()
},
go(){
// 传入的参数是正数,就往前走几步,
// 是负数就往后走几步
this.$router.go(3)
}
}
9.缓存路由组件
- 作用:让不展示的路由保持挂载,不被销毁
- 如果要缓存多个组件中的一部分就要绑定给一个数组,如下
<keep-alive :include=["News",'Message']>
<router-view></router-view>
</keep-alive>
- 具体编码:
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
10.两个新的生命周期钩子
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
- 具体名字:
activated:路由组件被激活时的触发
deactivated:路由组件失活时触发
activated(){
this.timer = setInterval(()=>{
this.opacity -= 0.01
if(this.opacity <= 0){
this.opacity = 1
}
},10)
console.log('组件被激活了');
},
deactivated(){
console.log('即将被销毁了');
clearInterval(this.timer)
}
11.路由守卫
11-1.前置路由守卫
- router.beforeEach((to,from,next)=>{})
- 组件之间切换的间隙触发,可以设置一些规则阻止切换,不满足就不允许切换,满足条件就允许切换
- to是切换的目标地址
- from时切换的初始地址
- next是是否允许切换
- to.meta.isAuth是设置在路由配置项的元配置项里,标识该组件是否要鉴权
router.beforeEach((to,from,next)=>{
console.log('前置路由守卫',to,from);
if(to.meta.isAuth){//判断是否 需要鉴权
if(localStorage.getItem('school') === '三河'){
next()
}
}else{next()}
})
11-2.后置路由守卫
- router.afterEach((to,from)=>{})
- 该守卫是组件切换完成后执行的,用来修改切换完成的title
- 路由里应该配置每个路由的title,在元配置项里meta:{title:‘zhuye’}
// 全局后置路由守卫
router.afterEach((to,from)=>{
console.log('后置路由守卫',to,from);
document.title = to.meta.title
})
11-3.独享路由守卫
- 某个路由单独享受的路由守卫
- beforeEnter:(to,from,next)=>{}
- 进入路由组件的时候触发
- 如果不符合条件就进入不了
children:[
{
name:'xinwen',
path:'News',
component:News,
meta:{isAuth:true,title:'新闻'},
// 单独路由守卫
beforeEnter:(to,from,next)=>{
if(to.meta.isAuth){//判断是否 需要鉴权
if(localStorage.getItem('school') === '三河'){
next()
}
}else{next()}
}
},
11-4.组件内路由守卫
- 在组件里面写的守卫
11-4-1.beforeRouteEnter
- 进入守卫,通过路由规则进入该组件的时候触发
beforeRouteEnter(to,from,next){
console.log('beforeRouteEnter组件内路由守卫',to,from);
if(to.meta.isAuth){//判断是否 需要鉴权
if(localStorage.getItem('school') === '三河'){
next()
}
}else{next()}
},
11-4-2.beforeRouteLeave
- 离开守卫,通过路由规则离开该组件的时候触发
beforeRouteLeave(to,from,next){
console.log('beforeRouteLeave',to,from);
next()
}
12.history和hash两种工作模式
12-1.hash
- 对于一个url来说 ----- #及其后面的内容就是hash值
- hash值不会包含在http请求中,就是说hash值不会带给服务器
- 地址中永远带着#号
- 若是以后将地址通过第三方手机app分享,app校验严格的话,
- 地址会被标记为不合法
- 兼容性较好
12-2.history
- 地址干净,美观
- 兼容性和hash模式相比略差
- 应用部署上线需要后端人员解决刷新页面中的404问题
13.Vue UI组件库(Elment UI)
省略