While accessing the DOM in Vue.js is generally not recommended, there are times when you need to. Vue provides 2 main methods for DOM access: Custom Directives and refs, which is what we will be looking at here. If you are new to refs then they simply provide a way to access a DOM object from your view model:

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

<script type="text/javascript">
export default{
  mounted(){
    // focus input
    this.$refs.input.focus();
  }
}
</script>

Here we are using a “ref” to focus our input. As you can see refs are available in the view model via this.$refs, which you can check out in this JSFiddle

While that is useful, refs also allow you to access a component’s view model directly, which means it’s possible to place a “ref” on any custom component and use it to affect the state, without having to extend the component or adjust the source code.

In the following example, I have a component which shows and hides the input value on focus and blur events respectively. The component doesn’t give me any way to directly change the show/hide state from the parent, so I have added a “ref” which allows me to change the state via a toggle button placed in the parent:

My-Input Component

<template>
  <div>
    <input type="text" @focus="show" @blur="hide" v-model="value">
    <div v-show="showValue">
      {{value}}
    </div>
  </div>
</template>

<script type="text/javascript">
export default{
  methods: {
    show() {
        this.showValue = true;
      },
      hide() {
        this.showValue = false;
      }
  },
  data() {
    return {
      value: 'foo',
      showValue: false
    }
  }
}
</script>

Parent

<template>
  <div>
    <my-input ref="input"></my-input>
    <button @click="toggle">Toggle</button>
  </div>
</template>

<script type="text/javascript">
import MyInput from './my-input.vue'

export default{
  components:{
    MyInput
  },
  methods: {
    toggle() {
      if (this.$refs.input.showValue) {
        this.$refs.input.hide();
      } else {
        this.$refs.input.show();
      }
    }
  }
}
</script>

As you can see, I’ve added a “ref” to the my-input custom component, which I am using to access the show() and hide() methods when the toggle button is clicked. You may also note that I am accessing the showValue data property so I know the current show/hide state. You can see this in action in this JSFiddle

While this example may be a little contrived, this method of accessing a component view model from the parent can be useful when you want to affect the state of a component but changing the source code is not possible (i.e. when using components published on NPM). A final word of warning though, use this method sparingly, and only when you don’t have any other real options, otherwise you could find yourself getting in to a real mess.

Advertisements