Vuex基本用法
1.通过npm安装Vuex
npm install --save-dev vuex
2.在src目录下,新建一个名为vuex的文件夹,然后在文件夹下新建一个store.js文件,来存放Vuex状态信息
3.新建Vuex配置,并将其通过export default暴露出去
import Vue from "vue";
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state:{
count: 10
}
})
4.在mainjs中引入vuex后,即可正常使用
import Vue from 'vue'
import App from './App'
import router from './router/index'
import store from './vuex/store'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,//store即为vuex配置,此处等价于store:store
components: {App},
template: '<App/>'
})
仓库 store 包含了应用的数据(状态)和操作过程。 Vuex 里的数据都是响应式的,任何组件使 用同- store 的数据时,只要 store 的数据变化,对应的组件也会立即更新。
数据保存在 Vuex 选项的 state 字段
5.在组件中直接使用即可
<template>
<div>
{{$store.state.count}} //1.可以直接使用,如果觉得乱的话,可以使用computed计算属性
{{count}}
</div>
</template>
<script>
export default {
name: "vFooter",
data(){
return{
data:'我是Footer'
}
},
computed:{//2.此处为通过计算属性来使用
count(){
return this.$store.state.count;
}
}
}
</script>
6.然后,引入该组件,既可以查看到该信息的显示
<template>
<div id="app">
<img src="./assets/logo.png">
<v-footer></v-footer>
</div>
</template>
<script>
import vFooter from './components/vFooter'
export default {
name: 'App',
components:{vFooter},
data() {
return{}
}
}
</script>
<style scoped>
#app {
text-align: center;
}
</style>
7.store中数据已经显示出来
8.那么存在store中的数据如何改变呢?
在组件内,来自 store 的数据只能读取,不能手动改变。改变 store 中数据的唯一途径就是显式地提交 mutations
刚才使用的state是Vuex的第一个选项,此处的mutations是Vuex的第二个选项,该选项用来修改state中的数据的,比如我们现在给刚才的实例增加2个mutations,用来加1和减1。
import Vue from "vue";
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state:{
count:10
},
mutations:{//新增2个mutations
increment(state){
state.count ++;
},
decrease(state){
state.count--;
}
}
})
9.在组件内,有两种方法来执行mutations
第一种:通过this.$store.commit方法来执行mutations。在组件中定义两个按钮,分别绑定事件为+1和-1
<template>
<div>
{{$store.state.count}}<hr>
<button @click="add1()">mutations加1</button>
<button @click="reduce1()">mutations减1</button>
</div>
</template>
<script>
export default {
name: "vFooter",
data(){
return{
data:'我是Footer'
}
},
computed:{
count(){
return this.$store.state.count;
}
},
methods:{//1.定义两个方法,分别为add1和reduce1
add1(){
return this.$store.commit('increment');//2.通过this.$store.commit()来执行mutations
},
reduce1(){
return this.$store.commit('decrease');
}
}
}
</script>
<style scoped>
</style>
第二种:通过this.$store.commit方法,直接使用包含type属性的对象。如下所示
mutations:{
increment(state,params){
state.count +=params.count;
}
}
export default({
methods:{
imcrement(){
this.$store.commit({
//通过包含type属性的对象来执行mutations
type:'increment',
count:10
})
}
}
})
10.如图所示,即可看到store中的count已经被修改了
mutations 还可以接受第二个参数,可以是数字、字符x串或对象等类型(当一个参数不够时,也可以传递一个对象,无限扩展,不要局限于只能传递一个参数的思维)。比如每次增加的不是 1, 而是指定的数量,可以这样改写:
//部分代码省略
mutations:{
increment(state,n=1){
state.count +=n;
}
}
//在ES6中可以为函数的参数设置默认值,如上所示n=1。当没有传入参数时,使用默认值
//在组件中使用this.$store.commit()来执行mutations,如下
export default({
methods:{
imcrement(){
this.$store.commit('increment',5);
}
}
})
//当一个参数不够用时,可以传入一个对象,无限扩展
注意:mutation 里尽量不要异步操作数据。如果异步操作数据了,组件在 commit 后,数据不能立即改变,而且不知道什么时候会改变
Vuex高级用法
Vuex 还有其他 3 个选项可以使用: getters、 actions、 modules。
1.getters
有这样的一个场景: Vuex 定义了某个数据 list, 它是一个数组,如果只想得到小于 10 的数据,最容易想到的方法可能是在组件的计算属性里进行过滤。这样写完全没有问题。但如果还有其他的组件也需要过滤后的数据时,就得把 computed 的代 码完全复制一份,而且需要修改过滤方法时,每个用到的组件都得修改,这明显不是我们期望的结 果。如果能将 computed的方法也提取出来就方便多了, getters 就是来做这件事的。
//store.js
import Vue from "vue";
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state:{
count:10,
list:[1,5,8,10,30,50] //list数据
},
mutations:{
increment(state,params){
state.count += params.count;
},
decrease(state){
state.count--;
}
},
getters:{ //getters方法
filterList:(state)=>{
return state.list.filter(item=>item%2==0)
}
}
})
//vFooter.vue
<template>
<div>
{{$store.state.count}}<hr>
<button @click="add1()">mutations加1</button>
<button @click="reduce1()">mutations减1</button><hr>
<span>通过计算属性computed:</span>{{filterList}} <hr>
<span>通过Vuex中getters方法:</span>{{getterList}}
</div>
</template>
<script>
export default {
name: "vFooter",
computed:{
count(){
return this.$store.state.count;
},
filterList(){//计算属性获取
return this.$store.state.list.filter((item)=>{return item%2==0})
},
getterList(){//通过vuex属性getters获取
return this.$store.getters.filterList
}
},
methods:{
add1(){
return this.$store.commit({
type:'increment',
count:88
})
},
reduce1(){
return this.$store.commit('decrease');
}
}
}
</script>
这种用法与组件的计算属性非常像。getter也可以依赖其他的 getterr,把 getter 作为第二个参数。 比如再写一个 getter,计算出 list 过滤后的结果的数量(listCount):
//其他代码省略
getters:{
filterList:(state)=>{
return state.list.filter(item=>item%2==0)
},
listCount:(state,getters)=>{//将getters作为参数,传递到名称为listCount的getter中
return getters.filterList.length;
}
}
然后,在组件中,和之前使用filterList的用法一样。
<span>通过计算属性computed:</span>{{filterList}} <hr>
<span>通过Vuex中getters方法:</span>{{getterList}}<hr>
<span>listCount后list长度:</span>{{$store.getters.listCount}}
//部分代码省略
export default({
computed:{
count(){
return this.$store.state.count;
},
filterList(){
return this.$store.state.list.filter((item)=>{return item%2==0})
},
getterList(){
return this.$store.getters.filterList
}
}
})
执行结果如下图所示:
2.actions
mutations 里不应该异步操作数据,所以有了 actions 选项。
actions与 mutations 很像, 不同的是 ①actions 里面提交的是 mutation ②actions里面可以异步操作业务逻辑
①actions 里面提交的是 mutation
actions在组件内,通过$store.dispatch来触发,例如:使用actions来对之前实例中的count增加1
//store.js
//部分代码省略
export default new Vuex.Store({
mutations:{
//加1
increment(state,params){
state.count += params.count;
},
//减1
decrease(state){
state.count--;
}
},
actions:{
incrementByAction(context){//使用actions,来执行mutations中的increment,来使count加1
context.commit('increment',{count:1})//因为本例 mutations中increment(state,params)有参数,所以此处也是两个参数
// context.commit('increment')
}
}
})
//vFooter.vue
<template>
<div>
<button @click="addByActions()">actions加1</button>
</div>
</template>
<script>
export default {
//部分代码省略
methods:{
addByActions(){
//此处使用this.$store.dispatch来触发actions
return this.$store.dispatch('incrementByAction');
}
}
}
</script>
执行结果如下图所示:
②actions里面可以异步操作业务逻辑
参见:https://blog.csdn.net/lzb348110175/article/details/89297973(未总结226)
3.modules
选项modules,用来将store分割到不同的模块。当你的项目足够大时,store里的state、getter、mutations、actions会非常多,都放在store.js里显然是不友好的,使用modules可以把它们写在不同的文件中。每个module都拥有自己的state、getters、mutations、actions,而且还可以多层嵌套。如下实例:
const moduleA = {
state: {...},
mutations: {...},
actions: {...},
getters: {...}
}
const moduleB = {
state: {...},
mutations: {...},
actions: {...},
getters: {...}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a //moduleA的状态
store.state.b //moduleB的状态
实例:
附:Vue篇目录:
3.Vue.js 实战 调查问卷WebApp项目 4.vue-cli + webpack搭建Vue开发环境
5. Vue简单问题汇总(持续更新...) 6.Vue组件之间数据通信之Bus总线
7.Vue-Router导航钩子(附Demo实例) 8.ES6箭头函数与普通函数的区别
9.Vuex的使用 10.Vuex组件中的mapState、mapGetters、mapMutations、mapActions等辅助函数
11.组件中调用Vuex的state,getters,mutations,actions,modules的数据传递、传参问题