Reputation: 3289
How can I attach global filters/mixins/and more to a defined Vue Instance instead of the Vue object?
Example
import Vue from 'vue.js'
import App from './app'
import demo from './mixins/demo'
Vue.mixin(demo)
const vm = new Vue({
router,
render: h => h(App).$mount('#app')
})
How to attach this mixin to vm instead of the Vue object in the case where I have multiple instances?
I tried vm.mixin(demo) but It doesn't seem to work
Upvotes: 0
Views: 649
Reputation: 37793
Your question is not that clear but I feel what you want is to have multiple Vue root instances on the page each with it's own set of global mixins/directives/filters etc.
Unfortunately Vue 2 was not designed in a way to make this easy. Great read on this is Global API section of Vue3 migration guide (citations):
Vue 2.x has a number of global APIs and configurations that globally mutate Vue’s behavior.
While this approach is convenient, it leads to a couple of problems. Technically, Vue 2 doesn't have a concept of an "app". What we define as an app is simply a root Vue instance created via
new Vue()
. Every root instance created from the same Vue constructor shares the same global configuration. As a result:
Global configuration makes it difficult to share the same copy of Vue between multiple "apps" on the same page, but with different global configurations
This is a problem mainly (but not exclusively) during the testing. To fix it, they introduced createLocalVue() method in vue-test-utils, which uses Vue.extend global API to create a "subclass" of base Vue constructor...
So I'v used the same approach to create an example below which shows 2 different Vue subclasses each with it's own set of global mixins and components. It sort of works but has it's quirks (for example take a look how components are registered - leaving out MyVue1.extend
call breaks the code)
My take from this exercise is that it can be done with Vue 2 but it can be a bumpy road and probably best solution is to use Vue 3 where those problems were solved properly...
const MyVue1 = Vue.extend()
const MyVue2 = Vue.extend()
MyVue1.mixin({
methods: {
mixinMethod: function() {
return 'MyVue1'
}
}
})
MyVue1.component('my-component1', MyVue1.extend({
template: '<div> Hello from my-component1: {{ mixinMethod() }} !</div>'
}))
MyVue2.mixin({
methods: {
mixinMethod: function() {
return 'MyVue2'
}
}
})
MyVue2.component('my-component2', MyVue2.extend({
template: '<div> Hello from my-component2: {{ mixinMethod() }} !</div>'
}))
const vm1 = new MyVue1({
template: '<my-component1 />',
}).$mount('#app1')
const vm2 = new MyVue2({
template: '<my-component2 />',
}).$mount('#app2')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app1"></div>
<div id="app2"></div>
Upvotes: 2
Reputation: 21
Did you try it?
import fooMixin from './mixins/fooMixin'
import barMixin from './mixins/barMixin'
const vm1 = new Vue({
router,
mixins: [fooMixin]
render: h => h(App).$mount('#app1')
})
const vm2 = new Vue({
router,
mixins: [barMixin]
render: h => h(App).$mount('#app2')
})
Upvotes: 0