vue 学习总结(二)[Vuex]

目录

Vuex

Vuex介绍

工作原理图

使用说明

案例一:求和案例

不使用vuex

使用vuex,将sum变量存储到vuex的state中

getters配置项

mapState, mapGetters

mapMutations,mapActions

多组件间共享数据

模块化+命名空间


Vuex

Vuex介绍

  • 专门在Vue中集中管理数据的一个插件,对Vue中多组件共享数据的集中管理,是组件间的一种通信方式,适用于任何组件间的数据传递;
  • Vuex Github 项目

工作原理图

使用说明

  • 首先安装Vuex插件:npm install vuex@3 (注意:vue2只能用vuex3,vue3只能用vuex4,分版本安装);
  • 使用Vuex的地方,进入插件并使用:import Vuex from "vuex";
  • 官方推荐使用方式:在src下建立store目录,目录下建立index.js文件;
  • /store/index.js文件引入并使用vuex插件,声明vuex的actions、mutations、state变量,根据声明的变量实例化vuex,最后js暴露实例对象;
  • main.js中引入Vuex插件库和 /store/index.js,实例化Vue时使用Vuex插件并传入store配置项

 /store/index.js

//引入Vue核心库
import Vue from "vue"
//引入Vuex插件库
import Vuex from "vuex"

//使用插件
Vue.use(Vuex)

//声明actions, 用于接收$store的dispatch操作,处理业务逻辑
const actions = {}

//声明mutations, 用于接收$store的commit操作,修改state中的数据
const mutations = {}

//声明state, 用于存放共享数据
const state = {}

//实例化store对象并暴露
export default new Vuex.Store({
    actions,
    mutations,
    state
});

main.js

import Vue from 'vue'
import App from './App.vue'

//引入store
import store from './store'

Vue.config.productionTip = false;

new Vue({
  render: h => h(App),
  //实例化Vue时传入store配置项
  store
}).$mount('#app')

 

 

案例一:求和案例

不使用vuex

创建MyCount模块,不使用vuex的情况下写出基本结构,并实现基本功能

<template>
    <div>
        <h2>求和案例,当前和为{{sum}}</h2>
        <input type="text" v-model.number="num">
        <button @click="increment">加</button>
        <button @click="decrement">减</button>
        <button @click="waitIncrement">等待1s后加</button>
    </div>
</template>

<script>
    export default {
        name: "MyCount",
        data(){
            return {
                num: 2,
                sum: 1
            }
        },
        methods: {
            increment(){
                this.sum += this.num;
            },
            decrement(){
                this.sum -= this.num;
            },
            waitIncrement(){
                setTimeout(()=>{
                    this.sum += this.num;
                }, 1000)
            }
        }
    }
</script>

App.vue里使用MyCount模块

<template>
    <div id="app">
        <MyCount/>
    </div>
</template>

<script>
    import MyCount from './components/MyCount'
    export default {
        name: 'App',
        components: {MyCount}
    }
</script>

页面呈现 

 

 

使用vuex,将sum变量存储到vuex的state中

首先在store/index.js中,state里声明变量sum,mutations里声明加减方法去直接操作sum;actions里声明等待后加1的方法,去操作业务逻辑,然后调用mutations的方法;

//引入Vue核心库
import Vue from "vue"
//引入Vuex插件库
import Vuex from "vuex"

//使用插件
Vue.use(Vuex)

//声明actions, 用于接收$store的dispatch操作,处理业务逻辑
const actions = {
    //注意:传参第一个为上下文可直接使用,value是调用时传递的参数值
    waitIncrement(context, value){
        setTimeout(()=>{
            context.commit('INCREMENT', value);
        }, 1000)
    }
}

//声明mutations, 用于接收$store的commit操作,修改state中的数据
const mutations = {
    //注意:约定mutations里的方法名大写,传参第一个默认参数为store里的state可直接使用,value为调用时传递的参数值
    INCREMENT(state, value){
        state.sum += value;
    },
    DECREMENT(state, value){
        state.sum -= value;
    }
}

//声明state, 用于存放共享数据
const state = {
    sum: 10
}

//实例化store对象并暴露
export default new Vuex.Store({
    actions,
    mutations,
    state
});

MyCount模块中的sum变量,重vuex中的state中取值,Mycount代码修改为如下

<template>
    <div>
        <h2>求和案例,当前和为{{sum}}</h2>
        <input type="text" v-model.number="num">
        <button @click="increment">加</button>
        <button @click="decrement">减</button>
        <button @click="waitIncrement">等待1s后加</button>
    </div>
</template>

<script>
    export default {
        name: "MyCount",
        data(){
            return {
                num: 2,
                // sum: 1
            }
        },
        //使用计算属性声明sum并从store取值
        computed: {
            sum(){
                return this.$store.state.sum;
            }
        },
        methods: {
            increment(){
                //使用commit方法能直接调用mutations里的方法
                this.$store.commit('INCREMENT', this.num);
            },
            decrement(){
                this.$store.commit('DECREMENT', this.num);
            },
            waitIncrement(){
                //使用dispatch方法能直接调用acitons里的方法
                this.$store.dispatch('waitIncrement', this.num);
            }
        }
    }
</script>

 

 

getters配置项

在store/index.js里配置getters,可实现和组件中computed一样的功能;

如在页面展示最后10倍sum的值。命名该变量为tenSum。

store/index.js里配置getters,并声明tenSum变量,同时在实例化store对象时引入getters

const getters = {
    tenSum(){
        return state.sum * 10;
    }
}

//实例化store对象并暴露
export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
});

组件MyCount页面使用$store.getters.xxx使用

<h2>求和案例,当前和为{{sum}}</h2>
<h3>当前和放大十倍为{{tenSum}}</h3>
...

//使用计算属性声明sum并重store取值
computed: {
    sum(){
        return this.$store.state.sum;
    },
    tenSum(){
        return this.$store.getters.tenSum;
    }
},

页面呈现

 

 

mapState, mapGetters

使用mapstate、mapGetters可以在组件使用store里state和getters的数据时,能简化声明,只需在组件的computed里简单使用即可,可以分贝映射state和getters里的数据到computed的数据。

在组件中引入vuex的mapState,mapGetters,并在computed里配置映射

import {mapState, mapGetters} from "vuex"
    export default {
        name: "MyCount",
        data(){
            return {
                num: 2,
                // sum: 1
            }
        },
        //使用计算属性声明sum并重store取值
        computed: {
            // sum(){
            //     return this.$store.state.sum;
            // },
            // tenSum(){
            //     return this.$store.getters.tenSum;
            // }

            //对象写法{name: 'value'}, 可以重命名
            ...mapState({sum: 'sum'}),

            //名字相同,可以使用数组写法
            ...mapGetters(['tenSum'])
        },

 

 

mapMutations,mapActions

mapMutations和mapActions可以分别映射store里action和mutations的方法到组件中,自己无需在定义一个方法去调用action和mutations的方法。

mapMutations映射会自动封装调用this.$store.commit方法,无法传递参数,需在模板中传递;

mapActions映射会自动封装调用this.$store.dispatch方法,无法传递参数,需在模板中传递;

在组件中引入vuex的mapMutations和mapActions,并在methods里进行配置映射

<!-- num参数在此传入,映射方式无法传递参数 -->
<button @click="increment(num)">加</button>
<button @click="decrement(num)">减</button>
<button @click="waitIncrement(num)">等待1s后加</button>


methods: {
    ...mapMutations({increment: 'INCREMENT', decrement: 'DECREMENT'}),
    ...mapActions(['waitIncrement'])

    // increment(){
    //     //使用commit方法能直接调用mutations里的方法
    //     this.$store.commit('INCREMENT', this.num);
    // },
    // decrement(){
    //     this.$store.commit('DECREMENT', this.num);
    // },
    // waitIncrement(){
    //     //使用dispatch方法能直接调用acitons里的方法
    //     this.$store.dispatch('waitIncrement', this.num);
    // }
}

多组件间共享数据

数据在state里或者是getters里存放,如需使用,可直接使用mapState/mapGetter映射即可。

新建组件OtherComponent,并映射mapState、mapGetter使用

<template>
    <div>
        <hr>
        <p>我是其他的组件,MyCount中和为:{{sum}}</p>
        <p>我是其他的组件,MyCount中和的10倍为:{{tenSum}}</p>
    </div>
</template>

<script>
    import {mapState, mapGetters} from 'vuex'
    export default {
        name: "OtherComponent",
        computed: {
            ...mapState(['sum']),
            ...mapGetters(['tenSum'])
        }
    }
</script>

App.vue中引入OtherComponent组件用使用

<template>
    <div id="app">
        <MyCount/>
        <OtherComponent/>
    </div>
</template>

<script>
    import MyCount from './components/MyCount'
    import OtherComponent from './components/OtherComponent'
    export default {
        name: 'App',
        components: {MyCount, OtherComponent}
    }
</script>

效果展现

 

模块化+命名空间

  • 同一功能类型封装在一起,多种数据分类清晰,方便后期维护

将store/index.js里的关于求和的属性和方法,封装为count.js

export default {
    //使用命名空间
    namespaced: true,
    actions: {
        waitIncrement(context, value){
            setTimeout(()=>{
                context.commit('INCREMENT', value);
            }, 1000)
        }
    },
    mutations: {
        INCREMENT(state, value){
            state.sum += value;
        },
        DECREMENT(state, value){
            state.sum -= value;
        }
    },
    state: {
        sum: 10
    },
    getters: {
        //这里注意,传入state参数
        tenSum(state){
            return state.sum * 10;
        }
    }
}

组件使用map映射时,给定命名空间

//对象写法{name: 'value'}, 可以重命名
...mapState('countAbout', {sum: 'sum'}),

//名字相同,可以使用数组写法
...mapGetters('countAbout', ['tenSum'])

...mapMutations('countAbout', {increment: 'INCREMENT', decrement: 'DECREMENT'}),

...mapActions('countAbout', ['waitIncrement'])

直接使用$store单独调用时

//state
this.$store.state.countAbout.sum;

//getters
this.$store.getters["countAbout/tenSum"];

//commit
this.$store.commit('countAbout/INCREMENT', this.num);

//dispatch
this.$store.dispatch('countAbout/waitIncrement', this.num);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值