vuex动态注册嵌套module提供模块内部组件间的数据共享(代码片段)

左直拳 左直拳     2023-01-09     661

关键词:

vuex提供了全局性的共享数据。如果数据限于模块内共享,可以采用嵌套module,通过命名空间进行访问。

vue开发的主角是组件。组件在代码解耦、复用、提高可读性方面立下功劳,但组件间共享数据、传递参数却很麻烦,尤其是组件嵌套层次很深的情况。如果是祖宗辈传递参数给儿孙辈还好一些,祖宗provider,儿孙inject;然而这是单向的,儿孙想更改祖宗里的这些值就难了。因为你想用 this.$parent,未必能找到父一辈的组件。就算能找到,this.$parent.$parent...这种方式也让人抓狂。

vuex就是为了解决这个问题的。其工作方式,就是所有组件都能访问、更改vuex对象里的数据。数据是共用的,有组件改了,所有组件看到的都变了。就好像在操作一个全局变量一样。

这样就会有一个问题。由于vuex提供的是全局性的数据共享机制,它的作用域是整个系统,不存在说我只在子系统内声明一个vuex对象,自己访问就好。如果我没有理解错误的话,一个系统,有且只有一个vuex对象。如果工程比较复杂,存在多个子系统,所有共享数据都放在一个vuex对象里,会很拥挤和臃肿。因此vuex提供了module,每个module都是一个store对象,并且可以嵌套。这样可以将子系统、模块的共享数据,存储进vuex对象里的相应module,区分层次。同时,module可以采取动态注册的方式,即当运行子系统或模块的时候,才注册相关module;关闭或退出子系统和模块,注销module。以下是详细说明:

一、创建vuex对象

src/store/index.js,这是面向整个系统的

import Vue from 'vue'
import Vuex from 'vuex'

import user from './module/user'
import app from './module/app'

Vue.use(Vuex)

export default new Vuex.Store(
  state: 
    //
  ,
  mutations: 
    //
  ,
  actions: 
    //
  ,
  modules: 
    user,
    app
  
)

二、某模块的store module

某模块的store module(src/projects/dzzhyj/store.js)

const key = 'dzzhyj'

export default 
  install (_this) 
    if (_this.$store.state[key]) //如果module已经存在,则先注销
      $store.unregisterModule(key)
    

    _this.$store.registerModule([key], 
      /*
        actions
          1、用于通过提交mutation改变数据
          2、会默认将自身封装为一个Promise
          3、可以包含任意的异步操作

        mutations
          1、通过提交commit改变数据
          2、只是一个单纯的函数
          3、不要使用异步操作,异步操作会导致变量不能追踪
      */
      namespaced: true,//请注意,是namespaced!而不是namespace!这个属性与类似“dzzhyj/product/”
      modules: 
        product: 
          namespaced: true,
          state: 
            v: 'hello world', // for test
            details: []
          ,
          mutations: // 同步操作
            setV (state, val) 
              state.v = val
            ,
            setDetails (state, val) 
              state.details = val
            
          ,
          actions: // 异步操作
            getV ( state ) 
              return state.v
            ,
            keepDetails: ( commit , val) => 
              commit('setDetails', val)
            
          
        
      
    )
  ,
  uninstall (_this) 
    _this.$store.unregisterModule([key])
  


三、动态注册store module

下图中,页签容器页、页签都是一个个独立的组件。在页签容器页(即明细信息对话框)注册,“报告”页签写入数据,“地图”页签读取数据。

在模块的明细信息对话框里进行注册store module(src/view/projects/dzzhyj/product/_pop.vue)

<!-- 这是一个弹出框 -->
<template>
  <div>
    <Modal v-model="modal1" :width="width" :styles=" top: '10px' " draggable >
		。。。
    </Modal>
  </div>
</template>

<script>
import myStore from '@/projects/dzzhyj/store.js'

export default 
  data () 
    return 
    ...
    
  ,
  created () 
    myStore.install(this) //注册我的store module
  ,
  destroyed () 
    myStore.uninstall(this)//注销我的store module
  ,
  methods: 
  	...
  

</script>

四、更改数据

src/view/projects/dzzhyj/product/_report.vue

<template>
  <div class="page-container">
	“报告”页签。。。
  </div>
</template>

<script>
export default 
  data () 
	。。。
  ,
  methods: 
    keepDetails (val) 
      //想支持这种 'dzzhyj/product/keepDetails' action,store中的namespaced = true
      this.$store.dispatch('dzzhyj/product/keepDetails', val).then(() => 
        console.log('已缓存明细数据')
      )
    
  

</script>

五、读取数据

“报告”页签的兄弟页签“地图”读取明细数据进行绘制

src/view/projects/dzzhyj/product/_map.vue

<template>
  <div class="map-container">
    "地图"页签。。。
  </div>
</template>

<script>
export default 
  data () 
	。。。
  ,
  methods: 
    dyeing (details) 
		//地图绘制
    
  ,
  computed: 
    getDetails () 
      let details = null
      if (this.$store.state.dzzhyj && this.$store.state.dzzhyj.product) 
        details = this.$store.state.dzzhyj.product.details
      
      return details
    
  ,
  watch: 
    getDetails (val) 
      this.dyeing(val)
    
  

</script>

六、总结

如果没有vuex,两个并列的页签组件之间,如何传递数据呢?可以将数据通过emit传给容器页,再由容器页传给另一个页签。比较麻烦,也不清晰。

vuex可以很好地解决组件间数据共享的问题。当然,如果明白vuex的原理,自己写代码实现一个store.js之类的组件也可以,但没有必要,就用vuex好了,很方便。之前见过网上一些文章都说,如果参数传递不太多,就没必要用这个vuex;甚至有人说不想用vuex。给人的感觉,就是vuex是个很庞大、笨重、复杂的东西。其实呢,vuex并不复杂,反而很好用,只是有一两个坑,避开就好。

参考文章:
vuex 的动态注册方法 registerModule

注册模块中的vuex未知突变类型

...】:2018-02-0614:29:24【问题描述】:我只是想在vuex中创建动态注册模块,但它似乎不起作用。这是我的商店文件importVuexfrom\'vuex\'importdescriptionModulefrom\'./module/descriptionModule\';constst 查看详情

使用 NuxtJS 和 vuex-module-decorators 的动态 vuex 存储模块

】使用NuxtJS和vuex-module-decorators的动态vuex存储模块【英文标题】:DynamicvuexstoremoduleswithNuxtJSandvuex-module-decorators【发布时间】:2020-06-0523:06:27【问题描述】:我很难让我的vuex模块与NuxtJSs-s-r、TypeScript和vuex-module-decorators一起使用。... 查看详情

Vuex:具有动态命名空间的 createNamespacedHelpers

】Vuex:具有动态命名空间的createNamespacedHelpers【英文标题】:Vuex:createNamespacedHelperswithdynamicnamespace【发布时间】:2019-07-0218:49:09【问题描述】:在我看到的关于vuex模块注册的几乎所有指南、教程、帖子等中,如果模块是由组件... 查看详情

vuex中module的命名空间概念(代码片段)

...空间概念默认情况下,模块内部的action、mutation和getter是注册在全局命名空间的。弊端1:不同模块中有相同命名的mutations、actions时,不同模块对同一mutation或action作出响应。弊端2:当一个项目中store分了很多模块的时候,在使用... 查看详情

vuex的使用及组件通信方式

...实现组件间的状态共享。在大型复杂的项目中(多级组件嵌套),需要实现一个组件更改某个数据,多个组件自动获取更改后的数据进行业务逻辑处理,这时候使用vuex比较合适。假如只是多个组件间传递数据,使用vuex未免有点... 查看详情

vuex-class(代码片段)

...录  2.store目录下的index.js //index.js是所有模块注册文件importVuefrom‘vue‘importVuexfrom‘vuex‘importuserfrom‘./model/user‘Vue.use(Vuex)exportdefaultnewVuex.Store(modules:user)//module目录下的user.jsconstuser=state:checked:‘你好vuex‘,mutations:ADD_US... 查看详情

vuex使用教程

...义异步的一些方法,module可以将多个store分成一个一个的模块。以上就是vuex大致的使用方法全文转自:辰漪博客 查看详情

vuex深入理解modules

...对象也将对变得非常大,难于管理。module:可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。二、怎么用module?一般结构constmoduleA=state:...,mutations:...,actions:...,getters:...constmoduleB=state:...,mutatio... 查看详情

vuex状态管理(代码片段)

VUEX状态管理VUEX是VUE提供的一个状态管理工具,具体他能做什么呢,比如有这样的业务场景:用户在登录后,可以设置他的登录信息。去到用户主页,就可以显示这个用户的登录信息。其实就是用来在不同的组件之间共享信息。... 查看详情

vuex中使用多模块时,如果不同模块中action有名字冲突该如何解决(代码片段)

...aced:true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有getter、action及mutation都会自动根据模块注册的路径调整命名conststore=newVuex.Store(modules:account:namespaced:true,//模块内容(moduleassets)state:...,//模块内的状态已... 查看详情

vuex

...les:    //数据过多时,我们应该将不同组件的数据分模块划分  )修改state的唯一方式就是提交mutationcommit()组件中使用committhis.$store.commit(‘mutation名字‘,‘数据‘)action中需要需要先从参数中获取commitactions:  //actionNa... 查看详情

一篇搞定vuex

...  所以,Vuex主要解决是组件间数据传递问题,尤其是嵌套组件, 查看详情

无法在组件中调度 Vuex 模块的操作

】无法在组件中调度Vuex模块的操作【英文标题】:CouldnotdispatchactionsofVuex\'smoduleincomponent【发布时间】:2019-10-1804:27:09【问题描述】:我是Vue和Vuex的新手。我有一个关于这个框架的问题,希望能得到一些帮助。这是我的主要商店... 查看详情

vuex使用学习六:modules(代码片段)

...应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store。通过对Vuex中的Store分隔,分隔成一个一个的Module模块,每个Module模块都拥有自己的state、mutation、actions和getters。constmoduleA=state:()=>(...) 查看详情

vuex的秘籍之vuex的模块化及工具类,样式的配置(代码片段)

...样一个需求:首页引入header组件和侧边栏组件,头部组件动态控制侧 查看详情

Vue.js 以特定方式自动注册 Vuex 模块

】Vue.js以特定方式自动注册Vuex模块【英文标题】:Vue.jsAutoregisterVuexmodulesinaspecificway【发布时间】:2020-07-2011:02:51【问题描述】:我刚开始使用Vue.js,我正在尝试使用Vuex。我的目录中有以下结构:src/store/store├──index.js└──m... 查看详情

vuex之state(代码片段)

...系统中,需要调用Vue.use(Vuex),通过在根实例vm(newVue(store)注册store,这样根组件的所有子组件都可以$store.state.xxx访问state的数据了。//这里我引入vue直接指定了路径方法不唯一,只要能引入vue即可importVuefrom'../../node_modules/vue/dist... 查看详情

vuex概述(代码片段)

...2*注意:如果要操作store中的state值,只能通过调用mutations提供的方法,才能操作对应的数据33*34*不推荐直接操作state中的数据,因为万一导致了数据的紊乱,不能快速定位到错误的原因3 查看详情