vuex技术多组件共享数据-vuex模块化+namespace

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vuex技术多组件共享数据-vuex模块化+namespace相关的知识,希望对你有一定的参考价值。

天空是连着的,如果我们也能各自发光的话,无论距离有多远,都能看到彼此努力的身影。

vuex技术多组件共享数据-vuex模块化+namespace

我们知道每一个组件都有自己的 data,那么多个组件如何共享数据?这就引出了 state 的概念,可以把多个组件共有的属性统一由state进行管理。但是组件并不能直接访问或操作state里的数据源,而是通过 mutations 来对数据源进行操作。而改变数据的行为触发由 Actions 来完成,Vue 为 actions的触发提供了一个 commit 的概念,由action 触发通过 mutations 对数据进行操作,从而改变 state 数据源。

通过:import nanoid from 'nanoid'来生成一个ID属性。
核心代码块:

methods:
            add()
                const personObj = id:nanoid(),name:this.name;
                this.$store.commit('ADD_PERSON',personObj)
                console.log(personObj);
                this.name = ''
            
        

当我们开发的项目比较大时,store中的数据就可能比较多,这时我们store中的数据就可能变得臃肿,为了解决这一问题,我们就需要将store模块化(module),

即每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块

vuex模块化核心代码示例
开启命名空间,简化代码示例:

const countOptions = 
    namespaced: true,
    state: 
        sum: 0,
        name: '勇敢牛牛,不怕困难',
    ,
    actions: 
        jiaodd(context, value) 
            context.commit("JIAODD", value)
        ,
        jiaWait(context, value) 
            context.commit('JIAWAIT', value)
        
    ,
    mutations: 
        JIA(state, value) 
            state.sum += value
        ,
        JIANJIAN(state, value) 
            state.sum -= value

        ,
        JIAODD(state, value) 
            if (state.sum % 2 != 0) 
                state.sum += value
            
        ,
        JIAWAIT(state, value) 
            setTimeout(() => 
                state.sum += value
            , 500)
        ,
    ,
    getters: 
        bigSum(tate) 
            return state.sum * 10
        
    

才可以使用简写,直接获取属性值

  ...mapState('a',['sum','name'])

在person组件中如果直接对commit操作。就在属性值前面加这个模块的名称

this.$store.commit('b/ADD_PERSON',personObj)

例如:

add()
                const personObj = id:nanoid(),name:this.name;
                this.$store.commit('b/ADD_PERSON',personObj)
                console.log(personObj);
                this.name = ''
            

在【person中联系muttion修改数据】

this.$store.commit('b/ADD_PERSON',personObj);

最终的数据结构

index.js

//引入Vue
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
//使用插件
Vue.use(Vuex)

//计算相关配置
import countOptions from './count'

// 人员相关配置
import personOptions from './person'

// 创建store
export default new Vuex.Store(
    modules: 
        a: countOptions,
        b: personOptions
    
)

// export default store

count.js


const countOptions = 
    namespaced: true,
    state: 
        sum: 0,
        name: '勇敢牛牛,不怕困难',
    ,
    actions: 
        jiaodd(context, value) 
            context.commit("JIAODD", value)
        ,
        jiaWait(context, value) 
            context.commit('JIAWAIT', value)
        
    ,
    mutations: 
        JIA(state, value) 
            state.sum += value
        ,
        JIANJIAN(state, value) 
            state.sum -= value

        ,
        JIAODD(state, value) 
            if (state.sum % 2 != 0) 
                state.sum += value
            
        ,
        JIAWAIT(state, value) 
            setTimeout(() => 
                state.sum += value
            , 500)
        ,
    ,
    getters: 
        bigSum(state) 
            return state.sum * 10
        
    

export default countOptions

person.js

import axios from "axios";
import  nanoid  from 'nanoid'
const personOptions = 
    namespaced: true,
    state: 
        personList: [
             id: '001', name: '张安' 
        ]
    ,
    actions: 
        addPersonWang(context, value) 
            if (value.name.indexOf('王') === 0) 
                context.commit('ADD_PERSON', value)
             else 
                alert('添加的人必须是姓王')
            
        ,
        addPersonServer(context) 
            axios.get('https://api.uixsj.cn/hitokoto/get?tyoe=social').then(
                response => 
                    context.commit('ADD_PERSON',  id: nanoid(), name: response.data )
                ,
                error => 
                    alert(error.message)
                

            )
        
    ,
    mutations: 
        ADD_PERSON(state, value) 
            console.log('muttion中的ADD_preson被调用了');
            state.personList.unshift(value)
        
    ,
    getters: 
        firstPersonName(state) 
            return state.personList[0].name
        
    

export default personOptions

Person.vue

<template>
    <div>
        <h1>person</h1>
        <h2 class="one">count组件的求和为sum</h2>
        <h2>列表中第一个信息是: firstPersonName </h2>
        <input type="text" name="" id="" placeholder="请输入名字" v-model="name">
        <button @click="add()">添加</button>
        <button @click="addWang()">添加一个姓王的人</button>
        <button @click="addServer()">添加一随机语句</button>
        <ul>
            <li v-for="p in personList" :key='p.id'>
                p.name
            </li>
        </ul>
    </div>
</template>

<script>
    import mapState  from 'vuex'
    import  nanoid  from 'nanoid'
    export default 
        name:'Person',
        data()
            return 
                name:'',
            
        ,
        computed:
            // personList()
            //     return this.$store.state.personList
            // 
            ...mapState('a', ['sum']),
            ...mapState('b', ['personList']),
            firstPersonName()
                return this.$store.getters['b/firstPersonName']
            
        ,
        methods:
            add()
                const personObj = id:nanoid(),name:this.name;
                this.$store.commit('b/ADD_PERSON',personObj);
                console.log(personObj);
                this.name = ''
            ,
            addWang()
                const personObj =  id: nanoid(), name: this.name ;
                this.$store.dispatch('b/addPersonWang', personObj)
                this.name = ''
            ,
            addServer()
                this.$store.dispatch('b/addPersonServer')
            
        ,
        mounted() 
            console.log(this.$store);
        

    
</script> 
<style>
    .one
        color: rgb(68, 156, 233);
    
</style>

Count.vue

<template>
    <div>
        <h1>当前数值为:sum</h1>
        <h2>放大10倍后的数值是:bigSum</h2>
        <h3>name</h3>
        <h3 class="tow">person组件总人数是: personList.length </h3>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前数和为奇数再加</button>
        <button @click="incrementWait(n)">延时时间后再加</button>
    </div>
</template>

<script>
    import mapGetters, mapState , mapMutations,mapActions from 'vuex'

    export default 
        name:'Count',
        data() 
            return
                n:1
            
        ,
        methods:
            ...mapMutations('a',  increment: 'JIA', decrement: 'JIANJIAN' ),
            ...mapActions('a', incrementOdd : 'jiaodd',incrementWait:'jiaWait'),
            
        ,
        computed:
           
            // ...mapGetters(['bigSum']),
            // ...mapState(['a','b'])
            ...mapState('a',['sum','name']),
            ...mapState('b', ['personList']),
            ...mapGetters('a',['bigSum']),
            

        ,
        mounted()                                                                          
            const x = mapState(name:'name');
            
        
       
    

</script>  

<style scoped>
    button
        margin-left: 10px;
    
    .tow
        color: rgb(68, 156, 233);
    
</style>

App.vue

<template>
   <div>
       <Count/>
       <Person/>
   </div>
</template>
<script>
    import Count from './components/Count.vue';
    import Person from './components/Person.vue'
	export default 
    name: "App",
    data() 
        return 
            data:1
        ;
    ,
    components: Count, Person,
    mounted()
        // console.log('app',this);
    

</script>
<style scoped>
    

</style>

main.js

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

// 也就是创建了一个store
// 引入store
import store from './store/index'
//关闭Vue的生产提示
Vue.config.productionTip = false
//创建vm
new Vue(
	el: '#app',
	render: h => h(App),
	store: store,
	beforeCreate() 
		Vue.prototype.$bus = this
	
)

以上是关于vuex技术多组件共享数据-vuex模块化+namespace的主要内容,如果未能解决你的问题,请参考以下文章

vuex使用,使用场景

Vuex 核心概念基本使用 及 求和案例

Vuex 核心概念基本使用 及 求和案例

Vuex

vuex动态注册嵌套module提供模块内部组件间的数据共享

Vuex 的使用