9.Vuex的使用

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 个选项可以使用: gettersactionsmodules

     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篇目录:

    1.Vue组件之间传值问题                              2.v-model 用在组件中

    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的数据传递、传参问题

   12.Vuex命名空间namespaced                   13.Vue axios的使用      

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扛麻袋的少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值