Vue.js $children 按组件名称
Vue.js $children by component name
我正在尝试按名称访问特定的 child。目前,由于 child 所在的位置,我通过以下方式调用 child:
this.$root.$children[0]
只要 child 始终是 [0]
就没问题,但如果有一种方法可以执行以下操作,那就太好了:
this.$root.$children['detail']
我一直在想 $refs
可能是我的问题的答案,但永远找不到对我有帮助的方法。
有什么想法吗?
您所说的这个子组件真的是您要从中访问它的组件的子组件吗?在这种情况下,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
this.$root.$children[0].constructor.name
你可以使用这个属性:
this.$root.$children[0].$options.name
例如:
this.$root.$children.find(child => { return child.$options.name === "name"; });
您不一定需要 $refs
,事实上,如果您的组件嵌套很深,有时它们是不可行的。我在搜索时多次找到此问答,但最终决定实施我自己的解决方案,因为我 运行 经常遇到这种情况。不要对老派的 for 循环犹豫不决,它们是必要的有几个原因,其中之一,我测试 x<descendants.length
(而不是预先设置诸如 len=descendants.length
之类的东西,然后针对that) 在每次迭代中,因为我在第二个 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;
}
一切都差不多,但在 Vue 2 中你需要使用:<details ref="detailsChild"></details>
而不是 v-ref 。
然后您需要做的就是使用 this.$refs.detailsChild;
并且您可以访问它的任何属性。
我昨晚试图瞄准一些 children。我试图在输入上调用 el.focus()
。我的问题是我试图通过单击按钮触发的实例方法来执行此操作,并且输入在第 3 方库中,我将其包装在另一个组件中。
我的解决方案是在我的包装器组件上放置一个 ref
。
例如,如果您有这样的标记:
<my-dropdown ref="myDropdown"></my-dropdown>
在 my-dropdown
中,您可以将另一个 ref
放在其中一个 children 上:
<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 是按名称而不是 relative-distance 查找那些 ref-named 元素。
我的建议是将 ref="something"
放在某个东西上然后做 console.log(this.$refs.something.$refs);
看看你能看到什么,当你这样做的时候,做 console.log(this.$refs.something);
看看会发生什么那里还有其他一些东西——像 $attrs
和 $children
和 $el
.
这样的东西
var childComponent = false;
$.each(this.$root.$children,function(i,child){
if(child.$route.name === component){
childComponent = child;
}
});
如果你在路由中指定了'name'那么你可以使用这个解决方案。
我正在尝试按名称访问特定的 child。目前,由于 child 所在的位置,我通过以下方式调用 child:
this.$root.$children[0]
只要 child 始终是 [0]
就没问题,但如果有一种方法可以执行以下操作,那就太好了:
this.$root.$children['detail']
我一直在想 $refs
可能是我的问题的答案,但永远找不到对我有帮助的方法。
有什么想法吗?
您所说的这个子组件真的是您要从中访问它的组件的子组件吗?在这种情况下,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
this.$root.$children[0].constructor.name
你可以使用这个属性:
this.$root.$children[0].$options.name
例如:
this.$root.$children.find(child => { return child.$options.name === "name"; });
您不一定需要 $refs
,事实上,如果您的组件嵌套很深,有时它们是不可行的。我在搜索时多次找到此问答,但最终决定实施我自己的解决方案,因为我 运行 经常遇到这种情况。不要对老派的 for 循环犹豫不决,它们是必要的有几个原因,其中之一,我测试 x<descendants.length
(而不是预先设置诸如 len=descendants.length
之类的东西,然后针对that) 在每次迭代中,因为我在第二个 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;
}
一切都差不多,但在 Vue 2 中你需要使用:<details ref="detailsChild"></details>
而不是 v-ref 。
然后您需要做的就是使用 this.$refs.detailsChild;
并且您可以访问它的任何属性。
我昨晚试图瞄准一些 children。我试图在输入上调用 el.focus()
。我的问题是我试图通过单击按钮触发的实例方法来执行此操作,并且输入在第 3 方库中,我将其包装在另一个组件中。
我的解决方案是在我的包装器组件上放置一个 ref
。
例如,如果您有这样的标记:
<my-dropdown ref="myDropdown"></my-dropdown>
在 my-dropdown
中,您可以将另一个 ref
放在其中一个 children 上:
<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 是按名称而不是 relative-distance 查找那些 ref-named 元素。
我的建议是将 ref="something"
放在某个东西上然后做 console.log(this.$refs.something.$refs);
看看你能看到什么,当你这样做的时候,做 console.log(this.$refs.something);
看看会发生什么那里还有其他一些东西——像 $attrs
和 $children
和 $el
.
var childComponent = false;
$.each(this.$root.$children,function(i,child){
if(child.$route.name === component){
childComponent = child;
}
});
如果你在路由中指定了'name'那么你可以使用这个解决方案。