Nwose Lotanna Web Developer and Writer

How to use refs to access your application DOM in Vue.js

5 min read 1627

How To Use Refs To Access Your Application DOM With Vue

Vue.js is a progressive JavaScript framework created by Evan You and the Vue core team, with contributions from 230-plus open source community lovers. Vue is used by more than 870,000 projects and has been starred 140,000 times on GitHub. It is an approachable core library with great focus on the view layer only. It also has a massive ecosystem of supporting libraries that helps you easily build responsive web experiences.

In this post, you will be introduced to ways to reference HTML elements in your components in Vue.js.

Prerequisites

This post is suited for all stages of developers who use Vue — including beginners. Here are a few prerequisites you should already have before going through this article.

You will need the following:

  • Node.js version 10.x or above. Verify your version by running node -v in your terminal/command prompt
  • npm 6.7 or above
  • A code editor; I highly recommend Visual Studio Code
  • The latest version of Vue, installed globally on your machine
  • Vue CLI 3.0 installed on your machine. To do this, uninstall the old CLI version first with npm uninstall -g vue-cli, then install the new one using npm install -g @vue/cli
  • Download a Vue starter project
  • Unzip the downloaded project, navigate into it, and run npm install to keep all the dependencies up to date

What are refs?

Refs are Vue instance properties used to register or indicate a reference to HTML elements or child elements in the template of your application.

If a ref attribute is added to an HTML element in your Vue template, you’ll then be able to reference that element or even a child element in your Vue instance. You can also access the DOM element directly, too; it is a read-only attribute and returns an object.

Why are refs important?

The ref attribute is vital in making the DOM element in which it is included selectable by serving as the key in the parent $ref attribute. So putting a ref attribute in an input element, for instance, will expose the parent DOM node as this.$refs.input, or you can say this.refs["input"].

DOM elements can be easily manipulated by defining methods on the particular element’s reference. A good instance is adding focus to an input element with this:

this.$refs["input"].focus()

In this way, refs can be used just like the document.querySelector('.element') in JavaScript or the $('.element') in jQuery. The $refs can be accessed both inside the Vue.js instance and outside of it. However, they are not data properties, so they are not reactive.

On template inspection in your browser, they do not show up at all because it is not an HTML attribute; it is only a Vue template attribute.

Demo

If you followed this post from the start, you should have downloaded the starter project and opened it up on VS Code. Open the components folder and copy this into the test.vue file:

<template>
  <div>
    <h2>Hello this is for refs man!</h2>
    <p>You have counted {{this.counter}} times</p>
    <input type="text" ref="input">
    <button @click="submit">Add 1 to counter</button>
  </div>
</template>
<script>
export default {
  name: 'Test',
  data(){
    return {
      counter: 0
    }
  },
  methods: {
    submit(){
      this.counter++;
      console.log(this.ref)
    }
  }
}
</script>

Now run this in your development server with the command:

npm run serve

You will see that the user interface displays a simple counter that gets updated on click, but when you open your developer tools in the browser, you will notice that it logs undefined.

It is very important that you get the syntax right because this means that Vue does not see this as an error, but it is. According to what we already know about Vue refs, they return an object, but judging by the undefined response, something is wrong. Copy the code below into the test.vue file:

<template>
  <div>
    <h2>Hello this is for refs man!</h2>
    <p>You have counted {{this.counter}} times</p>
    <input type="text" ref="input">
    <button @click="submit">Add 1 to counter</button>
  </div>
</template>
<script>
export default {
  name: 'Test',
  data(){
    return {
      counter: 0
    }
  },
  methods: {
    submit(){
      this.counter++;
      console.log(this.$refs)
    }
  }
}
</script>

When you run this and inspect it, you will notice that it now returns an object:

Inspecting test.vue

A quick look at the code block will reveal the correct syntax: inside the template it is called ref, but when we refer to it in the Vue instance, it is called $refs. This is very important to note so as to not get undefined returned. You can access every single possible property of the referenced element, including the element as it is in the template.

Let’s try logging some of the properties that might be of interest to us. Your test.vue file should be:

<template>
  <div>
    <h2>Hello this is for refs man!</h2>
    <p>You have counted {{this.counter}} times</p>
    <input type="text" ref="input">
    <button @click="submit">Add 1 to counter</button>
  </div>
</template>
<script>
export default {
  name: 'Test',
  data(){
    return {
      counter: 0
    }
  },
  methods: {
    submit(){
      this.counter++;
      console.log(this.$refs)
    }
  }
}
</script>
<style scoped>
p , input, button{
  font-size: 30px;
}
input, button{
  font-size: 20px;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

The application on your browser should look like this:

Test Application Running In Browser

Displaying the element

To display the HTML element as it is in the DOM, go into the submit method and change the methods code to the below:

methods: {
    submit(){
      this.counter++;
      console.log(this.$refs.input)
    }
  }

The input here is the reference name you earlier created inside the element (ref="input"). It can be any name of your choice.

Displaying the input value

To display the HTML element input value — the string that was typed into the text box in the user interface — go into the submit method and change the code to:

methods: {
    submit(){
      this.counter++;
      console.log(this.$refs.input.value)
    }
  }

This displays exactly the string you type in, which shows a similarity to query selection which vanilla JavaScript and jQuery can achieve too.

Displaying the element’s URL

The webpage in which the element can be found is also one of the many things that can be displayed with the Vue ref. Go into the submit method and change the code to this:

methods: {
    submit(){
      this.counter++;
      console.log(this.$refs.input.baseURI)
 }
}

There are many other things you can both access and log with the ref just from information on the object returned.

Handling conditionals

Vue.js refs can be also used inside elements that output more than one element in the DOM, like conditional statements where v-for directives are used. Instead of objects, refs return an array of the items when called. To illustrate this, create a simple list like this:

<template>
  <div>
    <p v-for="car in 4" v-bind:key="car" ref="car"> I am car number {{car}}</p>
    <button @click="submit">View refs</button>
  </div>
</template>
<script>
export default {
  name: 'Test',
  data(){
    return {
    }
  },
  methods: {
    submit(){
      console.log(this.$refs)
    }
  }
}
</script>

When you run it again in the development server, it will look like this:

App Preview With Conditionals

You can find the full code of this tutorial on GitHub here.

See the DOM in Vue Apps Exactly How a User Does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps – .

Conclusion

This post has exposed you to referencing HTML elements in your DOM in Vue.js. You can now both access and log these element by all the elements properties such as value, child node, data attributes, and even the base URL that houses it.

You have also been introduced to ways you can achieve this. It is important to note that refs get populated after the Vue instance has initialized and the component has been rendered, so using refs in computed properties is discouraged because it has the ability to directly manipulate child nodes. Happy hacking!

Plug: , a DVR for web apps

LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Nwose Lotanna Web Developer and Writer

Leave a Reply