1、状态管理
集中式存储管理应用的所有组件状态的,并以相应的规则保证状态以一种可预测的方式发生改变。
2、 Vuex 的理解
vuex 的核心就是 store ,可以理解为一个容器,包含应用的大部分状态,并且该状态只能通过一定的方式进行改变
3、 使用
安装: npm i --save vuex
【利用创建项目选择的时候选择了,就可以不用安装,因为已经自动安装了】
使用:
import vuex from 'vuex'
Vue.use(vuex) // 注册
vuex 实例化: // 由 4 个部分组成,每一个都是一个对象
const store = new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {}
})
4、 state 【注意:数据源】
是整个 store 中唯一的数据源:在这里定义各种数据
// this.$store.state.count 利用这样的方式拿到数据
写法一
mapState 辅助函数
5、getters【store 当中的计算属性,全部定义的方法】
返回值会被缓存起来{类似计算缓存}
getters: {
getCount (state) { // 自带参数为数据源
return state.count // 返回数据源中的count
}
}
6、mutations 【修改数据的唯一方法】
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。。
mutation: { // 在这里定义各种修改数据的方案
increment (state, 传递的数据) { // state 代表当前数据源
state.count += 传递的数据
},
}
修改方法: 在组件中提交
this.$store.commit('increment'); // 在组件当中提交 mutations ,其中名字为 mutation中的函数名
【注意: 该方案必须是同步代码】
// 使用辅助函数
mapMutations([
'incrementSync'
])
7、actions【处理异步的,与 mutations 反之】
在 actions 中提交 mutations ;
因为 actions 注意用于处理异步操作
如:
actions: {
incrementSync(context) { // context 与 store 实例具有相同的属性和方法
context.commit('increment'); // 当有异步操作的时候 放置在 mutations 中操作,在actions 中提交
}
}
// 使用辅助函数
mapActions([
'incrementSync'
])
// 触发
this.$store.diapatch('incrementSync')
8、 modules
将 store 分割为各个模块 每个模块都有自己的 state actions …
写法: 【针对商品模板的】
const moduleA = {
state: {},
getters: {},
mutations: {},
actions: {}
}
const moduleB = {
state: {},
getters: {},
mutations: {},
actions: {}
}
最后一步
const store = new Vuex.Store({
modules: {
moduleA,
moduleB,
...
}
})
使用
之前 如:store.state.count
现在 如:store.state.moduleA.里面的变量名
在src目录下新建一个store文件夹,在store文件夹下新建一个index.js的文件在里面写我们所需要的的代码
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// state 全部存放数据(数据源)
state: {
count: 0,
inc: 1,
dec: 1,
},
// 5、getters【store 当中的计算属性,全部定义的方法】无法修改 state中的数据
getters: {
// 参数 为 state 里的所有参数,数据
getCount: (state) => '=' + state.count, // 箭头函数 返回state 中的 count 数据
},
// mutations 【修改数据
mutations: {
increment (state, n) { // 方法一 加等于自己
state.count+=n;
state.inc = n;
},
decrement (state, n) { // 方法二 减等于自己
state.count-=n;
state.dec = n;
},
},
// actions 用于处理异步操作的 【通常是在mutations 里面写,然后这里利用commit调用】
actions: {
incrementSync ({ commit }) { // 解构
setTimeout(function() {
commit('increment')
},1000)
},
decrementSync ({ commit }) { // 解构
setTimeout(function() {
commit('decrement')
},1000)
},
},
modules: {
}
})
应用端
<template>
<div id="app">
<p>当前值: {{count1}}</p>
<p>当前值: {{count2}}</p>
<p>当前值: {{count3}}</p>
<p>当前值: {{count}}</p>
<p>对数据处理的结构: {{getCount}}</p>
<!-- 子组件 -->
<Inc></Inc>
<Dec></Dec>
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld.vue'
import {mapState, mapGetters} from 'vuex' // 引入
import Inc from './components/Inc'
import Dec from './components/Dec'
export default {
name: 'app',
components: {
// HelloWorld,
Inc,
Dec,
},
computed: {
//第一种获取方式
count1() {
// this.$store.state.count 利用这样的方式拿到数据
return this.$store.state.count
},
...mapState({
// 第二种获取方式
count2: state => state.count,
// 第三种获取方式【直接传字符串等同于它】
count3: 'count',
}),
// 第四种获取方式
...mapState([
'count', // 写法4 当计算属性名 与 state 名一样的时候,可以用
]),
// getters 的内容
...mapGetters([
'getCount', // 写法可以与上面四种一样
])
}
}
</script>
<style lang="less">
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
第二
<template>
<div class="app-inv">
<button @click="increment(7)">增加count</button>
<button @click="incrementSync(2)">异步增加count</button>
</div>
</template>
<script>
import { mapMutations, mapActions } from 'vuex'
export default {
methods: {
...mapMutations([
'increment', // 映射: 相当于this.$store.commit('increment')
]),
...mapActions([
'incrementSync'
])
}
}
</script>