A neon sign displaying “Do Something Great”

Functional components in Vue

I discovered functional components while training for the level 1 certification of Vue.js. While I might not use it every day as it is very verbose, I’d like to share an example in this article.

I’ll be 100% honest: functional component is another level. It uses the render function h() in Vue.js.

I believe it’s what Vue uses under the hood to convert your SFC (Single File Component) or In-Template code to Virtual DOM nodes.

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 .

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//Using TypeScrit and Composition API
import { ref, h } from "vue";

// To type the list of items
type User = {
  name: String;
};
// To type the props
type Props = {
  list: User[];
  activeIndex: number;
};
// To type the events ( e.g. emit)
type Events = {
  toogle(index: number): void;
};

/**
 * The challenge > Implement a functional component :
 *   1. Render the list elements (ul/li) with the list data
 *   2. Change the list item text color to red when clicked.
 */
const ListComponent = (props: Props, { emit }) => {
  return h(
    "ul", // create a ul element
    props.list.map((item: User, index) =>
      h(
        // loop the list prop (equivalent to v-for)
        "li", // ... to create an li element for each element
        {
          // ... with the mandatory key attribute
          key: index,
          // ...  with the inline style to set the text to red
          // when the current index is equal to activeIndex prop
          style: index == props.activeIndex ? { color: "red" } : null,
          // ... with the assignment of the node `innerText` value
          innerText: item.name,
          // ... and attaching the onclick handler with the toggle emit
          onClick: () => emit("toggle", index),
        }
      )
    )
  );
};

// This lists the props of the component,
// but doesn't define it. See above type.
ListComponent.props = ["list", "active-index"];
// This lists the events handled by the component,
// but doesn't define it. See above type.
ListComponent.emits = ["toggle"];

const list: User[] = [
  {
    name: "John",
  },
  {
    name: "Doe",
  },
  {
    name: "Smith",
  },
];
const activeIndex = ref(0);

function toggle(index: number) {
  activeIndex.value = index;
}

Now, you understand Vue.js a bit more in depth.

As for the template, the usage is unchanged to a regular SFC.

1
2
3
<template>
  <list-component :list="list" :active-index="activeIndex" @toggle="toggle" />
</template>

Feel free to contact me if you see any mistakes and if you simply want to say thank you.

Credit: Photo by Clark Tibbs on Unsplash.

License GPLv3 | Terms
Built with Hugo
Theme Stack designed by Jimmy