Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(可以理解vue组件中公用的数据)
在 Vue 之后引入 vuex
npm install vuex --save
Vuex五个核心概念
1. state:vuex的基本数据,可以看做是所有组件的公共数据。
2. getters:从基本数据(state)派生的数据,相当于state的计算属性。
3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
4. action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
核心概念1: State
所有组件的公共数据,初始化数据。数据不能在state直接修改。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
num: 0,
name: 'ming',
showLogin: false
},
})
在其他界面的调用:
方法一:直接通过$store
<template>
<div>
<h1>数量:{{ count }}</h1>
<h1>数量:{{ $store.state.num }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
count: this.$store.state.num,
};
},
};
</script>
方法二:通过computed添加一个计算属性来使用
<template>
<div>
<h1>点击数量:{{ count }}</h1>
</div>
</template>
<script>
export default {
computed:{
count(){
return this.$store.state.num
},
},
};
</script>
方法三:通过computed+mapState返回函数的方法来使用
<template>
<div>
<h1>点击数量:{{ count }}</h1>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
computed: mapState({
count:state=>state.num
}),
};
</script>
方法四:通过computed+mapState的数组来使用
<template>
<div>
<h1>点击数量:{{ num }}</h1>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
computed:{
//名称要与state中的数据属性名称相同
...mapState(['num'])
},
};
</script>
核心概念2: getters
store对象中getters就类似于计算属性,若想获取state的变量,直接获取即可,但很多时候获取的state变量需要经过一系列的加工或计算才是我们想要的,因此才有了getters,下面演示个最基本的getters使用:
export default new Vuex.Store({
state: {
num: 0,
},
getters: {
getNum(state){
return state.num + 10
},
},
})
方法一:this.$stroe.getters直接取值
<template>
<div>
<h1>点击数量:{{ count }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
count: this.$store.getters.getNum,
};
},
};
</script>
方法二:使用mapGetters取值
<template>
<div>
<h1>点击数量:{{ getNum1 }}</h1>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
computed:{
...mapGetters({
// 把 `this.getNum1` 映射为 `this.$store.getters.getNum`
getNum1: "getNum"
}),
},
};
</script>
核心概念3: mutations
将mutaions
理解为store
中的methods
, mutations
对象中保存着更改数据的回调函数,该函数名官方规定叫type
, 第一个参数是state
, 第二参数是payload
, 也就是自定义的参数.(我认为主要是修改States 数据)
export default new Vuex.Store({
state: {
num: 0,
},
mutations: {
//不传值
addNum1(state){
state.num+=1
},
//传值
addNum2(state,value){
state.num = value + state.num
},
},
})
方法一:使用 this.$store.commit('xxx') 提交 mutations
<template>
<div>
<h1>点击数量:{{ $store.state.num }}</h1>
<button @click="addEvent">添加点击数</button>
<button @click="addEvent1">添加点击数</button>
</div>
</template>
<script>
export default {
methods: {
addEvent: function () {
this.$store.commit('addNum1');
},
addEvent1: function () {
this.$store.commit('addNum2',10);
},
},
};
</script>
方法二:使用 mapMutations
<template>
<div>
<h1>点击数量:{{ $store.state.num }}</h1>
<button @click="addNum1">添加点击数</button>
<button @click="addNum2(1)">添加点击数</button>
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
methods: {
...mapMutations({
addNum1: "addNum1", // 将 `this.addNum1()` 映射为 `this.$store.commit('addNum1')`
addNum2: "addNum2",
}),
},
};
</script>
核心概念4: actions
actions
类似于 mutations
,不同在于:
-
actions
提交的是mutations
而不是直接变更状态 -
actions
中可以包含异步操作,mutations
中绝对不允许出现异步 -
actions
中的回调函数的第一个参数是context
, 是一个与store
实例具有相同属性和方法的对象
export default new Vuex.Store({
state: {
name: '',
},
mutations: {
setName(state,data){
state.name = data
},
},
actions: {
//方法一
setName(context, data) {
setTimeout(() => {
context.commit('setName', data)
}, 1000)
},
//方法二
setName({ commit }, data) {
setTimeout(() => {
commit('setName', data)
}, 1000)
},
//方法三
setName({ commit,state }, data) {
setTimeout(() => {
commit('setName', data)
}, 1000)
},
},
})
方法一:使用 this.$store.dispatch('xxx') 获取 action
<template>
<div>
<h1>名字:{{ this.$store.state.name }}</h1>
<button @click="addEvent">添加点击数</button>
</div>
</template>
<script>
export default {
methods: {
addEvent: function () {
this.$store.dispatch('setName','修改')
},
},
};
</script>
方法二:使用 mapActions
<template>
<div>
<h1>名字:{{ this.$store.state.name }}</h1>
<button @click="addEvent">添加点击数</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods: {
// 将 `this.add()` 映射为 `this.$store.dispatch('setName')`
...mapActions({
add: 'setName'
}),
addEvent: function () {
this.add('修改')
},
},
};
</script>
核心概念5: modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
组件中访问模块里的state
this.$store.state.'模块名'.'属性名'
import { mapState } from 'vuex'
computed: {
// ...
...mapState({
list: state => state.['模块名'].['属性名']
})
}
在组件中访问模块里的getter
this.$store.getters['属性名']
import { mapGetters } from 'vuex'
computed: {
// ...
...mapGetters({
list: '['模块名']/['属性名']'
})
// 或者
...mapGetters('模块名',['属性名'])
...mapGetters('city',['findOne'])
}
组件中commit模块里的mutations
this.$store.commit('属性名', opts)
import { mapMutations } from 'vuex'
computed: {
// ...
...mapMutations({
list: '['模块名']/['属性名']'
})
// 或者
...mapGetters('模块名',['属性名'])
...mapGetters('city',['findOne'])
}
组件中dispatch模块里的actions
this.$store.dispatch('属性名', opts)
import { mapActions } from 'vuex'
computed: {
// ...
...mapActions({
list: '['模块名']/['属性名']'
})
// 或者
...mapGetters('模块名',['属性名'])
...mapGetters('city',['findOne'])
}