javascript v-for 循环中的 Vue.js 引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52086128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Vue.js ref inside the v-for loop
提问by Lev Khruschev
I tried to use components inside v-forloop and init the refto future access some methods of these from parent. Here a simplified code of my case:
我尝试在v-for循环内使用组件并初始化ref以将来从父级访问这些方法的某些方法。这是我的案例的简化代码:
<template>
<div class="hello">
{{ msg }}
<ul>
<list-item
v-for="item in items"
:key="item.id"
:value="item.text"
:ref="`item${item.id}`"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
name: "HelloWorld",
components: {
ListItem
},
data() {
return {
msg: "Welcome to Your Vue.js App",
items: [
{ id: 1, text: "foo" },
{ id: 2, text: "bar" },
{ id: 3, text: "baz" },
{ id: 4, text: "foobar" }
]
};
},
mounted() {
setTimeout(() => this.$refs.item2.highlight(), 1500);
}
};
</script>
And ListItemcomponent:
和ListItem组件:
<template>
<li v-bind:class="{ highlight: isHighlighted }">
{{value}}
</li>
</template>
<script>
export default {
name: "list-item",
props: ["value"],
data() {
return {
isHighlighted: false
};
},
methods: {
highlight() {
this.isHighlighted = !this.isHighlighted;
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.highlight {
color: red;
}
</style>
It's just renders a few list items and highlights one of them after one and half second. But I got an error: Uncaught TypeError: _this.$refs.item2.highlight is not a function
After debug session I've found an interesting fact: refs defined inside v-forloop are not a components but the arrays with one component.
What is the logic, what is the f wrapper? Does anyone meet this case? Can somebody give the explanation of this behaviour?
Code presented above works fine with setTimeout(() => this.$refs.item2[0].highlight(), 1500);
Must I always pass [0]? Is there exist a better way? Help, please.
它只是渲染一些列表项并在一秒半后突出显示其中的一个。但是我遇到了一个错误:Uncaught TypeError: _this.$refs.item2.highlight is not a function
在调试会话之后,我发现了一个有趣的事实:在v-for循环内定义的引用不是组件,而是具有一个组件的数组。
什么是逻辑,什么是 f 包装器?有人遇到过这种情况吗?有人可以解释这种行为吗?
上面提供的代码在setTimeout(() => this.$refs.item2[0].highlight(), 1500);
Must I always pass 中可以正常工作[0]吗?有没有更好的方法?请帮忙。
回答by Sagar Chakravarthy
When using refs with v-for, the component / DOM nodes are stored as an array directly to the variable name so you don't need to use index number in the ref name. So you can do this:
将 refs 与 v-for 一起使用时,组件/DOM 节点将作为数组直接存储到变量名称,因此您无需在 ref 名称中使用索引号。所以你可以这样做:
<list-item
v-for="item in items"
:key="item.id"
:value="item.text"
ref="items"
/>
And use the refs in your component like this:
并在您的组件中使用 refs,如下所示:
this.$refs.items[index]
Also note that the refs may not be in order and would need to be handled in a different way which is a completely different issue. You can follow that here: https://github.com/vuejs/vue/issues/4952
另请注意,参考文献可能不按顺序排列,需要以不同的方式处理,这是一个完全不同的问题。你可以在这里关注:https: //github.com/vuejs/vue/issues/4952
回答by u6785157
I had faced the same issue.
我遇到了同样的问题。
As sobolevon mentioned, the returning value of $refs.{ref name}is an array in v-for refs, so my solution is to consider $refs.{ref name}is an array with one item only by default, and write $refs.{ref name}[0].methodToCall().
正如 sobolevon 提到的, 的返回值$refs.{ref name}是 v-for refs 中的一个数组,所以我的解决方案是考虑$refs.{ref name}一个默认只有一个项目的数组,并写入$refs.{ref name}[0].methodToCall().
And it works for my case.
它适用于我的情况。
回答by sobolevn
Considering your primary question: https://vuejs.org/v2/api/#ref
考虑您的主要问题:https: //vuejs.org/v2/api/#ref
The documentation says:
文档说:
When ref is used together with v-for, the ref you get will be an array containing the child components mirroring the data source.
当 ref 与 v-for 一起使用时,您得到的 ref 将是一个包含镜像数据源的子组件的数组。
But, I would say you are doing it wrong, because using refsare not a good way to go. We have very useful alternatives in vue-land. For example, one can use a prop.
但是,我会说你做错了,因为使用refs不是一个好方法。我们在vue-land 中有非常有用的替代品。例如,可以使用prop.
That's how a rewritten version of your code would look like:
这就是代码的重写版本的样子:
<template>
<div class="hello">
{{ msg }}
<ul>
<list-item
v-for="item in items"
:key="item.id"
:value="item.text"
:isHighlighed="item.isHighlighed"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
name: "HelloWorld",
components: {
ListItem
},
data() {
return {
msg: "Welcome to Your Vue.js App",
items: [
// We have moved `isHighlighed` falg into the data array:
{ id: 1, text: "foo", isHighlighed: false },
{ id: 2, text: "bar", isHighlighed: true },
{ id: 3, text: "baz", isHighlighed: false },
{ id: 4, text: "foobar", isHighlighed: false }
]
};
};
};
</script>
And then change your component definition to receive a new prop:
然后更改您的组件定义以接收新的prop:
<script>
export default {
name: "list-item",
props: ["value", "isHighlighted"]
};
</script>
This will solve your issue.
这将解决您的问题。

