【问题标题】:Vuex - Sharing common functions across modulesVuex - 跨模块共享通用功能
【发布时间】:2018-08-23 18:52:24
【问题描述】:

我正在开发一个 Vue Js 2 应用程序,我目前正在构建商店和不同的模块以分离代码。 有没有办法编写一个通用函数并在所有模块之间共享?

例如,我有一个函数 truncate() 需要在 customer.js、cart.js、address.js 中使用。 如果我在 store.js 中声明它并尝试在模块中使用,则会引发错误。 出口和进口是唯一的方法吗? 共享功能的最佳方式是什么?

【问题讨论】:

    标签: javascript vuejs2 vuex


    【解决方案1】:

    最简单的情况自然是在 js 文件中定义一个常规函数,然后在需要的任何地方导入/使用它。

    不过,有一些特定于 Vue 的方法:

    Vuex 模块中常见的可复用功能,可以使用Vuex Plugins

    查看下面的示例。注意根存储的用法:plugins: [myTruncatePlugin]

    const myTruncatePlugin = store => {
      store.truncate = function(str) {
        return str.replace(/-/g, '') + ' ...was truncaaaated!'; // example implementation
      }
    }
    
    const moduleA = {
      namespaced: true,
      state: {name: "name@moduleA"},
      mutations: { changeName(state, data) { state.name = this.truncate(data); } },
    }
    const moduleB = {
      namespaced: true,
      state: {title: "title@moduleB"},
      mutations: { changeTitle(state, data) { state.title = this.truncate(data); } },
    }
    const myStore = new Vuex.Store({
      strict: true,
      modules: {
        aaa: moduleA,
        bbb: moduleB
      },
      plugins: [myTruncatePlugin]  // IMPORTANT: YOU MUST DECLARE IT HERE
    });
    new Vue({
      store: myStore,
      el: '#app',
      mounted: function() {
        setTimeout(() => {
          this.changeName("-n-e-w-N-A-M-E-");
          this.changeTitle("-n-e-w-T-I-T-L-E-");
        }, 200);
      },
      computed: {
        ...Vuex.mapState('aaa', ['name']),
        ...Vuex.mapState('bbb', ['title'])
      },
      methods: {
        ...Vuex.mapMutations('aaa', ['changeName']),
        ...Vuex.mapMutations('bbb', ['changeTitle'])
      }
    })
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vuex"></script>
    
    <div id="app">
      <p>moduleA's name: {{ name }}</p>
      <p>moduleB's title: {{ title }}</p>
    </div>

    对于 Vue 实例中常见的可复用函数,可以使用Mixins。对于最一般的情况,有Global Mixin(小心使用):

    Vue.mixin({
      methods: {
        truncate(str) {
          return str.replace(/-/g, '') + ' ...was truncaaaated!'; // example implementation
        }
      }
    })
    
    // this.truncate() will be available in all Vue instances...
    new Vue({
      el: '#app1',
      data: {myStr1: '-o-n-e-'},
      mounted() { this.myStr1 = this.truncate(this.myStr1); }
    })
    new Vue({
      el: '#app2',
      data: {myStr2: '-t-w-o-'},
      mounted() { this.myStr2 = this.truncate(this.myStr2); }
    })
    // ...and components
    Vue.component('my-comp', {
    template: '#t3',
      data() { return {myStr3: '-t-h-r-e-e-'} },
      mounted() { this.myStr3 = this.truncate(this.myStr3); }
    });
    new Vue({
      el: '#app3',
    })
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.min.js"></script>
    
    <div id="app1">App1: "{{ myStr1 }}"</div>
    <div id="app2">App2: "{{ myStr2 }}"</div>
    
    <template id="t3">
      <div>App3's component: "{{ myStr3 }}"</div>
    </template>
    <div id="app3"><my-comp></my-comp></div>

    【讨论】:

      【解决方案2】:

      您可以使用 vue js 事件来分享功能,如

      eventBus.js // 它将创建公共实例

      import Vue from 'vue';
      export const eventBus = new Vue();
      

      common.js // 你的常用函数会进入这个文件

      import { eventBus } from '<path of file>'; 
      
      mounted() {
          eventBus.$on('truncate',()=> {
              this.truncate();
          })
      }
      
      methods: {
          truncate(){
              //truncate code
          }
      }
      

      customer.js // 从 customer.js 中调用常用的截断函数

      import { eventBus } from '<path of file>'; 
      eventBus.$emit('truncate');
      

      【讨论】:

        【解决方案3】:

        @acdcjunior 有使用 Mixins 的最佳答案,但我只是在你的 Vue 实例中声明方法,为你提供了另一种选择。

        所以下面的例子,我在 Vue 实例中创建 doTruncate 方法,然后组件通过 this.$parent.doTruncate 调用它们

        // register
        Vue.component('cart-component', {
          template: '<button @click="doTruncate">Cart Truncate!</button>',
          methods: {
          	doTruncate: function() {
            	this.$parent.doTruncate("Hello from cart");
            }
          }
        })
        
        // register
        Vue.component('customer-component', {
          template: '<button @click="doTruncate">Customer Truncate!</button>',
          methods: {
          	doTruncate: function() {
            	this.$parent.doTruncate("Hello from customer");
            }
          }
        })
        
        var app3 = new Vue({
          el: '#app',
          methods: {
          	doTruncate: function(params) {
            	alert(params);
            }
          }
        })
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.15/dist/vue.js"></script>
        <div id="app">
        <cart-component></cart-component>
        <br>
        <customer-component></customer-component>
        <br>
        <button @click="doTruncate('Hello from parent')">
        Parent!
        </button>
        </div>

        【讨论】:

          猜你喜欢
          • 2020-05-03
          • 1970-01-01
          • 2012-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-09
          • 2012-09-19
          • 1970-01-01
          相关资源
          最近更新 更多