Vue 3 — More Complex Render Functions

John Au-Yeung - Jan 19 '21 - - Dev Community

Subscribe to my email list now at http://jauyeung.net/subscribe/

Follow me on Twitter at https://twitter.com/AuMayeung

Many more articles at https://medium.com/@hohanga

Even more articles at http://thewebdev.info/

Vue 3 is the up and coming version of Vue front end framework.

It builds on the popularity and ease of use of Vue 2.

In this article, we’ll look at how to create render functions with Vue 3.

Replacing Template Features with Render Functions

We can replace template features with render functions.

Directives like v-if and v-for can be replaced within render functions.

v-if can be replaced an if statement.

v-for can be replaced with an array of items.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <todo-list :todos="todos"></todo-list>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            todos: [{ name: "eat" }, { name: "drink" }, { name: "sleep" }]
          };
        }
      });

      app.component("todo-list", {
        props: ["todos"],
        render() {
          if (this.todos.length) {
            return Vue.h(
              "div",
              this.todos.map(todo => {
                return Vue.h("div", todo.name);
              })
            );
          } else {
            return Vue.h("div", "no todos.");
          }
        }
      });

      app.mount("#app");
    </script>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

We created the todo-list component with the if statement to check the length fo the this.todos array.

And we called map to return an array of divs with the name .

v-on

The equivalent of the v-on directive is the on methods in the object in the 2nd argument.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <custom-div></custom-div>
    </div>
    <script>
      const app = Vue.createApp({});

      app.component("custom-div", {
        render() {
          return Vue.h(
            "div",
            {
              onClick: $event => console.log("clicked", $event.target)
            },
            "click me"
          );
        }
      });

      app.mount("#app");
    </script>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

We created a custom-div component with a div.

The 2nd argument is an object that has the onClick method, which listens to clicks on the div.

The 3rd argument has the content between the div tags.

v-model

v-model ‘s equivalent is the modelValue prop and the onInput method.

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <custom-input v-model="value"></custom-input>
      <p>{{value}}</p>
    </div>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            value: ""
          };
        }
      });

      app.component("custom-input", {
        props: ["modelValue"],
        render() {
          return Vue.h("input", {
            modelValue: this.modelValue,
            onInput: ev => this.$emit("update:modelValue", ev.target.value)
          });
        }
      });

      app.mount("#app");
    </script>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

We have the modelValue prop with the custom-input component.

this.modelValue has the prop’s value.

We set that as the modelValue property’s value.

And then we emit the update:modelValue event to send the value to the parent.

Now when we type in something, it’ll be synchronized with the value state.

So we’ll see what we typed displayed.

Event Modifiers

Event modifiers can also be replaced with render functions.

For instance, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <div id="app">
      <custom-div></custom-div>
    </div>
    <script>
      const app = Vue.createApp({});

      app.component("custom-div", {
        render() {
          return Vue.h(
            "div",
            {
              onClick: {
                handler: ev => console.log(ev),
                capture: true
              },
              onKeyUp: {
                handler: ev => console.log(ev),
                once: true
              },
              onMouseOver: {
                handler: ev => console.log(ev),
                once: true,
                capture: true
              }
            },
            "click me"
          );
        }
      });

      app.mount("#app");
    </script>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

to add the event handler methods.

The options are the modifiers.

Conclusion

We can replace various directives with their equivalents with render functions.

The post Vue 3 — More Complex Render Functions appeared first on The Web Dev.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .