简体   繁体   中英

Vuex - Sharing common functions across modules

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?

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("-newNAME-"); this.changeTitle("-newTITLE-"); }, 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: '-one-'}, mounted() { this.myStr1 = this.truncate(this.myStr1); } }) new Vue({ el: '#app2', data: {myStr2: '-two-'}, mounted() { this.myStr2 = this.truncate(this.myStr2); } }) // ...and components Vue.component('my-comp', { template: '#t3', data() { return {myStr3: '-three-'} }, 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>

@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/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>

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');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM