VueJS中学习使用Vuex详解
自己也学习了一下,写了一个小demo,
根据我自己的理解,其实状态管理中 state 就相当于 vue中 data属性,getters就相当于vue中的computed属性,mutations, actions就相当于vue中的方法,只是操作方式变了而已。
首先我们构建一个vue基本项目,引入vuex
npm install vuex
我们先来看一下demo的效果先
首先我们在src目录下新建一个 store 目录,在store 目录下在新建一个modules目录,表示模块的意思,根据上图,我们有两种状态,显示跟隐藏
我们在modules目录下新建一个 footerStatus.js 名字随便起的,
const state = {
showFooter: true,
changeNum: 0
}
// 是不是很像那个data中的数据
// 只不过这里我们把他提取出来赋值给一个 state 变量
在data属性中,我们可以在 methods 中定义各种函数,就像下面这样来操作data中数据
methods: {
getValue(){
return this.showFooter;
}
},
computed: {
showFooter(value) {
this.showFooter = value;
}
}
于是,我们要是想获取state里面的数据怎么办呢?这个时候,人们就想到了在getters里面定义一系列操作state的方法
const getters = {
isShow(state) {
return state.showFooter
},
getChangeNum() {
return state.changeNum
}
}
那你可能又会想,那我如果想更新getters里面的数据,怎么办呢?于是人们又想出了向state提交数据的方法 mutations,处理一系列同步任务的方法
const mutations = {
show(state) {
state.showFooter = true
},
hide(state) {
state.showFooter = false
},
newNum(state, sum) {
state.changeNum += sum
}
}
那你可能又会想我想处理一个异步任务呢,没错,vuex替你想到了这些,vuex提供了一个actions来做这些异步任务
const actions = {
hideFooter(context) {
context.commit('hide')
},
showFooter(context) {
context.commit('show')
},
getNem(context, num) {
context.commit('newNum', num)
}
}
最后我们需要到处模块
export default {
namespaced: true, // 进行多模块处理
state,
getters,
mutations,
actions
}
同理新建一个collection.js,理解步骤同上
// 数据状态
const state = {
collects: [], // 初始化一个collects数组
}
// 类似于computed属性
// get 获取状态
const getters = {
renderCollects(state) {
return state.collects
}
}
// 同步更新 状态
const mutations = {
pushCollects(state, items) {
state.collects.push(items)
}
}
// 异步更新 状态
const actions = {
invokePushItems(context, item) {
context.commit("pushCollects", item)
}
}
// 到处模块
export default {
namespaced: true,
state,
getters,
mutations,
actions
最后我们统一在 index.js 里面到处使用
import Vue from "vue"
import Vuex from "vuex"
import footerStatus from './modules/footerStatus'
import collection from './modules/collection'
Vue.use(Vuex)
export default new Vuex.Store({
modules: { // 这里声明两个模块,后面使用就知道为啥要这样搞了
collection,
footerStatus
}
})
接下来我们先在 main.js 导入 store/index.js
接下来我们编写组件来应用上面的状态
首先在我们的views目录新建一个StatusTest.vue,比较简单,无需多言
<template>
<div class="state-test-wrap">
我的state状态管理的学习demo
</div>
</template
接下来再新建一个文件 Test.vue
<template>
<div class="test-wrap">
<v-state-test v-if="isShow"></v-state-test>
<ul v-if="allList.length">
<li :key="index" v-for="(item, index) in allList">
编号:{{item.id}} ----
姓名:{{item.name}} ----
性别:{{item.sex}}
</li>
</ul>
<p>
<button class="hide" @click="hide">隐藏</button>
<button class="show" @click="show">展示</button>
<button class="addList" @click="invokePushItems(items)">异步提交数据</button>
<button class="addList2" @click="pushCollects(items)">同步提交数据</button>
</p>
</div>
</template>
<script>
import StateTest from "@views/StateTest.vue"
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
export default {
name: "test",
data() {
return {
items:
{
id: 0,
name: "ljw",
sex: "man"
}
}
},
components: {
"v-state-test": StateTest,
},
computed: {
...mapState({ // 这里的footerStatus是指模块的名字 name
isShow: state => state.footerStatus.showFooter, // 获取isShow
allList: state => state.collection.collects, // 获取 collects
}),
// 你也可以使用下面的方式来获取 isShow 的值
// footerStatus指的是modules文件夹下的footerStatus.js模块
// 第一个isShow是我自定义的只要对应template里v-if="isShow"就行,
// 第二个isShow是对应的footerStatus.js里的getters里的isShow
...mapGetters('footerStatus', {
isShow: 'isShow',
}),
...mapGetters('collection', {
allList: 'renderCollects'
})
},
methods: {
hide() {
this.$store.dispatch("footerStatus/hideFooter")
},
show() {
this.$store.dispatch("footerStatus/showFooter")
},
// 异步提交数据
...mapActions('collection',[
"invokePushItems"
]),
// 同步提交数据
...mapMutations('collection', [
"pushCollects"
]),
}
}
</script>
完结沙画