按组件名称的Vue.js $ children

时间:2016-03-03 10:12:47

标签: javascript vue.js web-frameworks

我正在尝试按名称访问特定的孩子。目前,由于孩子在哪里,我正在这样叫孩子:

this.$root.$children[0]

只要这个孩子总是[0],这是可以的,但如果有办法可以做到这样的事情会很好:

this.$root.$children['detail']

我一直在想$refs可能是我问题的答案,但却无法找到帮助我的方法。

有什么想法吗?

7 个答案:

答案 0 :(得分:28)

您正在谈论的这个孩子真的是您要从中访问它的组件的孩子吗?在这种情况下,v-ref确实是答案:

// in the code of the parent component, access the referenced child component like this:

this.$refs.detailsChild
<!-- Template of the parent component, assuming your child Component is called Details -->
<details v-ref:details-child></details>

相关API文档:http://vuejs.org/api/#v-ref

答案 1 :(得分:18)

您可以使用此属性:

this.$root.$children[0].$options.name

例如:

this.$root.$children.find(child => { return child.$options.name === "name"; });

答案 2 :(得分:2)

所有内容几乎相同,但是在Vue 2中,您需要使用:<details ref="details-child"></details>而不是v-ref。

那么您只需使用this.$refs.details-child;,您就可以访问其任何属性。

答案 3 :(得分:1)

this.$root.$children[0].constructor.name

答案 4 :(得分:0)

您不一定需要$refs,事实上,如果您有深层嵌套的组件,有时它们是不可行的。我在搜索时已经多次发现这个Q&amp; A,但最后我决定实施自己的解决方案,因为我经常遇到这种情况。不要为了旧学校的循环而烦恼,因为有几个原因它们是必要的,其中一个,我测试x<descendants.length(而不是预先设置诸如len=descendants.length之类的东西,以及因为我在第二个for循环中推进堆栈,所以在每次迭代时都会对此进行测试。

首先,用法:

let unPersonalizable = matchingDescendants(this, /a.checkimprintfiinformation$/, {first: true});

实现:

function matchingDescendants(vm, matcher, options) {
    let descendants = vm.$children;
    let descendant;
    let returnFirst = (options || {}).first;
    let matches = [];

    for (let x=0; x<descendants.length; x++) {
        descendant = descendants[x];

        if (matcher.test(descendant.$vnode.tag)) {
            if (returnFirst) {
                return descendant;
            }
            else {
                matches.push(descendant);
            }
        }

        for (let y=0, len = descendant.$children.length; y<len; y++) {
            descendants.push(descendant.$children[y]);
        }    
    }

    return matches.length === 0 ? false : matches;
}

答案 5 :(得分:0)

昨晚我试图针对一些孩子。我试图在输入上调用el.focus()。我的问题是,我试图通过单击按钮后触发的实例方法来执行此操作,而输入在第3方库中,然后将其包装在另一个组件中。

对我来说,解决方案是在包装器组件上放置一个ref

例如,如果您具有这样的标记:

<my-dropdown ref="myDropdown"></my-dropdown>

my-dropdown内,您可以在其中一个子项上放置另一个ref

<template>
    <div>
        <my-library-wrapper ref="libWrapper"></my-library-wrapper>
    </div>
</template>

my-library-wrapper内,您可以从具有引用的node_modules导入库。大多数库都将引用放在事物上,因此您可以使用它们来定位它们。

现在,您可以使用以下代码在此处定位示例组件:

 console.log(this.$refs.myDropdown);

 console.log(this.$refs.myDropdown.$refs);

 console.log(this.$refs.myDropdown.$refs.libWrapper);

 this.$refs.myDropdown.$refs.libWrapper.$refs.someThing.focus();
 this.$refs.myDropdown.$refs.libWrapper.$refs.someThing.click();

乍看之下,这似乎很奇怪,但是与this.$refs.myDropdown.$children[0].$children[1].focus();之类的东西相比,这样做的好处是refs的脆性要小得多。如果您或其他人以后将<divs>添加到标记中,则使用refs的代码不会中断,因为Vue会按名称而不是相对距离来查找那些引用命名的元素。

我的建议是将ref="something"放在某物上,然后做console.log(this.$refs.something.$refs);,看一看您所看到的,然后,一边做console.log(this.$refs.something);,然后再看一下那里还有其他东西-例如$attrs$children$el

答案 6 :(得分:0)

<div class="root">
  <div class="strip">strip</div>
  <div class="main">
    <div class="header">header</div>
    <div class="gallery">gallery</div>
    <div class="list">
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
      <div class="list-item">
        <h1>Item</h1>
      </div>
    </div>
  </div>
</div>

如果您在路由中指定了“名称”,则可以使用此解决方案。