Vue.js如何在组件内获取元素

156

我有一个组件,如何选择其中的元素?

我想获取该组件模板内的一个输入框。

可能会有多个组件,因此 querySelector 必须仅解析当前组件实例。

Vue.component('somecomponent', {
    template: '#somecomponent',
    props: [...],

   ...

    created: function() {
        somevariablehere.querySelector('input').focus();
    }
});
6个回答

187

Vue.js 2

v-el:el:uniquename已被替换为ref="uniqueName"。然后可以通过this.$refs.uniqueName访问该元素。


1
这让我意识到ref属性适用于任何HTML元素或Vue组件。不错的东西。 - C. Bess
4
看起来 $refs.uniqueName 是一个数组,因此您需要使用 this.$refs.uniqueName[0] 来获取引用的元素。 - Nicolas S.Xu
只有在挂载组件之后才能完成,这可以在父组件的mounted方法中完成:https://medium.com/@brockreece/vue-parent-and-child-lifecycle-hooks-5d6236bd561f - Yordan Georgiev
为什么它被标记为vuejs 2?它同样适用于vue.js 3。 - Passiv Programmer
@PassivProgrammer 因为如果你正在使用组合 API / Vue 3 最佳实践,你将无法访问 this.$refs(它是空的)。 - Aj Otto

152

根据您要访问的内容,有几个选项:

  • 使用this.$children可以访问Vue.js组件的子组件。

  • 您可以在模板中使用ref="uniqueName"标记特定的DOM元素,并稍后通过this.$refs.uniqueName引用它们。
    (但请记住,在组件/应用程序完成挂载并执行初始渲染之前,您将无法引用这些元素。)

  • 如果无法标记元素,则可以通过CSS选择器使用this.$el.querySelector('.myClass > .childElement')查询子元素的DOM。
    (如上所述,组件/应用程序需要完成挂载

您还可以通过在组件内部执行简单的console.log(this)来探索,它将显示Vue组件实例的所有属性。


9
提示:只有在挂载后,this.$el 才有定义。如果您想初始化一个变量,请在 mount() 中进行。 - wedi

60

答案并不是很清晰:

使用 this.$refs.someName,但是在使用之前,你必须在父组件中添加 ref="someName"

参见下面的演示。

new Vue({
  el: '#app',
  mounted: function() {
    var childSpanClassAttr = this.$refs.someName.getAttribute('class');
    
    console.log('<span> was declared with "class" attr -->', childSpanClassAttr);
  }
})
<script src="https://unpkg.com/vue@2.5.13/dist/vue.min.js"></script>

<div id="app">
  Parent.
  <span ref="someName" class="abc jkl xyz">Child Span</span>
</div>

$refsv-for

请注意,当与v-for一起使用时,this.$refs.someName将变成一个数组:

new Vue({
  el: '#app',
  data: {
    ages: [11, 22, 33]
  },
  mounted: function() {
    console.log("<span> one's text....:", this.$refs.mySpan[0].innerText);
    console.log("<span> two's text....:", this.$refs.mySpan[1].innerText);
    console.log("<span> three's text..:", this.$refs.mySpan[2].innerText);
  }
})
span { display: inline-block; border: 1px solid red; }
<script src="https://unpkg.com/vue@2.5.13/dist/vue.min.js"></script>

<div id="app">
  Parent.
  <div v-for="age in ages">
    <span ref="mySpan">Age is {{ age }}</span>
  </div>
</div>


1
还需要注意的是,引用的项目不是响应式的。 - Pithikos

42

Vue2 中,请注意只有在组件挂载后才能访问 this.$refs.uniqueName


2
在Vue的生命周期中,mounted之前的所有内容都不会在浏览器中呈现。因为它还没有被挂载,所以没有DOM可供检查。 - Coreus

7

6

组合式 API

模板引用 部分介绍了如何进行统一:

  • 在模板内使用 ref="myEl"; 当使用 v-for 时,使用 :ref=
  • 在 script 中使用 const myEl = ref(null) 并从 setup 暴露它

该引用将从挂载开始携带 DOM 元素。


执行像 document.querySelectorAll("nav > ul > li"); 这样的查询不可行吗? - user74091
不,不是这样的。但是你应该从文档根节点开始查询。由于你正在创建一个组件,所以它应该从组件内的节点开始。 - akauppi
好的,类似于<header ref="headerEL">这样的东西,其中header是nav的父元素,然后const headerEl = ref<HTMLElement>(),然后你可以做const links = headerEl.value.querySelectorAll('nav > ul > li') - user74091
(提示)在调用myEl之前添加await nextTick();以确保组件完全渲染。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接