Vue-loader: Support for methods in functional component + template

Created on 7 May 2018  路  2Comments  路  Source: vuejs/vue-loader

What problem does this feature solve?

There is no way for me to use functions in a functional template.

While I can declare methods outside the scope of the functional-component definition and access it within the render method (Snippet 1), I cannot access it when I use a functional template (Snippet 2).

_Snippet 1:_

<script>
function emit(listeners, eventName, ...args) {
    const eventHandler = listeners[eventName];
    if (typeof eventHandler === 'function') {
        eventHandler(...args);
    }
}

const comp = {
    functional: true,

    render(h, ctx) {
        return h('a', {
            attrs: {
                href: '#',
            },
            on: {
                click: emit(ctx.listeners, 'open'),
            },
        }, ['Link']);
    },
};

export default comp;
</script>

_Snippet 2: Doesn't work_

<template functional>
    <a
        href="#"
        @click="emit(listeners, 'open')"
    >
        Link
    </a>
</template>

<script>
function emit(listeners, eventName, ...args) {
    const eventHandler = listeners[eventName];
    if (typeof eventHandler === 'function') {
        eventHandler(...args);
    }
}

const comp = {
    functional: true,
};

export default comp;
</script>

What does the proposed API look like?

<template functional>
    <a
        href="#"
        @click="methods.emit(listeners, 'open')"
    >
        Link
    </a>
</template>

<script>
const comp = {
    functional: true,
    methods: {
        emit(listeners, eventName, ...args) {
            const eventHandler = listeners[eventName];
            if (typeof eventHandler === 'function') {
                eventHandler(...args);
            }
        },
    },
};

export default comp;
</script>

_This is a change in Core, but was asked to remake this issue in vue-loader_

Most helpful comment

It's possible to access a functional component's methods via $options already, although I couldn't find documentation anywhere.

<template functional>
    <a href="#" @click="$options.methods.emit(listeners, 'open')">Link</a>
</template>
<script>
export default {
    methods: {
        emit(listeners, eventName, ...args) {
            const eventHandler = listeners[eventName];
            if (typeof eventHandler === 'function') {
                eventHandler(...args);
            }
        },
    },
};
</script>

All 2 comments

I can open a PR if the feature request is approved

It's possible to access a functional component's methods via $options already, although I couldn't find documentation anywhere.

<template functional>
    <a href="#" @click="$options.methods.emit(listeners, 'open')">Link</a>
</template>
<script>
export default {
    methods: {
        emit(listeners, eventName, ...args) {
            const eventHandler = listeners[eventName];
            if (typeof eventHandler === 'function') {
                eventHandler(...args);
            }
        },
    },
};
</script>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

flashios09 picture flashios09  路  3Comments

matt-sanders picture matt-sanders  路  4Comments

sdvcrx picture sdvcrx  路  3Comments

amorphine picture amorphine  路  3Comments

githoniel picture githoniel  路  3Comments