MarredCheese
MarredCheese

Reputation: 20791

Vue: Why can't I use refs within component templates?

I'm struggling with Vue refs. If I define them in my main Vue instance's template, they work fine, but if I define them within a component template, they don't. What am I doing wrong?

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
</head>
<body>
  <div id="app"></div>
  <script src="main.js"></script>
</body>
</html>

main.js, version 1

const app = new Vue({
  el: '#app',
  template: `
    <div ref="divRef">
      <button ref="buttonRef">Submit</button>
    </div>
  `
});

result (matches expectation)

> app.$refs
> {buttonRef: button, divRef: div}

main.js, version 2

Vue.component('demo-page', {
  template: `
    <div ref="divRef">
      <button ref="buttonRef">Submit</button>
    </div>
  `
});

const app = new Vue({
  el: '#app',
  template: '<demo-page ref="componentRef"></demo-page>'
});

expected result

> app.$refs
> {componentRef: VueComponent, buttonRef: button, divRef: div}

actual result

> app.$refs
> {componentRef: VueComponent}

Upvotes: 1

Views: 2904

Answers (1)

ssc-hrep3
ssc-hrep3

Reputation: 16069

$refs are scoped within a component. That's the reason, you can only see the componentRef in the $refs of the app itself. The other $refs are accessible within the scope of each component. So, try to access the $refs within the scope of that component.

If you are defining a ref on an element also having the attribute v-for on it, this.$refs.refName will return you an array of DOM elements. Keep in mind that $refs are not reactive unlike data properties.

See also the documentation to $refs with child component instances and the documentation to the ref="" attribute.

Upvotes: 2

Related Questions