Vuex-集中式状态(数据)管理

什么时候使用Vuex?

1. 多个组件依赖于同一状态

2. 来自不同组件的行为需要变更同一状态

一、理解Vuex

多组件共享数据实现的两种不同方式:

  1. 全局事件总线

  1. vuex

二、案例分析

  1. vue实现

新建Count.vue子组件,在其中编写模板,包括按钮点击事件等,配置data()数据以及加减等方法的methods

<script>
    export default {
        name:'Count',
        data() {
            return {
                n:1, //用户选择的数字
                sum:0 //当前的和
            }
        },
        methods: {
            increment(){
                this.sum += this.n
            },
            decrement(){
                this.sum -= this.n
            },
            incrementOdd(){
                if(this.sum % 2){
                    this.sum += this.n
                }
            },
            incrementWait(){
                setTimeout(()=>{
                    this.sum += this.n
                },500)
            },
        },
    }
</script>
  1. Vuex实现

1.main.js里引入Vuex,之后就可以在创建vm时传入store配置项了

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//引入store
import store from './store'

//关闭Vue的生产提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)

//创建vm
new Vue({
    el:'#app',
    render: h => h(App),
    store,
    beforeCreate() {
        Vue.prototype.$bus = this
    }
})

2.在src文件夹里创建store文件夹,在里面新建index.js文件(用于创建vuex中最为核心的store)

import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
    /* jia(context,value){
        console.log('actions中的jia被调用了')
        context.commit('JIA',value)
    },
    jian(context,value){
        console.log('actions中的jian被调用了')
        context.commit('JIAN',value)
    }, */
    jiaOdd(context,value){
        console.log('actions中的jiaOdd被调用了')
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了')
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    }
}
//准备mutations——用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了')
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了')
        state.sum -= value
    }
}
//准备state——用于存储数据
const state = {
    sum:0 //当前的和
}

//创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})

3.Vue.use(Vuex)需放在index.js里,否则会报错

Count.vue:

<script>
    export default {
        name:'Count',
        data() {
            return {
                n:1, //用户选择的数字
            }
        },
        methods: {
            increment(){
                this.$store.commit('JIA',this.n)
            },
            decrement(){
                this.$store.commit('JIAN',this.n)
            },
            incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                this.$store.dispatch('jiaWait',this.n)
            },
        },
        mounted() {
            console.log('Count',this)
        },
    }
</script>

Vuex原理图:

this.$store.dispatch('actions里的方法',要传的数据)

this.$store.commit('mutations里的方法',要传的数据)

  1. getters的使用

当state中的数据需要经过加工后再使用时,可以使用getters加工。

  1. 在store->```index.js```中追加```getters```配置

//准备getters——用于将state中的数据进行加工
const getters = {
    bigSum(state){
        return state.sum*10
    }
}
//创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})
  1. 在组件中读取数据

<h1>当前求和为:{{$store.state.sum}}</h1>

三、四个map方法的使用

  1. mapState方法:用于帮助映射state中的数据为计算属性

Count.vue

优化后代码:

index.js

const state = {
    sum:0, //当前的和
    school:'尚硅谷',
    subject:'前端'
}

Count.vue

//借助mapState生成计算属性,从state中读取数据。(对象写法)
           ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),

            //借助mapState生成计算属性,从state中读取数据。(数组写法)
            ...mapState(['sum','school','subject']),
  1. mapGetters方法:用于帮助映射getters中的数据为计算属性

/* bigSum(){
                return this.$store.getters.bigSum
            }, */
//借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
             ...mapGetters({bigSum:'bigSum'})
            
            //借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
            ...mapGetters(['bigSum'])

3.mapActions方法:用于帮助我们生成与```actions```对话的方法,即:包含```$store.dispatch(xxx)```的函数

methods: {
            //程序员亲自写方法
            /* increment(){
                this.$store.commit('JIA',this.n)
            },
            decrement(){
                this.$store.commit('JIAN',this.n)
            }, */

            //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            ...mapMutations({increment:'JIA',decrement:'JIAN'}),

            //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
             ...mapMutations(['JIA','JIAN']),
}

用这种方法必须在模板的点击事件调用的函数中传入参数:

<button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前求和为奇数再加</button>
        <button @click="incrementWait(n)">等一等再加</button>

因为通过mapMutations生成的方法是这种形式的:

而我们期待生成的方法是这样的:

期待生成的方法中this.n是我们自己指定的,而mapMutations并不知道我们要传的参数是什么,会默认获取一个value值,如果不在点击事件中传入参数n,mapMutations会自动接收event鼠标点击事件,从而会显示NAN.

4.mapActions():用于帮助我们生成与```mutations```对话的方法,即:包含```$store.commit(xxx)```的函数.

methods: {
            //程序员亲自写方法
            /* incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },
            incrementWait(){
                this.$store.dispatch('jiaWait',this.n)
            }, */

            //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
            ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

            //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
            // ...mapActions(['jiaOdd','jiaWait'])

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值