精华内容
下载资源
问答
  • 主要介绍了详解如何更好的使用module vuex,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 一、 前言在项目如何使用vuex呢?以前我都是非模块化去写的,可能大家和我一样也是这么去写,但是回过头去看看vue的文档,发现模块化去使用vuex更好,vue是单页面应用,其实只有一个页面,那么首页也好列表页也好,...


    一、 前言

    在项目如何使用vuex呢?以前我都是非模块化去写的,可能大家和我一样也是这么去写,但是回过头去看看vue的文档,发现模块化去使用vuex更好,vue是单页面应用,其实只有一个页面,那么首页也好列表页也好,那都相当于这一个页面的一个模块,也可以把它理解为是一个一个的组件,毕竟组件化、组件抽离、组件封装是比较火的,所以在使用vuex的模块化的时候就能更好的去管理对应的模块,对于数据分离和定位都非常的好。废话有点多,先丢张图。

    Demo连接:github.com/cookie-zhan…


    通信之间还是比较麻烦的,所以诞生了vuex。

    二、 啥是vuex?

    有人说是一个插件、有人说是一个仓库。官方说的就比较好理解,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。其实它就是对vue做数据管理的,更好的存储数据、响应数据。

    三、 什么时候最适合使用vuex?

    引用官方语言:Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的store模式就足够您所需了,但是,如果您需要构建一个大型单页应用,您很可能会考虑如何更好的在组件外部管理状态,Vuex将会成为自然选择。

    四、 由图讲原理


       四大核心模块:

    1. state: 翻译:状态,state其实是数据状态管理对象,在这里你可以初始化一些你想要的数据。
    2. getter: 翻译: 获得者,getter是对state的数据对象的读取,getters从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。getters就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
    3. Actions:翻译:行动,Actions里面我们可以定义我们想执行异步的方法,在这里它并不会立即去执行,而是在页面中去dispatch这个方法,提交mutations,而不是直接去改变状态,在页面中有两种方式去做派发,第一种  this.$store.dispatch('xxx') 第二种 可以使用mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(Demo中有体现)
    4. mutations:翻译: 突变,mutations里面可写很多的改变状态的方法,也就是像翻译一样,可以改变state里面的数据,试讲state的里面数据发生改变的唯一方式。

    五、上Demo

    初始化项目就不讲了,根据文档一步一步生成就可以了

    • 目录结构:


    页面展示



    模块化数据

        首先在store里面创建modudel文件夹,分别创建homeDataStore.js和listDataStore.js,这两个模块就是分别存储对应页面的数据,以上页面展示可以看到我只在list页面写了数据,所以我们就把list页面作为例子来讲。

    listDataStore.js代码展示

    import axios from 'axios'
    const listData = {
        namespaced:true,//注意 模块化管理数据请不要忘了命名空间的开启
        state:{
           List:[],
           count: 0,
           compoentData:[],
           number: 0
    
        },
        actions:{
            getListData(context){
                new Promise((resolve,reject)=>{
                    axios.get('../../../static/listData.json').then((res)=>{
                        context.commit('ListData',{'listDatas': res.data.listData})
                    })
                })
            },
            handleAdd(context){
                context.commit("handleAddState")
            }
        
        },
        mutations:{
            ListData(state, paylod){
                state.List = paylod.listDatas
            },
            handleAddState(state){
                state.number++;
            }
        },
        getters: {
            List: state => state.List,
            count: state => state.count,
            number: state => state.number
        }
    }
    export default listData;
    复制代码

    数据格式是一样的,每个页面都是这四大核心模块组成

    store文件夹下面的index.js文件展示

    //这个是总的store,抛出各个模块的store
    import Vue from 'vue'
    import Vuex from 'vuex'
    import homeData from './moudel/homeDataStore'
    import listData from './moudel/listDataStore'
    Vue.use(Vuex)
    const store = new Vuex.Store({    
    modules:{ 
           homeData,
            listData,
        }})export default store;复制代码

    在这里引入各个模块的数据。

    main.js文件展示

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import store from  './store/index'
    Vue.config.productionTip = false
    /* eslint-disable no-new */
    new Vue({ 
     el: '#app',  
    router,  
    store,  
    render: h => h(App)
    })
    复制代码

    引入store,将store注册到vue的实例上面,这样对应模块的数据基本格式是这样,接下来在看看页面中怎么调用的吧。

    页面使用store数据  列表页展示

    <template>
     <div> 
    <router-link to='/'> 首页home</router-link><br/>
    这是列表页list<br/>
    <ul> 
    <li v-for="item in List" v-bind:key="item.id">{{item.item}}</li> 
    </ul>       
     <div>计算:</div>
            <div>{{number}}</div>
            <button @click='handleAdd()'>add</button> 
       </div></template><script>
    import { mapGetters, mapActions } from 'vuex'
    export default {    
    name: 'list',
    data(){        
    return{}    
    },    
    computed:{        
        ...mapGetters('listData',['List','number'])    
    },    
    methods:{        
      //方法一:  ...mapActions('listData',['getListData','handleAdd']),       
       //方法二:       
       ...mapActions({            
         getListData:"listData/getListData",            
         handleAdd:"listData/handleAdd"        
    })    
    },    
    mounted(){        
       this.getListData();    
    }}
    </script>
    <style></style>复制代码

    引入import { mapGetters, mapActions } from 'vuex' 辅助函数,在computed计算属性里面把对应页面的数据也就是列表页对应的列表页的store拿到List number,也可以认为是读取里面的数据,将数据映射到页面来,这样就拿到了响应的数据,methods里面是映射到页面的方法,比如getListData方法就是走接口请求过来的数据,当页面加载完后调用,也就是在mounted。handleAdd方法也是派发,在对应的actions里面可以看到。如果不用辅助函数,也就会用到dispatch,这里没在细讲

    demo地址:github.com/cookie-zhan…

    六 总结

    以上描述简单易懂,可以在项目中直接使用这种模块化管理数据的方式,总体来看就更好的理解vux的流程图,单向数据流连通起来就可以形成一个完美的闭环。 没有太多文采,只想用最近单易懂的语言描述自己的理解,如果能帮到你那么一丢丢,请给我一个小小的赞⊙_⊙!


    转载于:https://juejin.im/post/5c997e59f265da60f6731774

    展开全文
  • Vuex Module

    2020-07-09 18:38:24
    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割: const moduleA = { state: () => ({...

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

    const moduleA = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: () => ({ ... }),
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
    

    模块的局部状态

    对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。

    const moduleA = {
      state: () => ({
        count: 0
      }),
      mutations: {
        increment (state) {
          // 这里的 `state` 对象是模块的局部状态
          state.count++
        }
      },
    
      getters: {
        doubleCount (state) {
          return state.count * 2
        }
      }
    }
    

    同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState:

    const moduleA = {
      // ...
      actions: {
        incrementIfOddOnRootSum ({ state, commit, rootState }) {
          if ((state.count + rootState.count) % 2 === 1) {
            commit('increment')
          }
        }
      }
    }
    

    对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:

    const moduleA = {
      // ...
      getters: {
        sumWithRootCount (state, getters, rootState) {
          return state.count + rootState.count
        }
      }
    }
    

    命名空间

    默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

    如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。例如:

    const store = new Vuex.Store({
      modules: {
        account: {
          namespaced: true,
    
          // 模块内容(module assets)
          state: () => ({ ... }), // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
          getters: {
            isAdmin () { ... } // -> getters['account/isAdmin']
          },
          actions: {
            login () { ... } // -> dispatch('account/login')
          },
          mutations: {
            login () { ... } // -> commit('account/login')
          },
    
          // 嵌套模块
          modules: {
            // 继承父模块的命名空间
            myPage: {
              state: () => ({ ... }),
              getters: {
                profile () { ... } // -> getters['account/profile']
              }
            },
    
            // 进一步嵌套命名空间
            posts: {
              namespaced: true,
    
              state: () => ({ ... }),
              getters: {
                popular () { ... } // -> getters['account/posts/popular']
              }
            }
          }
        }
      }
    })
    

    启用了命名空间的 getter 和 action 会收到局部化的 getter,dispatch 和 commit。换言之,你在使用模块内容(module assets)时不需要在同一模块内额外添加空间名前缀。更改 namespaced 属性后不需要修改模块内的代码。

    在带命名空间的模块内访问全局内容(Global Assets)

    如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。

    若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

    modules: {
      foo: {
        namespaced: true,
    
        getters: {
          // 在这个模块的 getter 中,`getters` 被局部化了
          // 你可以使用 getter 的第四个参数来调用 `rootGetters`
          someGetter (state, getters, rootState, rootGetters) {
            getters.someOtherGetter // -> 'foo/someOtherGetter'
            rootGetters.someOtherGetter // -> 'someOtherGetter'
          },
          someOtherGetter: state => { ... }
        },
    
        actions: {
          // 在这个模块中, dispatch 和 commit 也被局部化了
          // 他们可以接受 `root` 属性以访问根 dispatch 或 commit
          someAction ({ dispatch, commit, getters, rootGetters }) {
            getters.someGetter // -> 'foo/someGetter'
            rootGetters.someGetter // -> 'someGetter'
    
            dispatch('someOtherAction') // -> 'foo/someOtherAction'
            dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
    
            commit('someMutation') // -> 'foo/someMutation'
            commit('someMutation', null, { root: true }) // -> 'someMutation'
          },
          someOtherAction (ctx, payload) { ... }
        }
      }
    }
    

    在带命名空间的模块注册全局 action

    若需要在带命名空间的模块注册全局 action,你可添加 root: true,并将这个 action 的定义放在函数 handler 中。例如:

    {
      actions: {
        someOtherAction ({dispatch}) {
          dispatch('someAction')
        }
      },
      modules: {
        foo: {
          namespaced: true,
    
          actions: {
            someAction: {
              root: true,
              handler (namespacedContext, payload) { ... } // -> 'someAction'
            }
          }
        }
      }
    }
    

    带命名空间的绑定函数

    当使用 mapState, mapGetters, mapActions 和 mapMutations 这些函数来绑定带命名空间的模块时,写起来可能比较繁琐:

    computed: {
      ...mapState({
        a: state => state.some.nested.module.a,
        b: state => state.some.nested.module.b
      })
    },
    methods: {
      ...mapActions([
        'some/nested/module/foo', // -> this['some/nested/module/foo']()
        'some/nested/module/bar' // -> this['some/nested/module/bar']()
      ])
    }
    

    对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为:

    computed: {
      ...mapState('some/nested/module', {
        a: state => state.a,
        b: state => state.b
      })
    },
    methods: {
      ...mapActions('some/nested/module', [
        'foo', // -> this.foo()
        'bar' // -> this.bar()
      ])
    }
    

    而且,你可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:

    import { createNamespacedHelpers } from 'vuex'
    
    const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
    
    export default {
      computed: {
        // 在 `some/nested/module` 中查找
        ...mapState({
          a: state => state.a,
          b: state => state.b
        })
      },
      methods: {
        // 在 `some/nested/module` 中查找
        ...mapActions([
          'foo',
          'bar'
        ])
      }
    }
    

    给插件开发者的注意事项

    如果你开发的插件(Plugin)提供了模块并允许用户将其添加到 Vuex store,可能需要考虑模块的空间名称问题。对于这种情况,你可以通过插件的参数对象来允许用户指定空间名称:

    // 通过插件的参数对象得到空间名称
    // 然后返回 Vuex 插件函数
    export function createPlugin (options = {}) {
      return function (store) {
        // 把空间名字添加到插件模块的类型(type)中去
        const namespace = options.namespace || ''
        store.dispatch(namespace + 'pluginAction')
      }
    }
    

    模块动态注册

    在 store 创建之后,你可以使用 store.registerModule 方法注册模块:

    import Vuex from 'vuex'
    
    const store = new Vuex.Store({ /* 选项 */ })
    
    // 注册模块 `myModule`
    store.registerModule('myModule', {
      // ...
    })
    // 注册嵌套模块 `nested/myModule`
    store.registerModule(['nested', 'myModule'], {
      // ...
    })
    

    之后就可以通过 store.state.myModule 和 store.state.nested.myModule 访问模块的状态。

    模块动态注册功能使得其他 Vue 插件可以通过在 store 中附加新模块的方式来使用 Vuex 管理状态。例如,vuex-router-sync 插件就是通过动态注册模块将 vue-router 和 vuex 结合在一起,实现应用的路由状态管理。

    你也可以使用 store.unregisterModule(moduleName) 来动态卸载模块。注意,你不能使用此方法卸载静态模块(即创建 store 时声明的模块)。

    注意,你可以通过 store.hasModule(moduleName) 方法检查该模块是否已经被注册到 store。

    保留 state

    在注册一个新 module 时,你很有可能想保留过去的 state,例如从一个服务端渲染的应用保留 state。你可以通过 preserveState 选项将其归档:store.registerModule(‘a’, module, { preserveState: true })。

    当你设置 preserveState: true 时,该模块会被注册,action、mutation 和 getter 会被添加到 store 中,但是 state 不会。这里假设 store 的 state 已经包含了这个 module 的 state 并且你不希望将其覆写。

    模块重用

    有时我们可能需要创建一个模块的多个实例,例如:

    • 创建多个 store,他们公用同一个模块 (例如当 runInNewContext 选项是 false 或 ‘once’ 时,为了在服务端渲染中避免有状态的单例)
    • 在一个 store 中多次注册同一个模块

    如果我们使用一个纯对象来声明模块的状态,那么这个状态对象会通过引用被共享,导致状态对象被修改时 store 或模块间数据互相污染的问题。

    实际上这和 Vue 组件内的 data 是同样的问题。因此解决办法也是相同的——使用一个函数来声明模块状态(仅 2.3.0+ 支持):

    const MyReusableModule = {
      state: () => ({
        foo: 'bar'
      }),
      // mutation, action 和 getter 等等...
    }
    
    展开全文
  • at getModule (webpack-internal:///./node_modules/vuex-module-decorators/dist/esm/index.js:27:36) at Store.eval (webpack-internal:///./node_modules/vuex-module-decorators/dist/esm/index.js:305:46) ...
  • vuex module

    2019-06-06 14:27:06
    Vuex学习(二)--模块modules及获取根部数据或方法 2018年11月29日 16:28 ...为了解决这个问题,Vuex允许我们将store分隔成模块(module),每个模块拥有自己的state,mutation,action,getter...

    Vuex学习(二)--模块modules及获取根部数据或方法

    2018年11月29日

    16:28

    1.使用modules的目的:

    由于使用单一的状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂,store对象就会变得非常臃肿;为了解决这个问题,Vuex允许我们将store分隔成模块(module),每个模块拥有自己的state,mutation,action,getter,甚至是嵌套子模块

    2.具体写法:

    (1)在store中新建一个模块文件

     

              

    export default{
        namespaced:true,
        state:{
            arr:[]
        },
        getters:{
            add(state){
                return state.arr.push({a:"123"})
            }
        },
        mutations:{
            push2(state){
                console.log("45")
                state.arr.push('2')
            },
            aaa(state){
                state.arr={a:222}  
            }
        },
        actions:{
            adda({ state, commit, rootState}){
                // commit('aaa',null,{root:true})
                commit('aaa', 'aaa', { root: true })
            }
        }
    }

    (2)在store中的出口文件中引入模块

    这里的属性名也可以简写成  moduleA  ES6写法

    index.js

    (3)模块中的getters参数及其可取到的值  

        ①state:获取modules中的state数据

        ②getters:获取modules中的getters数据

        ③rootState:获取根部state数据

        ④rootGetters:获取根部getters数据

    modules中的getters

    (4)模块中的mutations参数及其可取到的值

        ①state:获取modules中的state数据

        ②getters:获取modules中的getters数据

        ③调用方法时传入的值

    (5)模块中的actions参数及其可取到的值

        ①commit:获取模块的mutations

      commit('aaa', 'aaa', { root: true })  这样才是获得根的mutations 

        ②dispatch:获取根部actions

        ③rootState:获取根部state,rootState.数据名称

        ④rootGetters:获取根部getters,rootState.数据名称

        ⑤state:获取modules中的getters

        ⑥getters:获取modules中的getters

    modules中的actions

    (6)modules中的子模块

    名为modoleChild的子模块

    3.组件中获取数据及方法的写法

    (1)获取模块中state的数据  也可以这样获取根数据 state.即可

    (2)获取模块中getters的数据   这样暂时不能获得根getterts  要想获得根getters 可以使用原来的方法

                                     ...mapGetters([''])

    (3)获取模块中mutations或actions的方法  

    <template>
      <div class="hello">
        <div>{{nameBig}}</div>
        <button @click="aa">按钮</button>
        <button @click="age">按钮</button>
      </div>
    </template>
    
    <script>
    import { createNamespacedHelpers } from 'vuex';
    const { mapState: mapState1, mapActions, mapGetters } = createNamespacedHelpers('wang');
    
    // import { mapState, mapActions } from "vuex";
    export default {
      name: 'HelloWorld',
      props: {
        msg: String,
      },
      computed: {
        ...mapState1({
          name: (state) => state.name,
        }),
        ...mapGetters(['nameBig']),
      },
      methods: {
        ...mapActions(['age']),
        aa() {
          this.age(3);
          console.log(this.name);
        },
      },
      mounted() {
        console.log(this.nameBig)
      },
    };
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped lang="less">
    h3 {
      margin: 40px 0 0;
    }
    ul {
      list-style-type: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 0 10px;
    }
    a {
      color: #42b983;
    }
    </style>
    

     

    展开全文
  • vuex Module

    2019-01-11 20:30:43
    为了解决以上问题,Vuex 允许将 store 分割成模块(module)。 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割: const moduleA = { state: { ... ...

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。
    当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
    为了解决以上问题,Vuex 允许将 store 分割成模块(module)。
    每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
    

    模块的局部状态
    对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。
    const moduleA = {
      state: { count: 0 },
      mutations: {
        increment (state) {
          // 这里的 `state` 对象是模块的局部状态
          state.count++
        }
      },

      getters: {
        doubleCount (state) {
          return state.count * 2
        }
      }
    }


    同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState:
    const moduleA = {
      // ...
      actions: {
        incrementIfOddOnRootSum ({ state, commit, rootState }) {
          if ((state.count + rootState.count) % 2 === 1) {
            commit('increment')
          }
        }
      }
    }

    对于模块内部的 getter,根节点状态会作为第三个参数暴露出来:
    const moduleA = {
      // ...
      getters: {
        sumWithRootCount (state, getters, rootState) {
          return state.count + rootState.count
        }
      }
    }

    命名空间

    默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的(即注册在根节点上),
    使得多个模块能够对同一 mutation 或 action 作出响应。
    如果希望模块具有更高的封装度和复用性,可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
    当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
    例如:

    const store = new Vuex.Store({
      modules: {
        account: {
          namespaced: true,
    
          // 模块内容(module assets)
          state: { ... }, // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
          getters: {
            isAdmin () { ... } // -> getters['account/isAdmin']
          },
          actions: {
            login () { ... } // -> dispatch('account/login')
          },
          mutations: {
            login () { ... } // -> commit('account/login')
          },
    
          // 嵌套模块
          modules: {
            // 继承父模块的命名空间
            myPage: {
              state: { ... },
              getters: {
                profile () { ... } // -> getters['account/profile']
              }
            },
    
            // 进一步嵌套命名空间
            posts: {
              namespaced: true,
    
              state: { ... },
              getters: {
                popular () { ... } // -> getters['account/posts/popular']
              }
            }
          }
        }
      }
    })

    启用了命名空间的 getter 和 action 会收到局部化的 getter,dispatch 和 commit。
    换言之,你在使用模块内容(module assets)时不需要在同一模块内额外添加空间名前缀。
    更改 namespaced 属性后不需要修改模块内的代码。

    在带命名空间的模块内访问全局内容(Global Assets)
    如果希望使用全局 state 和 getter,
    rootState 和 rootGetter 会作为第三和第四参数传入 getter
    也会通过 context 对象的属性传入 action。
    若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

    modules: {
      foo: {
        namespaced: true,
    	
        getters: {
          // 在这个模块的 getter 中,`getters` 被局部化了
          // 你可以使用 getter 的第四个参数来调用 `rootGetters`
          someGetter (state, getters, rootState, rootGetters) {
            getters.someOtherGetter // -> 'foo/someOtherGetter'
            rootGetters.someOtherGetter // -> 'someOtherGetter'
          },
          someOtherGetter: state => { ... }
        },
    
        actions: {
          // 在这个模块中, dispatch 和 commit 也被局部化了
          // 他们可以接受 `root` 属性以访问根 dispatch 或 commit
          someAction ({ dispatch, commit, getters, rootGetters }) {
            getters.someGetter // -> 'foo/someGetter'
            rootGetters.someGetter // -> 'someGetter'
    
            dispatch('someOtherAction') // -> 'foo/someOtherAction'
            dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
    
            commit('someMutation') // -> 'foo/someMutation'
            commit('someMutation', null, { root: true }) // -> 'someMutation'
          },
          someOtherAction (ctx, payload) { ... }
        }
      }
    }

    在带命名空间的模块注册全局 action
    若需要在带命名空间的模块注册全局 action,
    可添加 root: true,并将这个 action 的定义放在函数 handler 中。

    例如:
    {
      actions: {
        someOtherAction ({dispatch}) {
          dispatch('someAction')
        }
      },
      modules: {
        foo: {
          namespaced: true,
    
          actions: {
            someAction: {
              root: true,
              handler (namespacedContext, payload) { ... } // -> 'someAction'
            }
          }
        }
      }
    }

    带命名空间的绑定函数

    当使用 mapState, mapGetters, mapActions 和 mapMutations 这些函数来绑定带命名空间的模块时,写起来可能比较繁琐:
    computed: {
      ...mapState({
        a: state => state.some.nested.module.a,
        b: state => state.some.nested.module.b
      })
    },
    methods: {
      ...mapActions([
        'some/nested/module/foo', // -> this['some/nested/module/foo']()
        'some/nested/module/bar' // -> this['some/nested/module/bar']()
      ])
    }

    对于这种情况,可以将模块的空间名称字符串作为第一个参数传递给上述函数,
    这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为:

    computed: {
      ...mapState('some/nested/module', {
        a: state => state.a,
        b: state => state.b
      })
    },
    methods: {
      ...mapActions('some/nested/module', [
        'foo', // -> this.foo()
        'bar' // -> this.bar()
      ])
    }

    可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。
    它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:

    import { createNamespacedHelpers } from 'vuex'
    const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
    
    export default {
      computed: {
        // 在 `some/nested/module` 中查找
        ...mapState({
          a: state => state.a,
          b: state => state.b
        })
      },
      methods: {
        // 在 `some/nested/module` 中查找
        ...mapActions([
          'foo',
          'bar'
        ])
      }
    }

    给插件开发者的注意事项
    如果开发的插件(Plugin)提供了模块并允许用户将其添加到 Vuex store,
    可能需要考虑模块的空间名称问题。对于这种情况,可以通过插件的参数对象来允许用户指定空间名称:

    // 通过插件的参数对象得到空间名称
    // 然后返回 Vuex 插件函数
    export function createPlugin (options = {}) {
      return function (store) {
        // 把空间名字添加到插件模块的类型(type)中去
        const namespace = options.namespace || ''
        store.dispatch(namespace + 'pluginAction')
      }
    }

     

    模块动态注册

    在 store 创建之后,可以使用 store.registerModule 方法注册模块:
    // 注册模块 `myModule`
    store.registerModule('myModule', {
      // ...
    })
    // 注册嵌套模块 `nested/myModule`
    store.registerModule(['nested', 'myModule'], {
      // ...
    })

    之后就可以通过 store.state.myModule 和 store.state.nested.myModule 访问模块的状态。
    模块动态注册功能使得其他 Vue 插件可以通过在 store 中附加新模块的方式来使用 Vuex 管理状态。例如,vuex-router-sync
    插件就是通过动态注册模块将 vue-router 和 vuex 结合在一起,实现应用的路由状态管理。
    也可以使用 store.unregisterModule(moduleName) 来动态卸载模块。
    注意,不能使用此方法卸载静态模块(即创建 store 时声明的模块)。
    在注册一个新 module 时,很有可能想保留过去的 state,
    例如从一个服务端渲染的应用保留 state。可以通过 preserveState 选项将其归档:store.registerModule('a', module, { preserveState: true })。

     

    模块重用

    有时可能需要创建一个模块的多个实例
    例如:
        创建多个 store,他们公用同一个模块
        (例如当 runInNewContext 选项是 false 或 'once' 时,为了在服务端渲染中避免有状态的单例)
        在一个 store 中多次注册同一个模块
        
    如果使用一个纯对象来声明模块的状态,那么这个状态对象会通过引用被共享,导致状态对象被修改时 store 或模块间数据互相污染的问题。
    实际上这和 Vue 组件内的 data 是同样的问题。因此解决办法也是相同的——使用一个函数来声明模块状态(仅 2.3.0+ 支持):

    const MyReusableModule = {
      state () {
        return {
          foo: 'bar'
        }
      },
      // mutation, action 和 getter 等等...
    }

    展开全文
  • vuex-persistedstate Persist and rehydrate your Vuex state between page reloads. Install npm install --save vuex-persistedstate The UMD build is also available on unpkg: <script src=...
  • vuex module总结

    2020-01-15 15:39:50
    vuex module总结 // 创建store文件夹 然后在store文件夹下创建对应的js文件 // 在该js文件中引入对应的依赖文件 import Vue from 'vue' import Vuex from 'vuex' import moduleA from 'moduleA所在的文件的地址' ...
  • VUEX封装module

    2019-05-24 20:22:43
    VUEX封装module 目录结构 store/index.js,配置,以及导入两种方式 import Vue from 'vue' import Vuex from 'vuex' import m from './module/m' import authority from './module/authority' // 调试方法 ...
  • 当在严格模式中使用 Vuex 时,在属于 Vuex 的 state 上使用v-model会比较棘手: <input v-model="obj.message"> 假设这里的obj是在计算属性中返回的一个属于 Vuex store 的对象,在用户输入时,v-...
  • vuexmodule

    2020-05-21 10:17:49
    vuexmodule 一、什么时候需要在 vuex 中使用 module 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们...
  • declare module "vuex" { interface Store<s> { direct: AppStore } } </s></code></pre> <p>Is it means that I can use some code instead of (working) <pre><code> import { store as ...
  • 前言Vuex源码学习已经连载到了第四篇,前三篇的内容如下:长篇连载:Vuex源码学习(一)功能梳理长篇连载:Vuex源码学习(二)脉络梳理作为一个Web前端,你知道Vuex的install做了什么吗?正文整合模块这一节该分析模块的...
  • vuexmodule

    2019-08-07 15:40:00
     为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割: 在src下建立文件夹store,用于存放...
  • Vuexmodule

    千次阅读 2019-02-02 15:16:54
    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。 新建一个js,moduleA: const state = {...
  • vuex-Module

    2018-02-24 15:25:00
    Vuex 允许将 store 分割成模块(module)。 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块 const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, ...
  • m just trying to separate typescript declaration code from runtime code, and have a question about direct-vuex configuration from <a href="https://github.com/paleo/direct-vuex#create-the-store">readme...
  • vuex module使用

    2017-11-27 21:26:40
    const moduleA = {  state: {....},  mutations: {....},  actions: {...},  getters: {...} ...const moduleB = {  state: {....},  mutations: {....},  actions: {...},  getters: {...} }
  • Vuex中的Module

    2019-11-05 16:53:12
    Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块 { moduleA: { state: {}, mutation: {}, action: {}, getters: {} }, ...
  • vuexmodule使用

    2020-10-25 10:43:55
    import Vuex from 'vuex' Vue.use(Vuex) // 1 下载vuex 导入 use一下 // 2 new Vuex.Store // 3 挂载到new vue上 export default new Vuex.Store({ state: { // 在这里写的就是所有组件都能有 全局数据了 // 名字...
  • vuex-module.zip

    2020-06-15 09:59:17
    vuex模块化懒加载 解决vuex数据臃肿 数据庞大 引起的性能问题 使用我自定义的懒加载模式解决 适用于大型项目构建或者vuex太过于庞大
  • 前言 vuex 规定更改 state 的唯一方法是提交 mutation,主要是为了能用 devtools 追踪状态变化。 那么,提交 mutation 除了最主要的更改 state,它还做了其它一些...Vuex Module Vuex 严格模式 Class 的基本语法 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,603
精华内容 641
关键字:

modulevuex

vue 订阅