Debug School

rakesh kumar
rakesh kumar

Posted on

Role of refs in Vue

understanding-vue-refs
vue-template-refs
How to get $refs using Composition API in Vue3?
use-ref-to-load-data-from-child-component-and-put-into-parent-components
proper-use-of-vue-refs

QUESTION

How to get $refs using Composition API in Vue3
How to get $refs using Composition API in Vue3?
use-ref-to-load-data-from-child-component-and-put-into-parent-components
use-ref-to-load-data-from-child-component-and-put-into-parent-components

VIDEO

Ref with Interview question

Image description

Equivalent to

Image description

this.$refs["input"].focus()
Enter fullscreen mode Exit fullscreen mode

Image description

output
before onclick
Image description
after onclick

Image description
Displaying HTML elements

Image description

Image description

** Setting style**
Image description

Image description

What are refs in Vue.js?

understanding-vue-refs
Refs are Vue.js instance properties that are 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; it is a read-only attribute and returns an object.

getElementById in Vue.js
The use of JavaScript’s getElementById is not encouraged in Vue, as it creates performance issues. Vue’s ref helps you “reference” DOM elements in a more efficient way.

How to use refs in Vue.js
The ref attribute makes a DOM element selectable by serving as the key in the parent $ref attribute.

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"].

For a quick visual guide on referencing with $refs in Vue.js, check out this video tutorial.

this.refs in Vue
You can manipulate a DOM element by defining methods on the element’s reference. For example, you could focus on an input element with this:

this.$refs["input"].focus()
Enter fullscreen mode Exit fullscreen mode

In this way, refs can be used just like the document.querySelector('.element') in JavaScript or the $('.element') in jQuery. While document.querySelector() performs some of the functions of refs, refs are more efficient, because they give you direct access to the specific element you need. On the other hand, document.querySelector() simply returns the first element in your DOM that matches the selector you specified. 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, $refs do not show up at all because it is not an HTML attribute; it is only a Vue template attribute.

How Vue.js refs work
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>
Enter fullscreen mode Exit fullscreen mode

Now run this in your development server with the command:

npm run serve
Vue $refs
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>
Enter fullscreen mode Exit fullscreen mode

Image description

Getting DOM elements in Vue.js
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>
Enter fullscreen mode Exit fullscreen mode

The application on your browser should look like this:

Image description

Displaying HTML elements in Vue.js
To display the HTML element as it is in the DOM, go into the submit method and change the methods code to the following:

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

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

Displaying the HTML 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)
    }
  }
Enter fullscreen mode Exit fullscreen mode

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

Displaying a Vue 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)
 }
}
Enter fullscreen mode Exit fullscreen mode

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

Handling conditionals in Vue.js
Vue.js refs can also be 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>
Enter fullscreen mode Exit fullscreen mode

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

Image description
** Watching refs in Vue**
Say you want to react to a change in a DOM element, like triggering a function when the value of an element changes. You can set up a watcher for this.

Below, we have a simple component with data:

const Name = {
  data: () => ({
    myName: "Sam"
  }),
}
Enter fullscreen mode Exit fullscreen mode

We create the watcher inside the mounted hook so that it only takes effect after the component has been rendered. We use the $watch() instance method to watch for changes in the component’s data, myName. When the value changes, the console.log function is triggered.

<template>
  <div>
    <name ref="name" /> 
  </div>
</template>

<script>
export default {
  //...
  components: { Name },
  mounted() {
    this.$watch(
      () => {
        return this.$refs.name.myName;
      },
      (val) => {
        console.log(val);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)