Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespaced Mixins #7501

Closed
GesJeremie opened this issue Jan 22, 2018 · 2 comments
Closed

Namespaced Mixins #7501

GesJeremie opened this issue Jan 22, 2018 · 2 comments

Comments

@GesJeremie
Copy link

GesJeremie commented Jan 22, 2018

What problem does this feature solve?

I want to be able to create a namespaced mixin.

Let's take this notification mixin for example:

(function()  {
    'use strict';

    window.mixins = window.mixins || {}

    window.mixins.notification = {
        methods: {
            show: function(type, message, duration) {
                duration = duration || 5000;

                new Noty({
                    type: type,
                    text: message,
                    timeout: duration,
                    theme: 'custom'
                }).show();
            }
        }
    }
}());

I can import it in my component and use it:

(function() {
    'use strict';

    Vue.component('basic-component', function() {
        mixins: [window.mixins.notification],

        created: function() {
            this.show();
        }
    })
})

But this doesn't scale since you don't really know where the show() method comes from.

This can be already "solved" using a prefix in the method such as:

(function() {
    'use strict';

    Vue.component('basic-component', function() {
        mixins: [window.mixins.notification],

        created: function() {
            this.mixinNotificationShow();
        }
    })
})

but it seems a bad "implementation".

What does the proposed API look like?

Let's take my first example:

(function()  {
    'use strict';

    window.mixins = window.mixins || {}

    window.mixins.notification = {
        methods: {
            show: function(type, message, duration) {
                duration = duration || 5000;

                new Noty({
                    type: type,
                    text: message,
                    timeout: duration,
                    theme: 'custom'
                }).show();
            }
        }
    }
}());

This could be injected in the component such as:

(function() {
    'use strict';

    Vue.component('basic-component', function() {
        mixins: [{mixin: window.mixins.notification, as: 'notification'}],

        created: function() {
            // Will produce a mixins namespace suffixed with the name given for the mixin
            this.mixins.notification.show();
        }
    })
})
@posva
Copy link
Member

posva commented Jan 22, 2018

It would be even better to just do mixins: { notification: window.mixins.notifications } but I don't see why do you need this.

But this doesn't scale since you don't really know where the show() method comes from.

Yes, you know. It comes from the mixin you explicitly included in that component. The idea of a mixin is to reuse some behaviour across components in an explicit and transparent way, and how would it apply to other things like hooks?

If you want that namespace for functions that are not related to the component you want to use the mixin on, you can add the namespace yourself very easily the way you proposed

const mixin = {
	created () {
		this.$showNotification = () => {}
 	}
}

or with a dynamic name using a function

function buildNotificationMixin (namespace) {
	return {
		created () {
			this[namespace] = {}
			this[namespace].show = () => {}
		}
	}
}

// Component.vue
const Component = {
	mixins: [buildNotificationMixin('$notifications')
}

or use a computed to group things

const mixin = {
	computed () {
		$notifications () {
			return {
				show: () => {}
			}
		}
	}
}

Related: #1470

@yyx990803
Copy link
Member

This doesn't have to be in Vue core. The mixin mechanism is already flexible enough for you to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants