1.vuex的存储是响应式的,当store的状态发生改变时,那么组件中的状态也会跟着相应改变。
2.store的状态是不可以直接改变的,改变store的唯一办法是通过commit mutation。
3.为了使所有的子组件不用频繁注入store,vue提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex))
State
/main.js
import store from './store/'
vue.use(vuex)
new Vue({
router,
store,
}).$mount('#app')
通过在根组件中注入store,我们可以在子组件中this.$store 访问store中的状态(state)
/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
const state = {
count1: 1,
count2: 2
}
export default new Vuex.Store({
state
})
/子组件
html:
<p>{{count1}}</p>
<p>{{count2}}</p>
js:
export default {
computed: {
count1 () {
return this.$store.state.count1
},
count2 () {
return this.$store.state.count2
},
}
}
mapState 辅助函数
在子组件获取store的方法有很多,最常见的方法是就是上面介绍的
但是一旦想要获取多个状态值就需要声明很多个计算属性,这样就会让代码显得很冗余(上面获取两个状态,就需要写两个函数)
可以使用 mapState 辅助函数帮助我们生成计算属性,使代码看起来很简洁
方式一:
html:
<p>{{count1}}</p>
<p>{{count2}}</p>
js:
export default {
computed: {
...mapState(['count1','count2'])
}
}
方式二:
html:
<p>{{countAlias1}}</p>
<p>{{countAlias2}}</p>
js:
export default {
computed: mapState({
countAlias1: 'count1',
countAlias2: 'count2',
})
}
方式三:
html:
<p>{{count1}}</p>
<p>{{count2}}</p>
js:
export default {
computed: mapState({
count1: state => state.count1
count2: state => state.count2
//完整是这样子的,以上是简写:count1 = function (state) { return state.count1 }
})
}
mutations
想要更改state的状态值,只能通过commit mutations的方法来更改。
比如我想点击验证按钮的时候,下面的p标签的插值表达式{{datatext}}状态值会变化。
/html
<button @click="change">验证</button>
<p>{{datatext}}</p>
/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations';
const state = {
datatext: '我还没有改变'
}
export default new Vuex.Store({
state,
mutations
})
使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。
/mutation-types.js
export const DATATEXT_MUTATION = 'DATATEXT_MUTATION'
/mutations.js
import { DATATEXT_MUTATION } from './mutation-types';
export default {
// 定义mutations函数,第一个参数state(状态值)、第二个参数是载荷
[DATATEXT_MUTATION](state,res) {
// 改变state中的datatext状态值
state.datatext = res
}
}
/html
<button @click="change">验证</button>
<p>{{datatext}}</p>
组件下的js
export default {
methods: {
// 将this.$store.commit("DATATEXT_MUTATION")映射为this.DATATEXT_MUTATION()
// 通俗点讲就是用this.datatext_mutation()代替this.$store.dispatch("datatext_mutation")
...mapMutations(['DATATEXT_MUTATION']),
change() {
this.DATATEXT_MUTATION('我改变了状态值')
}
}
}
mapMutations辅助函数
在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。
acitons
actions类似于mutations,但是actions可以用异步,但是mutations只能用于同步。
用一个倒计时的例子来加深actions的使用,还是刚刚那个mutations的例子
/html
<button @click="change">验证</button>
<p>{{datatext}}</p>
/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations';
import actions from './action';
const = {
datatext: '我还没有改变'
}
export default new Vuex.Store({
state,
mutations,
actions
})
/mutation-types.js
export const DATATEXT_MUTATION = 'DATATEXT_MUTATION'
/mutations.js
import { DATATEXT_MUTATION } from './mutation-types';
export default {
// 定义mutations函数,第一个参数state(状态值)、第二个参数是载荷
[DATATEXT_MUTATION](state,res) {
// 改变state中的datatext状态值
state.datatext = res
}
}
在service里面定义一个倒计时方法
/service
export const doubleAfter2seconds = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('2s后我被改变了')
}, 2000);
} )
}
/actions.js
import {DATATEXT_MUTATION} from './mutation-types'
import {doubleAfter2seconds} from './service'
export default {
async datatext_mutation({
commit
}) {
let res = await doubleAfter2seconds()
commit(DATATEXT_MUTATION,res)
}
}
在组件里使用action
export default {
methods: {
// ...mapActions(['datatext_mutation']),
change() {
this.$store.dispatch("datatext_mutation");
}
}
}
mapActions
可以使用辅助函数mapActions将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store):
methods: {
...mapActions(['datatext_mutation']),
change() {
this.datatext_mutation()
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。