Introduction
Here I’ll show you how to build a functional component using defineComponent
.
I’ll share an example I came across in the Vue.js challenge series, where I learned to use this functionality.
Do read all the comments in the code below.
Code example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
// ./MyButton
// Using TypeScrit
import { h } from "vue";
import { defineComponent } from "vue";
const MyButton = defineComponent(
// this is the setup method where destructure the context
// to extract emit and slots
(props, { emit, slots }) => {
// this arrow function is similar to the `return {}`
// that you use in the setup function in a SFC component
return () => {
// call the render function
return h(
// add a button element
"button",
{
// with the disabled attribute assigned
// to the disabled prop value
disabled: props.disabled,
// bind a click event to custom-click emit
onClick: () => emit("custom-click"),
},
// this pass on the slot content to the element
slots.default?.()
);
};
},
// extra options, e.g. declare props and emits
// like the props, component name and emits
{
// component name
name: "MyButton",
// definition of the props
props: {
disabled: { type: Boolean, default: false },
},
// definition of the emits
emits: ["custom-click"],
}
);
export default MyButton;
|
Now, you understand Vue.js a bit more in depth.
As for the template, the usage remains unchanged to a regular SFC.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script setup lang="ts">
import { ref } from "vue";
import MyButton from "./MyButton";
const disabled = ref(false);
const onClick = () => {
disabled.value = !disabled.value;
};
</script>
<template>
<!--
:disabled is the same as :disabled="disabled" since Vue 3.4+
see https://vuejs.org/guide/essentials/template-syntax.html#same-name-shorthand
-->
<MyButton :disabled @custom-click="onClick"> my button </MyButton>
</template>
|
Feel free to contact me if you see any mistakes and if you simply want to say thank you.
Credit: Photo by Kelly Sikkema on Unsplash.