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>
<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_
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>
Most helpful comment
It's possible to access a functional component's
methodsvia$optionsalready, although I couldn't find documentation anywhere.