Vuex中的核心方法
Vuex
是一个专为Vue.js
应用程序开发的状态管理模式,其采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。每一个Vuex
应用的核心就是store
仓库,store
基本上就是一个容器,它包含着你的应用中大部分的状态state
。什么情况下可以使用Vuex?
如果不打算开发大型单页应用,应用够简单,最好不要使用 Vuex。一个简单的 store 模式就足够了。但是,如果需要构建一个中大型单页应用,就要考虑如何更好地在组件外部管理状态,Vuex 是不错的选择。
关于Vuex
的五个核心概念,在这里可以简单地进行总结:
state
: 基本数据,包含了store
中存储的各个状态。getters
: 从基本数据派生的数据,类似于 Vue 中的计算属性,根据其他 getter 或 state 计算返回值mutations
: 提交更改数据的方法,同步操作;一组方法,是改变store
中状态的执行者,只能是同步操作actions
: 像一个装饰器,包裹mutations
,使之可以异步。modules
: 模块化Vuex
。
import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, getter: { doneTodos: (state, getters) => { return state.todos.filter(todo => todo.done) } }, mutations: { increment (state, payload) { state.count++ } }, actions: { addCount(context) { // 可以包含异步操作 // context 是一个与 store 实例具有相同方法和属性的 context 对象 } } }) // 注入到根实例 new Vue({ el: '#app', // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件 store, template: '<App/>', components: { App } })
改变状态
this.$store.commit('increment')
State
单一状态树
在Vue组件中获得Vuex状态
Vuex 使用 state
来存储应用中需要共享的状态。为了能让 Vue 组件在 state
更改后也随着更改,需要基于state
创建计算属性。
// 创建一个 Counter 组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count // count 为某个状态
}
}
}
Action与Mutation的区别
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作,而Mutation只能且必须是同步操作
mapState辅助函数
mapState
函数返回的是一个对象,当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余,为了解决这个问题,我们可以使用mapState
辅助函数帮助我们生成计算属性。
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from "vuex";
export default {
// ...
computed: mapState({
// 箭头函数
count: state => state.count,
// 传字符串参数 count 等同于 state => state.count
countAlias: 'count',
// 使用 this
countPlusLocalState: function(state) {
return state.count + this.localCount;
}
})
// ...
}
如果当前组件中还有局部计算属性需要定义,通常可以使用对象展开运算符...
将此对象混入到外部对象中。
import { mapState } from "vuex"; export default { // ... computed: { localComputed: function() { /* ... */ }, // 使用对象展开运算符将此对象混入到外部对象中 ...mapState({ // ... }) // ... }
案例
1 <template> 2 <div class="hello"> 3 <h2>加减法计算器</h2> 4 <div> 5 <el-input-number v-model="num" @change="handleChange" :min="1"></el-input-number> 6 </div> 7 </div> 8 </template> 9 10 <script> 11 export default { 12 name: 'HelloWorld', 13 data () { 14 return { 15 num:this.$store.state.num 16 } 17 } 18 } 19 </script> 20 21 22 JS文件 23 import Vue from 'vue' 24 import App from './App' 25 import router from './router' 26 import store from './store' 27 import ElementUI from 'element-ui' 28 import 'element-ui/lib/theme-chalk/index.css' 29 30 Vue.use(ElementUI) 31 Vue.config.productionTip = false 32 33 new Vue({ 34 el: '#app', 35 router, 36 store, 37 components: { App }, 38 template: '<App/>' 39 }) 40 41 store文件夹中的index.js 42 import Vue from 'vue' 43 import Vuex from 'vuex' 44 45 Vue.use(Vuex) 46 47 let store = new Vuex.Store({ 48 state: { 49 num: 100 50 } 51 }) 52 53 export default store