Vue.js Components — Templates and Controlling Updates

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

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

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

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we look at alternative ways to define templates and controlling updates.

Alternative Ways to Define Templates

Inline Templates

When the inline-template attribute is present on a child component, the component will use its inner content as its template rather than treating it as distributed content.

However, the scope of the data that’s available inside would be confusing since we have access to the child component’s scope instead of the parent’s inside the tags.

For example, if we have:

src/index.js :

Vue.component("bar", {  
  data() {  
    return {  
      baz: "bar"  
    };  
  },  
  template: `  
    <p></p>  
  `  
});

new Vue({  
  el: "#app",  
  data: {  
    foo: "foo"  
  }  
});
Enter fullscreen mode Exit fullscreen mode

index.js :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <bar inline-template>  
        <div>  
          {{baz}}  
        </div>  
      </bar>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

Then {{bar}} is referencing baz from the bar component. It also overrides the template that we defined in bar .

X-Templates

Another way to define templates is to use a script tag with type text/x-template . Then it can be referenced with an ID.

For example, we can write:

src/index.js :

Vue.component("hello", {  
  data() {  
    return {  
      hello: "hello"  
    };  
  },  
  template: "#hello-template"  
});

new Vue({  
  el: "#app",  
  data: {  
    foo: "foo"  
  }  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <script type="text/x-template" id="hello-template">  
      <p>{{hello}}</p>  
    </script>  
    <div id="app">  
      <hello></hello>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

The code:

<script type="text/x-template" id="hello-template">  
  <p>{{hello}}</p>  
</script>
Enter fullscreen mode Exit fullscreen mode

is our template and we referenced it by using its ID in:

template: "#hello-template"
Enter fullscreen mode Exit fullscreen mode

So we get hello displayed on the page. This should be avoided for production apps because they separate templates from the rest of the component definition.

Controlling Updates

Vue can control view updates with its reactivity system in most cases. However, there are some edge cases where we want to control the updates ourselves.

Forcing an Update

It’s likely that we made a mistake somewhere if we have to force an update in almost all cases.

In those unlikely cases, we can use $forceUpdate .

Use v-once to Render Static Components

We can use v-once to cache the static content after it’s rendered. This is useful for pages with lots of static content.

For example, we can use it as follows:

src/index.js :

Vue.component("hello", {  
  template: `  
    <div v-once>hello</div>  
  `  
});

new Vue({  
  el: "#app"  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <hello></hello>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

It’s convenient for rare cases when we have to render lots of static content, but it shouldn’t be needed unless we actually see slow rendering.

It may cause trouble if we want to render dynamic content later and when developers aren’t familiar with v-once works on the code. They may be confused about why the component isn’t updating.

Conclusion

We can define templates within a component with the inline-template attribute or using a script element with the type text/x-template .

Then we can reference it by its ID in our component code.

We can use $forceUpdate to force updates and v-once to cache the content after it’s rendered, which may be useful for static content. However, they shouldn’t be used almost all the time.

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