我有一个小的 Vue.js 组件,它显示最喜欢的星形图标。单击图标收藏/取消收藏该元素。到目前为止,我只实现了 UI 部分,如下所示:
<template>
<div :key="favorite">
<a v-on:click="toggleFavorite" style="cursor: pointer">
<i v-show="favorite" class="text-warning fas fa-star"></i>
<i v-show="!favorite" class="text-warning far fa-star"></i>
</a>
</div>
</template>
<script>
export default {
data() {
return {
favorite: true,
}
},
mounted() {
},
methods: {
toggleFavorite() {
this.favorite = !this.favorite
}
},
props: ['team-id'],
}
</script>
<style scoped>
</style>
如您所见,逻辑非常简单。
这很好用,但是让我困扰的一件事是,如果我从我的模板中删除 :key
属性,当我点击它时图标不会更新(即使我已经检查过基础属性是确实更新正确)。添加 :key
使其工作,我想是因为它强制 Vue.js 在 favorite
更新时完全重新渲染组件。
为什么会这样?我对 JS 框架的世界相当陌生,所以请原谅我可能遗漏的任何明显的东西。我在网上做了一些研究,但找不到解释。我只是想确保我以正确的方式做事,而不仅仅是解决这里的问题。
最佳答案
Vue 在必要时使用虚拟 DOM 修补。也就是说,每当 vue 检测到 DOM 上的更改时,它都会对其进行修补以提高性能。并且在 DOM 中打补丁不会改变图标或图像。您需要替换 DOM。
因此,vue 为我们提供了每当我们需要通过替换方法更改 DOM 的方式时,我们可以使用 :key
绑定(bind)。
因此,:key
绑定(bind)可用于强制替换元素/组件而不是重用它。
只要 favorite
数据发生变化,下面的整个 html div 就会被替换,因为我们在其上绑定(bind)了 :key
:
<div :key="favorite">
<a v-on:click="toggleFavorite" style="cursor: pointer">
<i v-show="favorite" class="text-warning fas fa-star"></i>
<i v-show="!favorite" class="text-warning far fa-star"></i>
</a>
</div>
这就是为什么 vue 强制允许我们在循环内使用 :key
绑定(bind),因为每当它检测到 data
中的更改时,都需要替换循环内的元素.这是从 2.2.0+
开始强制执行的,ESLint 也实现了此功能,因此如果您在循环中错过了 :key
绑定(bind),那么您将看到错误当你使用支持 eslint 的编辑器时,该行,以便你可以修复错误。
只是一个意见,应该从 vue 中删除 :key
绑定(bind)的严格要求,因为我们可能想要一个 predefined data
的循环,但不想更改 DOM 但我们仍然使用 v-for
循环来列出更大的数据。但这种情况可能很少见。
仔细阅读documentation for :key binding然后你就会有一个想法。
:key
绑定(bind)在您想要:
Properly trigger lifecycle hooks of a component
Trigger transitions
- 使用
:key
绑定(bind)来替换 DOM。请记住它会降低性能,因为它会替换绑定(bind)到元素的整个 DOM。 - 当你不想替换 DOM 或
您认为不需要检测
data
更改。这将 让 vue 在没有:key
绑定(bind)的情况下表现更好。
关于vue.js - 为什么我的 Vue 组件需要 :key?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48931387/