Vue 3 — Refs and Edge Cases
Tags: vue, webdev, programming, javascript
Published: 2021-01-25 23:39:51

**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 3 is in beta and it’s subject to change.**

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 use template refs and edge cases with Vue 3.

### Template refs

Sometimes we may need to directly access the DOM.

To let us do that, we can assign a ref to the DOM element we want to access and then we can access it in our component code.

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">
      <input ref="input" />
    </div>
    <script>
      const app = Vue.createApp({
        methods: {
          focusInput() {
            this.$refs.input.focus();
          }
        },
        mounted() {
          this.focusInput();
        }
      });

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

to focus an input when the Vue instance mounts.

We assigned the `input` ref to our input.

Then we called `focus` on it to focus on the input.

We can also add a ref to component itself and use that to call `focusInput` .

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 ref="customInput"></custom-input>
    </div>
    <script>
      const app = Vue.createApp({
        mounted() {
          this.$refs.customInput.focusInput();
        }
      });

      app.component("custom-input", {
        methods: {
          focusInput() {
            this.$refs.input.focus();
          }
        },
        template: `<input ref='input' />`
      });

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

We put our input into the `custom-input` component.

And we have the `focusInput` method that calls `focus` on the input.

We assigned a ref to the `custom-input` component so that we can call the `focusInput` method of it.

And so we get the same result as we did before.

`$refs` are only populated after the component is rendered.

It’s the last resort for direct child component manipulation.

We should avoid accessing refs from templates and computed properties.

### Edge Cases

There’re edge cases in Vue 3 that aren’t addressed by the usual constructs.

### Controlling Updates

Usually, we rely on Vue’s reactivity system to update our component.

But sometimes, we may need to control how components are updated.

Vue provides ways to do that.

### Forcing Updates

We can force updates by using the `$forceUpdate` method on a component.

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">
      <button @click="forceUpdate">update</button>
      <p>{{new Date()}}</p>
    </div>
    <script>
      const app = Vue.createApp({
        methods: {
          forceUpdate() {
            this.$forceUpdate();
          }
        }
      });
      app.mount("#app");
    </script>
  </body>
</html>
```

to do that.

We have a non-reactive expression in our template, so we can call `$forceUpdate` to update the component with a new date.

### Create Static Components with `v-once`

We can create static component with the `v-once` directive.

It makes the content inside the element with the directive only update once.

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">
      <div v-once>
        hello world
      </div>
    </div>
    <script>
      const app = Vue.createApp({});

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

then Vue will never try to update the component once it’s rendered once.

### Conclusion

Template refs let us access component methods and DOM elements directly.

We can also force updates with the `$forceUpdate` method and the `v-once` directive to display static content.