最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vuex - Sharing common functions across modules - Stack Overflow

programmeradmin1浏览0评论

I am working on a Vue Js 2 application and I'm currently building the store and the different modules to separate out the code. Is there a way to write a common function and share it across all modules?

For example, I have a function truncate() that I need to be use in customer.js, cart.js, address.js. If I declare it in store.js and try to use in modules, it throws an error. Is export and import the only way? What is the best way to share the function?

I am working on a Vue Js 2 application and I'm currently building the store and the different modules to separate out the code. Is there a way to write a common function and share it across all modules?

For example, I have a function truncate() that I need to be use in customer.js, cart.js, address.js. If I declare it in store.js and try to use in modules, it throws an error. Is export and import the only way? What is the best way to share the function?

Share Improve this question asked Mar 15, 2018 at 4:00 VishwasVishwas 1,4988 gold badges22 silver badges34 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 12

The simplest case is, naturally, to just define a regular function in a js file and import/use it anywhere you need it.

There are Vue-specific approaches, though:

For common reusable functions in Vuex modules, you can use Vuex Plugins.

Check an example below. Mind the usage at the root store: 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>

For common reusable functions in Vue instances, you can use Mixins. For the most general case there's the Global Mixin (use with care):

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/[email protected]/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>

@acdcjunior has the best answer using Mixins, but I'm giving you another option by just declaring method in your Vue instance.

So belows example, I am creating doTruncate method in Vue instance then the components are calling them by 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/[email protected]/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>

you can use vue js events to share function like

eventBus.js // it will create common instance

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

common.js // your common functions will go into this file

import { eventBus } from '<path of file>'; 

mounted() {
    eventBus.$on('truncate',()=> {
        this.truncate();
    })
}

methods: {
    truncate(){
        //truncate code
    }
}

customer.js // call your common truncate function from customer.js

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

评论列表(0)

  1. 暂无评论