vuex 2.0学习心得(中) mutation&action
Vuex (vue2.0) 基础mutation&action(理解)Vuex采用和Redux类似的单向数据流的方式来管理数据。用户界面负责触发动作(Action)进而改变对应状态(State),从而反映到视图(View)上。如下图所示: 完整的Vuex用Vuex开发的应用结构应该是这样的:devtools 工具 backbend A
Vuex (vue2.0) 基础mutation&action(理解)
Vuex采用和Redux类似的单向数据流的方式来管理数据。用户界面负责触发动作(Action)进而改变对应状态(State),从而反映到视图(View)上。如下图所示:
完整的Vuex用Vuex开发的应用结构应该是这样的:
devtools 工具
backbend API 后台数据接口
actions 动作定义方法
dispatch 处理
mutations 变化 响应
state 状态
store 仓库
State
State负责存储整个应用的状态数据,一般需要在使用的时候在跟节点注入store
对象,后期就可以使用this.$store.state
直接获取状态
//store为实例化生成的
import storefrom'./store'
new Vue({
el: '#app',
store,
render: h => h(App)
})
这个store可以理解为一个容器,包含着应用中的state等。实例化生成store的过程是:
const mutations = {...};
const actions = {...};
const state = {...};
Vuex.Store({
state,
actions,
mutation
});
后续在组件中使用的过程中,如果想要获取对应的状态你就可以直接使用this.$store.state
获取,当然,也可以利用vuex
提供的mapState
辅助函数将state
映射到计算属性中去,如.
//
我是组件
import {mapState}
from'vuex'
export
default{
computed: mapState({
count:
state=>
state.count
})
}
这样直接就可以在组件中可以获取store。中的state数据,用于初始化信息等信息的存放。
Mutations
Mutations中文意思是变化响应, The only way to actually change state in a Vuex store is bycommitting a mutation,在vue中,只有mutation才能正真改变VUEX stroe中的state. mutation类似事件,每一个mutation都有一个类型和一个处理函数,因为只有mutation才能改变state.所以处理函数都会自动获取一个默认的参数名称-state。所谓的类型型其实指的就是函数的名称。
Action去comit一个mutation。它要指定去commit哪一个mutation,然后指定结束之后要做什么什么事情就要给出一个函数,所以说mutation的构成有两点名称和函数。
const store = new Vuex.Store({
state: {
count:0
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--
}
}
})
Action
action去commitmutations,所以还要定义action. store.js里面添加actions.
actions: {
increment(context) {
context.commit("INCREMENT");
},
decrement(context) {
context.commit("DECREMENT");
}
}
Action其实和mutation 是一样的,同样的结构,类型和函数。原因是我们在后面要dispatch一个action,所以action需要一个名字让我们找到,然后找到后执行的方法。
函数会自动获得一个默认参数context, 它是一个store实例,通过它可以获取到store实例的属性和方法,如context.state就会获取到 state属性, context.commit就会执行commit命令。
Context 相当与一个store对象的实例(也是对象),我们可以通过对象的解构赋值直接获取到该方法。
修改后的actions如下:
actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
}
}
+
dispatch action
在就剩下dispatch action了。什么时候dispatch action呢?只有当我们点击按钮的时候.给按钮添加click事件,在click事件处理函数的中dispatch action.
打开increment.vue组件,给两个按钮添加click事件。
<template>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template>
<script>
export default {
methods: {
increment(){
this.$store.dispatch("increment");
},
decrement() {
this.$store.dispatch("decrement")
}
}
}
</script>
其实像上面dispatchaction比较麻烦,如果有10个按钮,我们要写10个函数,且存在大量的重复,并且我们的事件处理函数名字和action的名字是一样的
这种组件中的事件处理函数名字和action的名字是相同的,直接把事件处理函数名字放到一个数组中。组件中的methods修改如下:
import {mapActions} from "vuex";
export default {
methods: {
...mapActions(["increment", "decrement"])
}
}
如果事件处理函数名字和action的名字不同,给mapActions提供一个对象,对象的属性是事件处理函数名字,属性值是对应的dispatch的action的名字。
<template>
<div>
<button @click="add">+1</button> <!-- 事件处理函数变为add -->
<button @click="decrement">-1</button>
</div>
</template>
<script>
import {mapActions} from "vuex";
export default {
methods: {
...mapActions(["decrement"]),
// mapActions 对应做出改变
...mapActions({
add: "increment"
})
}
}
通过vuex 传递参数
很多时候,组件和组件之间还要传递参数,这些都要经过vuex。 在increment组件内部增加一个输入框和一个按钮,点击按钮的时候,count增加输入框内的值。
<template>
<div>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
// 增加内容
<div>
<input type="text" v-model="incrementValue">
<button@click="incrementWithValue">increment</button>
</div>
</div>
</template>
在组件内部dipatch action 的时候,他可以自定义参数,只要参数在他dispatch 的action 后面,一次排列出来就可以了。在这里,我们点击按钮的时候,触发一个incrementWithValue action ,打一个参数就可以这样写this.$store.dispatch(“increamentValue”,value)increament.vue组件如下:
<template>
<div>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
<div>
<input type="text" v-model="incrementValue">
<button@click="incrementWithValue">increment</button>
</div>
</div>
</template>
<script>
import{mapActions} from "vuex";
export default {
data() {
return {
incrementValue: 0
}
},
methods: {
...mapActions(["increment","decrement"]),
incrementWithValue() {
//调用store中定义的方法,store,index.js的action方法作者也是定义成了incrementWithValue
this.$store.dispatch("incrementWithValue",this.incrementValue)
}
}
}
</script>
同样,actions和mutations 中的处理函数也是一样,它除了可以得到默认参数外,还可以接受自定义的参数,我们自定义的参数,依次在默认参数后面列出来就可以了。 在store.js中分加增加incrementWithValueaction和 INCREMENT_WITH_VALUE mutation
conststore = new Vuex.Store({
state: {
count:0
},
mutations: {
//加1
INCREMENT(state) {
state.count++;
},
//减1
DECREMENT(state) {
state.count--
},
INCREMENT_WITH_VALUE(state, value){
state.count +=value;
}
},
actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
},
incrementWithValue({commit}, value){
commit("INCREMENT_WITH_VALUE", parseInt(value))
}
}
})
错误处理
当我们给vuex传参的时候,我们要检测参数的正确性,如果有错误需要进行处理
action 中如果是同步操作,就用try..catch语句,组件中使用try…catch,捕获action中抛出的错误。Increment.vue组件中,incrementWithValue()方法中修改如下:
methods: {
...mapActions(["increment","decrement"]),
incrementWithValue() {
try {
this.$store.dispatch("incrementWithValue",this.incrementValue)
}catch(error) {
alert(error)
}
}
}
同时store.js中的action 也进行如下修改:
incrementWithValue({commit},value){
let intValue = parseInt(value);
if(isNaN(intValue)){
throw "Not an Interger"
}else {
commit("INCREMENT_WITH_VALUE", intValue)
}
}
如果action中进行的是异步操作,那就需要在回调函数中进行错误处理。
incrementWithValue({commit},value){
let intValue = parseInt(value)
setTimeout(function() {
if(isNaN(intValue)) {
alert("Not anInterger")
}else {
commit("INCREMENT_WITH_VALUE", intValue)
}
}, 2000)
}
异步操作给出用户提示信息
首先,在我们的increment.vue中添加一个提示信息,简单给一个div进行提示。用户提示信息的显示和隐藏,又涉及到一个状态,我们设为waiting,需要在state 中进行添加。默认为false, 同时我们组件需要从state 中获取到初始状态。increment.vue组件修改如下:
<template>
<div>
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
<div>
<input type="text" v-model="incrementValue">
<button@click="incrementWithValue">increment</button>
</div>
<!-- 展示信息 -->
<div v-if ="show">
waiting
</div>
</div>
</template>
<script>
import {mapActions} from "vuex";
export default {
data() {
return {
incrementValue: 0
}
},
// computed 从state 中获取初始状态
computed: {
show: function() {
return this.$store.state.waiting;
}
},
methods: {
...mapActions(["increment","decrement"]),
incrementWithValue() {
this.$store.dispatch("incrementWithValue",this.incrementValue)
}
}
}
</script>
mutation 去操作状态,所以增加两个muatation, 用于显示和隐藏waiting. action 中去触发这两个mutation. 整个state 如下:
conststore = new Vuex.Store({
state: {
count:0,
//新增waiting 状态
waiting: false
},
mutations: {
//加1
INCREMENT(state) {
state.count++;
},
//减1
DECREMENT(state) {
state.count--
},
INCREMENT_WITH_VALUE(state, value){
state.count +=value;
},
//显示和隐藏waiting
SHOW_WAITING_MESSAGE(state){
state.waiting = true;
},
HIDE_WAITING_MESSAGE(state){
state.waiting = false;
}
},
actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
},
incrementWithValue({commit}, value){
commit("SHOW_WAITING_MESSAGE");
let intValue = parseInt(value)
setTimeout(function() {
if(isNaN(intValue)) {
alert("Not anInterger")
}else {
commit("HIDE_WAITING_MESSAGE");
commit("INCREMENT_WITH_VALUE", intValue)
}
}, 2000)
}
}
})
更多推荐
所有评论(0)