background

Before, the company made an audit function, and the business data and status were relatively complicated. At the beginning, Vuex Store was used for data interaction. Recently, the requirement of page template based on audit function was introduced, and different functions were developed according to its template (different menu entry, same template, only different API). In the process of transformation, we encountered the problem of how to reuse store components.

The problem

The audit system can open multiple menus, that is, the menus generated by the same template need to be opened and used at the same time. As we know, components in VUE can be reused, and each reference generates a new instance, but the introduction of store in components leads to different instances sharing the same store, and data will be confused

Method 1: Make the menu mutually exclusive

$router-push = this.$router-push = this.$router-push = this.$router-push = this. Listen for the binding event @click to see if a push operation needs to be performed after a new menu is opened. This method limits the ability to open multiple pages

Method 2: Try to reference different stores without using menus

Then I began to think whether I could reference different stores by dynamically modifying the first parameter of mapState, mapActions, and mapMutations (muduleName).

ModuleName cannot be dynamically modified because the first parameter of mapState cannot get this. Is it possible to call mapXXX directly without using the mapxxx function? Yes, but there are too many changes to make

Method three: Try dynamic registration

Vuex.vuejs.org/zh/guide/mo…

Dynamic registration is also possible, but requires a different moduleName to be registered, and then the problem goes back to method two, which just changes from static registration to dynamic registration

Method 4: Component register store

Unlike method 3, which registers the Module, this registers the entire Store

$this.$root.$store = this.$root

conclusion

If you know from the beginning that you need to reuse components, it is better not to use store in components, because the purpose of store is to share the entire VUE application data. Method 4 is feasible but breaks this pattern. Causes external components to be unable to access their internal re-registered store (of course, you can register modules dynamically into the global store)

[Update] PassedDynamic Registration ModuleRegister into the global Store

// Unified management mixins
import Base from '@/page/base';
import module from '@/store/modules/module';
import Vuex from 'vuex';

export default function(menuName) {
  return {
    store: new Vuex.Store(module),
    components: { Base },
    created() {
      const rootStore = this.$root.$store;
      // Register module dynamically. The two states are not synchronizedrootStore.registerModule(menuName, { ... module,namespaced: true});Rootstore. state[menuName]
      this.$store.subscribe(mutation= > {
        rootStore.commit(`${menuName}/${mutation.type}`, mutation.payload); }); }}; }Copy the code

Other articles by author:

Share personal software/tools for development

Interpret and implement a simple KOA-Router

A note about using $attrs for Element el-Button

github: github.com/masongzhi