gpt4 book ai didi

vue.js - 为什么我的 Vue 组件需要 :key?

转载 作者:搜寻专家 更新时间:2023-10-30 22:11:32 26 4
gpt4 key购买 nike

我有一个小的 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


  1. 使用 :key 绑定(bind)来替换 DOM。请记住它会降低性能,因为它会替换绑定(bind)到元素的整个 DOM。
  2. 当你不想替换 DOM 或您认为不需要检测 data 更改。这将让 vue 在没有 :key 绑定(bind)的情况下表现更好。

关于vue.js - 为什么我的 Vue 组件需要 :key?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48931387/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com