1.什么是vuex
一个专为 Vue.js 应用程序开发的状态管理模式
1.1什么是状态管理模式
状态自管理应用包含
- state:驱动应用数据源
- view:以声明的方式将state映射到视图
- actions:响应view因用户的操作发生的状态变化
1.2 vuex过程
2.核心概念
2.1 State
定义在全局共享的数据
state: {
// 所有的任务列表
list: [],
inputVal: 'aaa',
Tmpid: 5,
viewKey: 'all'
}
2.2 Mutations
不能在此函数中执行异步操作
用于变更store中的数据,只能通过mutation变更store数据,不能直接操作store的数据 可以集中监控所有数据的变化
mutations: {
initList(state, list) {
// state是固定参数 给state仓库里的List赋值
state.list = list
}
}
2.3 Actions
在action中 不能直接修改state中的数据 必须通过context.commit()触发某个mutation函数才可以
actions: {
getList(context) {
axios.get('./list.json').then(({ data }) => {
// console.log(data);
// 调用mutation里的方法,传给他一个参数 是获取到的列表
context.commit('initList', data)
})
}
},
2.4 Getter
不会改变state里的数据,只是包装的作用
getters: {
unDoneNum(state) {
return state.list.filter(x => x.done === false).length
}
}
要有返回值 按需导入
import { mapGetters } from 'vuex'
在computed中 将getter中的函数名添加到如下数组中
computed: {
...mapGetters(['unDoneNum'])
},
2.5 Modules
解决在一个单一树中,所有的状态集中,会产生一个很大的对象。
将 store 分割成模块(module)
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
3.应用
简单的计算案例 包含源码
3.1 main.js
import Vue from 'vue'
import App from './App.vue'
// 导入store中暴露的Store
import store from './store'
Vue.config.productionTip = false
new Vue({
// 将store挂载到实例上,这样vue中的每一个组件都能访问store里的数据
store,
render: h => h(App)
}).$mount('#app')
3.2 app.vue
<template>
<div>
<my-addition></my-addition>
<p>-------------</p>
<my-subtraction></my-subtraction>
</div>
</template>
<script>
import Addition from './components/Addition.vue'
import Subtraction from './components/Subtraction.vue'
export default {
data() {
return {
}
},
components: {
'my-addition': Addition,
'my-subtraction': Subtraction
}
}
</script>
<style>
</style>
3.3 store index.js
// 初始化vuex
import Vue from 'vue'
import Vuex from 'vuex'
// 注册到项目中
Vue.use(Vuex)
// 通过new创建一个Vuex.Store实例 并暴露出去
export default new Vuex.Store({
state: {
// 定义在全局共享的数据
count: 2
},
mutations: {
// 不能在此函数中执行异步操作
// 用于变更store中的数据,只能通过mutation变更store数据,不能直接操作store的数据 可以集中监控所有数据的变化
add(state) {
// state表示全局中的数据对象,是固定写法
/* setTimeout(() => {
state.count++
}, 2000); */
state.count++
},
add1(state, step) {
// step表示参数 一次加多少
state.count += step
},
// 减法
sub(state) {
state.count--
},
sub1(state, step) {
state.count -= step
}
},
actions: {
addAsync(context) {
setTimeout(() => {
// 在action中 不能直接修改state中的数据 必须通过context.commit()触发某个mutation函数才可以
context.commit('add')
}, 2000);
},
// 异步带参数加法
addNAsync(context, step) {
setTimeout(() => {
context.commit('add1', step)
}, 2000);
},
subAsync(context) {
setTimeout(() => {
context.commit('sub')
}, 2000);
},
// 异步带参数加法
subNAsync(context, step) {
setTimeout(() => {
context.commit('sub1', step)
}, 2000);
}
},
modules: {
},
getters: {
// 不会改变state里的数据,只是包装的作用
show(state) {
return '当前最新的数量是【' + state.count + '】'
}
}
})
3.4 add组件
<template>
<!-- 在template中 this可以省略 -->
<div>
<!-- 组件访问数据第一种方法:$store.state.count -->
<!-- 使用getter的方法一 -->
<h2>{{$store.getters.show}}</h2>
<h3>当前最新的count值为:{{$store.state.count}}</h3>
<button @click="addbtn">+1</button>
<button @click="addbtn1">+n</button>
<button @click="addbtn2">+1 async</button>
<button @click="addbtn3">+n async</button>
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
addbtn() {
// this.$store.state.count++
// commit的作用就是调用mutation中的某个函数
this.$store.commit('add')
},
addbtn1() {
// commit 触发mutation 第一种方法 第二种在减法里
this.$store.commit('add1', 2)
},
// 异步
addbtn2() {
// 专门触发action
this.$store.dispatch('addAsync')
},
// 异步带参数加法
addbtn3() {
this.$store.dispatch('addNAsync', 5)
}
}
}
</script>
3.5 sub
<template>
<div>
<!-- 组件访问数据第二种方法: -->
<!-- 第三部,直接使用 -->
<h2>{{$store.getters.show}}</h2>
<h3>当前最新的count值为:{{count}}</h3>
<button @click="subbtn">-1</button>
<button @click="subbtn1">-n</button>
<button @click="subbtn2">-1 async</button>
<button @click="subNAsync(5)">-n async</button>
</div>
</template>
<script>
// 第一步:先导入 从vuex中按需导入mapState函数
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
data() {
return {}
},
// 第二步,通过导入mapState函数,将当前所需的全局数据,映射为组件的computed计算属性。即在计算属性里将使用的数据放入数组中
computed: {
...mapState(['count']),
...mapGetters(['show'])
},
methods: {
...mapMutations(['sub', 'sub1']),
...mapActions(['subAsync', 'subNAsync']),
subbtn() {
// 调用
this.sub()
},
subbtn1() {
this.sub1(3)
},
subbtn2() {
this.subAsync()
}
}
}
</script>