Views: 2616
Last Modified: 28.04.2022

When you need to work with several storages within a single application, use the modular system. This mode changes syntax for storage declaration and call actions.

The example below uses the storage with two modules that work within two different Vue applications.

Place elements with identifiers application1 and application2 in the html code: this way we can check for data simultaneously updated in two applications.

First application will show results and second app will change the data.

<div id="application1"></div>
<div id="application2"></div>

In JS extension:

import {createStore, mapState} from 'ui.vue3.vuex';
import {BitrixVue} from 'ui.vue3';

const counterStore = {
	namespaced: true,
	state() {
		return {
			counter: 0
		}
	},
	actions: {
		increaseCounter: (store) => {
			store.commit('increaseCounter', {count: 1});
		},
		decreaseCounter: (store) => {
			store.commit('increaseCounter', {count: -1});
		}
	},
	mutations: {
		increaseCounter: (state, payload = {}) => {
			let {count = 1} = payload;
			state.counter += count;
		}
	}
};

const statusStore = {
	namespaced: true,
	state() {
		return {
			lastAction: 'None'
		}
	},
	actions: {
		setAction(store, payload) {
			const action = payload.toString();
			store.commit('setAction', action);
		},
	},
	mutations: {
		setAction(state, action) {
			state.lastAction = action;
		}
	}
};

const store = new createStore({
	modules: {
		counterStore,
		statusStore,
	}
});

const Buttons = {
	methods: {
		increase() {
			this.$store.dispatch('counterStore/increaseCounter').then(() => {
				this.$store.dispatch('statusStore/setAction', 'Plus');
			});
		},
		decrease() {
			this.$store.dispatch('counterStore/decreaseCounter').then(() => {
				this.$store.dispatch('statusStore/setAction', 'Minus');
			});
		}
	},
	// language=Vue
	template: `
        <button @click="increase">+</button>
        <button @click="decrease">-</button>
    `
};

BitrixVue.createApp({
	components: {
		Buttons
	},
	template: `
        <Buttons/>
    `
}).use(store).mount('#application1');

const Counter = {
	computed: {
		counter() {
			return this.counterStore.counter+' шт.';
		},
		...mapState({
			counterStore: state => state.counterStore,
			statusStore: state => state.statusStore
		})
	},
	template: `
        <div>Click counter — {{ counter }}</div>
        <div>Last action — {{ statusStore.lastAction }}</div>
    `
};

BitrixVue.createApp({
	components: {
		Counter
	},
	template: `<Counter/>`
}).use(store).mount('#application2');

There are several differences when using modular system:

  • Special parameter must be added to parameters when declaring storage:

    namespaced: true, 
    

  • Upon initializing the storage, you need to list all nested storages in the object modules:

    const store = new createStore({
    	modules: {
    		counterStore,
    		statusStore,
    	}
    });
    

Method and action calls are also a little bit different:

  • When executing actions, instead of standard call:

    store.dispatch('setAction', 'Plus');
    

    indicate action jointly with namespace:

    store.dispatch('statusStore/setAction', 'Plus');
    

  • Replace standard call when editing data (mutation):

    store.commit('setAction', 'Plus');
    

    with mutation jointly with namespace:

    store.commit('statusStore/setAction', 'Plus');
    

To use storage data in component template, the component must declare use of these values in template via calculated properties.

Also, use helper function mapState to avoid manually writing all structure elements:

computed: {
    ...mapState({
        counterStore: state => state.counterStore,
        statusStore: state => state.statusStore
    })
},





Courses developed by Bitrix24