Vue.js $children 按组件名称

Posted

技术标签:

【中文标题】Vue.js $children 按组件名称【英文标题】:Vue.js $children by component name 【发布时间】:2016-06-16 14:23:37 【问题描述】:

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

this.$root.$children[0]

只要那个孩子总是[0] 就可以了,但是如果有办法做这样的事情那就太好了:

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

我一直在想$refs 可能是我的问题的答案,但始终找不到对我有帮助的方法。

有什么想法吗?

【问题讨论】:

【参考方案1】:

您所说的这个孩子真的是您想要访问它的组件的孩子吗?在这种情况下,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

【讨论】:

对于使用 Vue v2 的人,您可以在模板中设置 ref 属性,如下所示:&lt;details ref="detailsChild"&gt;&lt;/details&gt;。 vuejs.org/v2/api/#ref【参考方案2】:
this.$root.$children[0].constructor.name

【讨论】:

请编辑更多信息。不建议使用纯代码和“试试这个”的答案,因为它们不包含可搜索的内容,也没有解释为什么有人应该“试试这个”。【参考方案3】:

你可以使用这个属性:

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

例如:

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

【讨论】:

这只是访问$children数组中第一个组件的名称,这不是OP所要求的。 怎么样?您的一行代码正在访问数组中第一个元素的名称。您还没有解释如何使用这行代码来解决 OP 的问题。 您可以使用 find:this.$root.$children.find(child =&gt; return child.$options.name === "name"; );。我会更新答案。 按组件名称选择子组件:this.$root.$children.find(child =&gt; return child.$options._componentTag === "tabs-component"; ); 我认为对于这个,你需要像这样为你的孩子添加变量名。export default name: ''【参考方案4】:

你不一定需要$refs,事实上,如果你有深度嵌套的组件,它们有时是不可行的。我在搜索时多次找到此问答,但由于我经常遇到这种情况,最终决定实施我自己的解决方案。不要对老派的 for 循环犹豫不决,它们是必要的,有几个原因,其中一个原因是,我在每迭代,因为我在第二个 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】:

一切都差不多,但在 Vue 2 中你需要使用:&lt;details ref="detailsChild"&gt;&lt;/details&gt; 而不是 v-ref 。

那么你需要做的就是使用this.$refs.detailsChild;,你可以访问它的任何属性。

【讨论】:

建议编辑 detailsChild 以修复 javascript 语法。或者使用this.$refs["details-child"](假设 vue 支持)【参考方案6】:

我昨晚试图针对一些孩子。我试图在输入时调用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 的脆弱性要小得多。如果您或其他人稍后将 &lt;divs&gt; 添加到标记中,则使用 refs 的代码不会中断,因为 Vue 是通过名称而不是相对距离来查找那些引用命名的元素。

我的建议是把ref="something" 放在某事上,然后做console.log(this.$refs.something.$refs); 看看你能看到什么,当你这样做的时候,做console.log(this.$refs.something); 看看那里还有哪些其他可用的东西-- 像$attrs$children$el 这样的东西。

【讨论】:

【参考方案7】:
var childComponent = false; 
$.each(this.$root.$children,function(i,child)       
   if(child.$route.name === component)             
      childComponent = child;        
     
);

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

【讨论】:

以上是关于Vue.js $children 按组件名称的主要内容,如果未能解决你的问题,请参考以下文章

在 vue.js 组件中反应 this.props.children

vue.js学习笔记七

vue.js学习笔记七

vue.js学习笔记七

在 vue.js 组件中渲染子组件

459 vue使用$root$parent$children进行父子组件通信