vuex是什么
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
vuex解决了什么问题
- 如何确保在不同组件中的数据保持同步
- 如何确保每次对于数据的修改都是可追踪的
- 举个例子
一个户外商店有两名员工,张三和李四,在一天的早上,他们分别对帐篷的数量做了一次盘点,发现一共有三个帐篷可供出售,俩个人在商店里度过了一天,张三卖出去俩个,他以为库存里还有一个,李四卖出去一个,他以为库存里还有俩个,而事实上是,库存现在已经为零了,如果他们再接受客户的预订,就会出现库存不足的情况,OK,听完这个故事,我们可以得知,张三和李四因为没有保持库存的数量的同步导致了尴尬,这个就是所谓的数据保持同步,店长也需要随时知道当天是谁卖出了多少个帐篷,这个行为我们称之为数据修改是可追踪的
vuex中存什么
- 一般情况下,只有多个组件均需要共享的数据,才有必要存储在vuex中,对于某个组件中的私有数据,依旧存储在组件自身的data中
例如:
- 对于所有组件而言,当前登陆的用户名是需要在全体组件之间共享的,则它可以放在vuex中
- 对于文章详情页组件来说,当前的用户浏览的文章数据则应该属于这个组件的私有数据,应该要放在这个组件的data中
vuex核心概念
1. state声明变量
state提供唯一的公共数据源,所有共享的数据都要统一放到store中的state属性中存储
为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js文件。当然, 这个步骤并不是必需的。
定义state
store/index.js
// 引入vuex
// 定义store
import Vue from 'vue'
import Vuex from 'vuex'
// 1. 以插件的格式把vuex挂载到Vue上
Vue.use(Vuex)
// 2. 创建Vuex.Store的实例
const store = new Vuex.Store({
// 各种配置(类似于data,methods,computed....)
// state就对应理解为组件中data
state: {
num: 100
}
})
// 3. 导出store实例
export default store
挂载到vue实例
在main.js中来引入上面定义好的vuex
main.js
import Vue from 'vue'
import App from './App.vue'
// 在入口文件中引入store
import store from './store/index.js'
Vue.config.productionTip = false
// 挂载到vue的实例上
new Vue({
store: store,
render: h => h(App),
}).$mount('#app')
组件中使用state
方法1:$store对象使用
我们在
components
目录下定义一个StoreComponent
组件,在StoreComponent
组件中演示一下通过$store使用state中数据的方法
模板中:{
{ $store.state.num }}
其它配置项中:this.$store.state.num
components/AddItem.vue
<template>
<div>
通过$store拿到state中的数据:{
{$store.state.num}}
</div>
</template>
<script>
export default {
mounted () {
// 其它配置项中通过this.$store获取
console.log(this.$store.state.num)
}
}
</script>
方法2:mapState映射使用
使用步骤
- 组件中按需导入mapState函数:
import { mapState } from 'vuex'
- 将state中数据映射为计算属性:
computed:{ ...mapState(['state中的属性名']) }
- 把映射到组件内的数据当成一般计算属性使用
components/SubItem.vue
// es6 按需导入
import {
mapState } from 'vuex'
// console.log('mapState', mapState)
// mapState就是vuex中的一个函数
// mapState(['num']): 调用这个函数,传入实参['num']
// const rs = mapState(['num'])
// // rs就是一个对象,结构是:
// // {
// // num: function (){}
// // }
// console.log('rs',rs)
export default {
name: 'SubItem',
// 把mapState([])的结果,就是一个对象
// 把这个对象展开,合并到computed这个对象中
computed: {
...mapState(['num'])
}
}
解惑:
1.
- mapState是vuex中的一个函数
- mapState([‘num’])调用之后得到的是一个对象,通过解构语法可以解构出来一个个单独的计算属性
- 当组件中需要同时使用多个state中的数据的时候使用mapState比较合适
- vuex是我们安装的包,它是一个对象,有很多的方法,第一句是引入Vuex中的mapState方法。相当于
import Vuex from 'vuex'; const mapState = Vuex.mapState;
- mapState([“count”]) 得到的是一个对象,其中有一个方法名是count,这个对象类似于
{count:function(){}}
...obj
是es6新增的扩展运算符,这里用来把mapState([“count”]) 得到的对象合并到computed这个对象中
整个过程的示意图如下:
state特性总结
- state中定义的数据都是响应式的,只要数据发生变化,任何一个使用到当前数据的组件都会得到更新
- state中的数据虽然可以直接修改也能成功,但是强烈不建议这么做,下面我们说如何修改state中的数据
2.mutations同步修改
如果我们想修改state中的某个数据,我们可以通过提交mutations的方式进行修改
定义mutation
new Vuex.Store({
state:{
},
mutations:{
// 函数名可以是任意合法的函数名
// 参数1:表示当前state
// 参数2:可选。它表示调用函数1时,传入的参数。
函数名1(参数1,参数2){
// 在函数内部,修改state中的数据
}
}
})
说明:
- mutations是固定写法(只有一个)
- mutations定义完成之后,就等待被调用。它的作用是用来修改vuex中的数据
store/index.js定义
// 引入vuex
// 定义store
import Vue from 'vue'
import Vuex from 'vuex'
// 1. 以插件的格式把vuex挂载到Vue上
Vue.use(Vuex)
// 2. 创建Vuex.Store的实例
const store = new Vuex.Store({
// 各种配置(类似于d