zoukankan      html  css  js  c++  java
  • Vuex module

    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
        }
      }
    }

    命名空间

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

    可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。

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

    { root: true } 作为第三参数传给 dispatchcommit 即可

            dispatch('someOtherAction') // -> 'foo/someOtherAction'
            dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
    
            commit('someMutation') // -> 'foo/someMutation'
            commit('someMutation', null, { root: true }) // -> 'someMutation'

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

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

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

    带命名空间的绑定函数

    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'
        ])
      }
    }

    模块动态注册

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

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

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


    模块重用

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

    实际上这和 Vue 组件内的 data 是同样的问题

    使用一个函数来声明模块状态(仅 2.3.0+ 支持):

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

    module.js

    import Vue from 'vue';
    import 'es6-promise/auto'
    import Vuex from 'vuex';
    
    Vue.use(Vuex);
    
    const moduleA = {
        namespaced: true,
        state: {
            name: 'ModuleA',
            count: 0,
            price: 0,
            total: 0,
        },
        getters: {
            //計算moduleA中的count狀態值與root store中的count狀態值 之間的差值
            countDistanceWithRootCount(state, getters, rootState) {
                return state.count - rootState.count;
            },
        },
        mutations: {
            increment(state) {
                state.count++;
                state.total = state.price * state.count;
            },
            setName(state, payload) {
                state.name = payload.name;
            },
            calculate(state, payload) {
                state.total = state.price * payload;
            },
        },
        actions: {
            //儅大於主節點的count值時,使用主節點的count
            useRootCountIfCountOverClocked({state, commit, rootState}) {
                if (state.count > rootState.count) {
                    commit('calculate', rootState.count);
                }
            },
        },
    };
    
    
    const moduleStore = new Vuex.Store({
        state: {
            count: 10,
        },
        modules: {
            accountA: moduleA,
        },
        mutations: {
            calculate(state, payload) {
                //root store中同名的calculate方法
                console.log('called!');
            },
        },
    
    });
    export default moduleStore;
    
    

    app.js

    /**
     * First we will load all of this project's JavaScript dependencies which
     * includes Vue and other libraries. It is a great starting point when
     * building robust, powerful web applications using Vue and Laravel.
     */
    
    require('./bootstrap');
    
    window.Vue = require('vue');
    
    // import store from './Vuex/index';
    import store from './Vuex/module.js';
    
    /**
     *
     * The following block of code may be used to automatically register your
     * Vue components. It will recursively scan this directory for the Vue
     * components and automatically register them with their "basename".
     *
     * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
     */
    
    // const files = require.context('./', true, /.vue$/i)
    // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))
    
    Vue.component('example-component', require('./components/ExampleComponent.vue').default);
    Vue.component('store-component', require('./components/StoreComponent.vue').default);
    Vue.component('module', require('./components/ModuleStore.vue').default);
    /**
     * Next, we will create a fresh Vue application instance and attach it to
     * the page. Then, you may begin adding components to this application
     * or customize the JavaScript scaffolding to fit your unique needs.
     */
    
    const app = new Vue({
        el: '#app',
        store,
    });
    
    

    ModuleStore.vue:

    <template>
        <div>
            <table>
                <tr>
                    <th>name</th>
                    <th>count</th>
                    <th>price</th>
                    <th>total</th>
                </tr>
                <tr>
                    <td>{{name}}</td>
                    <td>{{count}}</td>
                    <td>{{price}}</td>
                    <td>{{total}}</td>
                </tr>
            </table>
        </div>
    </template>
    
    <script>
        // import {mapState, mapActions, mapMutations, mapGetters} from 'vuex';
        import {createNamespacedHelpers} from 'vuex';
    
        const {mapState, mapActions, mapMutations, mapGetters} = createNamespacedHelpers('accountA');
    
        export default {
            name: "ModuleStore",
            data: function () {
                return {
                    pName: '',
                    pCount: 0,
                    pPrice: 0,
                    pTotal: 0,
                }
            },
            computed: {
                // ...mapState('accountA', [
                //     'name',
                //     'count',
                //     'price',
                //     'total',
                // ]),
                ...mapState([
                    'name',
                    'count',
                    'price',
                    'total',
                ]),
                ...mapActions([
                    'useRootCountIfCountOverClocked',
                ]),
    
            },
    
    
        }
    </script>
    
    <style scoped>
    
    </style>
    
    

    web.php:

    <?php
    
    use IlluminateSupportFacadesRoute;
    
    /*
    |--------------------------------------------------------------------------
    | Web Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register web routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | contains the "web" middleware group. Now create something great!
    |
    */
    
    Route::get('/', function () {
        return view('welcome');
    });
    
    Auth::routes();
    
    Route::get('/home', 'HomeController@index')->name('home');
    Route::get('/store-test', function (Request $request) {
        return view('store');
    });
    Route::get('/module', function (Request $request) {
        return view('module');
    });
    
    


    访问:http://vuex.test/module


    批注 2020-04-25 001050

  • 相关阅读:
    .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
    《ASP.NET Core 与 RESTful API 开发实战》-- (第10章)-- 读书笔记
    《ASP.NET Core 与 RESTful API 开发实战》-- (第9章)-- 读书笔记(下)
    《ASP.NET Core 与 RESTful API 开发实战》-- (第9章)-- 读书笔记(上)
    《ASP.NET Core 与 RESTful API 开发实战》-- (第8章)-- 读书笔记(尾)
    解决win10桌面图标变成白图标的问题
    微信小程序封装http请求
    Java如何控制某个方法允许并发访问的线程个数----Semaphore
    java实现获取用户IP地址
    shell有减号开头的参数的问题
  • 原文地址:https://www.cnblogs.com/dzkjz/p/12771110.html
Copyright © 2011-2022 走看看