注意:
vue2xx搭配 vue-router3xx + vuex3xx + vant2xx 或 element-ui 使用
vue3xx搭配 vue-router4xx + vuex4xx + vant3xx/vant4xx 或 element-plus使用
顺便提一句
在vue3项目里推荐使用低版本的vue-router 比如4.0.1版本 高版本在使用params传参时会报错
1 创建一个vue2项目(此时vue-cli版本为4.5.15,node.js为14xx)
① vue create vue2 (vue2是项目名 可自拟任意名称) 回车
② 点击 ↓ 键选择Manually select features 回车
③ 点击 ↓ 键分别选择Router和Vuex 点击空格键确认选择 回车
④ 选择2.x(默认就是) 回车 一直回车x4 在这里选择In package.json 回车 再回车 等待下载依赖
⑤ 按照提示执行指令即可
⑥执行后结果
⑦ 复制对应地址:http://localhost:8084/ 在浏览器打开 效果如下
⑧ 用vscode打开刚刚创建的vue2项目文件夹 删除清空多余项 得到一个纯净的vue2项目
如此你就可以使用路由router和状态管理vuex了 路由这里就不详谈了 重点在于vuex
vuex 当然这里的vuex都是简陋的毛坯房
下面开始装修
① 如图创建文件和文件夹
store文件夹下各文件代码
actions.js
export const actions = {
}
getters.js
export const getters = {
}
mutations.js
export const mutations = {
}
state.js
export const state = {
}
index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//引入
import {state} from './state'
import {mutations} from './mutations'
import {actions} from './actions'
import {getters} from './getters'
//使用
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
现在相当于给客厅粉刷了一遍,什么东西还没有放。
这四个文件用来定义和管理全局状态的 比如登录信息什么的
都知道vue是由一个个组件组成的, 每个页面就是一个组件,每个组件数据肯定不一样
我们可以这样形容
你买了一个三室一厅的房子
房子对应vue2这个项目
客厅对应项目的首页
这个vue2项目有三个组件页面对应房子的三室
在客厅里放着一个包对应全局的状态管理
在包里放着打开三室的门钥匙对应着登录信息(比如token)
重点来了:我拿着钥匙进入其中一个叫home的房间 那这个房间里的数据如何用vuex来进行状态管理?
这时store/modules的作用就来了
那就建立一个home.js文件来管理的是home组件数据
store/modules/home.js
const state = {
sum:0
}
const mutations = {
changeSumJia(state){
state.sum ++
},
changeSumJian(state){
state.sum --
}
}
const actions = {
asyncChangeSumJia({commit}){
commit('changeSumJia')
},
asyncChangeSumJian({commit}){
commit('changeSumJian')
}
}
const getters = {
sum:state=>state.sum
}
export default {
state,
mutations,
actions,
getters,
namespaced:true
}
在store/index.js里引入home.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import {state} from './state'
import {mutations} from './mutations'
import {actions} from './actions'
import {getters} from './getters'
//这里引入home
import home from './modules/home'
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
//模块home 后面的模块都写在这里
modules:{
home
}
})
export default store
如此我们在home这个模块里就设置了一个叫sum的数据
现在把这个sum数据放入对应叫home的房间里(home.vue)
引用vuex里的mapGetters和mapActions
home.vue
<template>
<div>
<div class="c">
<p>home模块变量</p>
<p>store/modules/home/sum: <span>{{ sum }}</span> </p>
<button @click="jia">加 1</button>
<button @click="jian">减 1</button>
</div>
<div class="c">
<p>全局变量</p>
<p>store/state/count: <span>{{ count }}</span></p>
<button @click="add">加 2</button>
</div>
</div>
</template>
<script>
//mapState,mapGetters用拓展符写在computed里
//mapActions,mapMutations用拓展符写在methods里
import { mapState,mapGetters,mapActions,mapMutations } from 'vuex'
export default {
data(){
return{
}
},
computed:{
...mapGetters({
//这里'home/sum'是拿到store/modules/home.js里的getters里的变量sum 然后赋值给我们定义的变量sum(取名一致是为了便于理解和管理 当然你也可以写成这样:name:'home/sum' 展示数据就是{{name}})
sum:'home/sum',
//这里的'count'拿到的是store/state.js里的getters里的变量count 实际项目里大多是用户的token 然后赋值给我们定义的变量count 展示数据就是{{ count }}
count:'count'
})
},
mounted(){
},
methods:{
...mapActions({
//看过上面注释就可以轻松了解到 这里拿到store/modules/home.js/actions里定义的方法 然后赋值 在template里可直接调用该方法jia或者jian
jia:'home/asyncChangeSumJia',
jian:'home/asyncChangeSumJian'
}),
...mapMutations({
//mutations和actions里都是方法,实质上都是执行mutations里的方法,不同的是mutations里的方法是同步过程,而actions里的方法是异步过程
add:'changeCount'
})
}
}
</script>
<style scoped>
.c{
width: 80%;
padding: 20px;
margin: 0 auto;
border:1px solid red;
}
.c>p>span{
color: coral;
}
</style>
效果如图:
动态效果:
在actions方法里也可以请求接口数据,然后渲染上去。此时home.js应该这么写
const state = {
//这里定义一个空数组变量sum 用于放置下面的接口数据
sum:[],
num:16
}
const mutations = {
//这里可以放入第二个参数(形参)data 用于赋值给state里的变量
changeSumJia(state,data){
state.sum = data
},
//这里是num自身作加减 不用传入第二个形参
changeSumJian(state){
state.num --
}
}
const actions = {
asyncChangeSumJia({commit}){
//http()为数据接口
http().then(res=>{
//执行后 state里定义的sum就被res赋值了
commit('changeSumJia',res)
})
},
//{commit}是用了解构方法解构出commit这一方法 也可不解构使用形参context
//commit是调用mutations里的方法 而dispatch是可以调用actions里的方法
asyncChangeSumJian(context){
//context意为上下文 这个context有commit这一方法 去调用mutations里的方法
context.commit('changeSumJian')
}
}
const getters = {
sum:state=>state.sum
//也可全写成下面这样
//sum(state){
//return state.sum
// }
}
export default {
state,
mutations,
actions,
getters,
namespaced:true
}
拓展一下数据持久化
vue使用状态管理vuex弊端之一就是刷新页面导致数据丢失
这可以使用vuex-persistedstate这一插件来解决
1 下载vuex-persistedstate插件
npm i vuex-persistedstate
2 store/index.js
先引入插件 后配置参数
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//引入数据持久化插件vuex-persistedstate
import createPersistedState from 'vuex-persistedstate'
import {state} from './state'
import {mutations} from './mutations'
import {actions} from './actions'
import {getters} from './getters'
//这里引入home
import home from './modules/home'
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
//模块home 后面的模块都写在这里
modules:{
home
},
//配置数据持久化 这里是所有vuex里数据都持久化
plugins:[createPersistedState()]
})
export default store
所有vuex里数据持久化效果:
上面的配置导致vuex里所有的变量都持久化了,这在实际开发中是我们所不希望的。
那么通过进一步的设置 可以实现按需持久化(让指定模块里的数据保持持久化)
store/index.js
记得先引入插件 后配置
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//引入数据持久化插件vuex-persistedstate
import createPersistedState from 'vuex-persistedstate'
import {state} from './state'
import {mutations} from './mutations'
import {actions} from './actions'
import {getters} from './getters'
//这里引入home
import home from './modules/home'
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
//模块home 后面的模块都写在这里
modules:{
home
},
//配置数据持久化 所有vuex里数据持久化
//plugins:[createPersistedState()]
//按需配置数据持久化 指定vuex里(home模块)数据持久化
plugins:[createPersistedState({
//默认名称vuex
key:'homeSum',
//默认localStorage 本地储存 这里建议临时储存 也可写成window.sessionStorage
storage:sessionStorage,
//默认vuex全部变量
paths:['home']
})]
})
export default store
按需持久化效果: