Vuex

之前一直搞不懂Vuex怎么用,但学了Redux之后,发现Vuex简单好多啊。

安装

1
npm install vuex --save

前提是已经搭建好了其他vue的项目环境,开始!

使用

目录结构

效果

index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div class="index">
<h2>vuex练习</h2>
<content>
<v-a></v-a>
<v-b></v-b>
</content>
<v-detail></v-detail>
</div>
</template>

<script type="text/ecmascript-6">
import componentA from './componentA.vue';
import componentB from './componentB.vue';
import showDetail from './showDetail.vue';
export default {
components: {
'v-a': componentA,
'v-b': componentB,
'v-detail': showDetail
}
};
</script>

componentA.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div class="component">
<h5>A:加法子组件</h5>
<button @click="add">+</button>
</div>
</template>

<script type="text/ecmascript-6">
export default {
methods: {
add () {
this.$store.dispatch('add');
}
}
};
</script>

componentB.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div class="component">
<h5>B:减法子组件</h5>
<button @click="sub">-</button>
</div>
</template>

<script type="text/ecmascript-6">
export default {
methods: {
sub () {
this.$store.dispatch('sub');
}
}
};
</script>

showDetail.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<div class="showDetail">
显示数据变化:{{myNum}}
</div>
</template>

<script type="text/ecmascript-6">
export default {
computed:{
myNum () {
return this.$store.state.num;
}
}
};
</script>

index.js

1
2
3
4
5
6
7
8
9
10
11
import Vue from 'vue';
import indexComponent from './components/index.vue';
import store from './store';

const index = Vue.extend(indexComponent);

new Vue({
el: '#main',
store,
render: h => h(index)
});

store.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
state: {
num: 0
},
mutations: {
add (state) {
return state.num++;
},
sub (state) {
return state.num--;
}
},
getters: {

},
actions: {
add ({commit}) {
commit('add');
},
sub ({commit}) {
commit('sub');
}
}
});

export default store;

整体思路

好了,基本代码展示完,说一下使用思路。可以看到加法和减法是两个不同的组件,它们运算后的结果又展示在另一个组件,这些统计组件之间的通信通过vuex来实现是比较方便的。先说一个简单步骤:

新建一个store.js文件,在这个js文件中有state,mutations,actions等
在入口文件(此项目是index.js)中使用store
想要在页面中修改数据只能通过dispatch来触发对应的action,然后action的commit又会触发mutations中的方法来修改state。
Vuex只能通过mutations中来修改state,而要在页面中展示state不能通过data赋值,需要使用computed来实现。

改进

现在我们的代码看起来不够好,改一下吧。

新建一个vuex文件夹,把state,mutations,actions等独立出来

1
2
3
4
//state.js
export default {
num: 0
}
1
2
3
4
5
6
7
8
9
//mutations.js
export default {
add (state) {
return state.num++;
},
sub (state) {
return state.num--;
}
}
1
2
3
4
5
6
7
8
9
//actions.js
export default {
add ({commit}) {
commit('add');
},
sub ({commit}) {
commit('sub');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//store.js,记住改index引用store.js的路径
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

import state from './state';
import mutations from './mutations';
import actions from './actions';

const store = new Vuex.Store({
state,
mutations,
actions
});

export default store;

最后我们使用一下mapState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//showDetail.vue
<template>
<div class="showDetail">
显示数据变化:{{myNum}}
</div>
</template>

<script type="text/ecmascript-6">
import { mapState } from 'vuex';
export default {
computed: mapState({
myNum: 'num'
})
};
</script>

可以看到,使用mapState可以让我们不用每次都用return语句来返回数据,省了不少事。更深入的之后再说了。

代码