Skip to content

Vue与微信小程序中key的区别及踩坑记录

背景

在uniapp开发微信小程序过程中,遇到了组件刷新相关的问题,特此记录Vue和微信小程序中key属性的区别以及解决方案。

Vue中的key

作用机制

key 这个特殊的 attribute 主要作为 Vue 的虚拟 DOM 算法提示,在比较新旧节点列表时用于识别 vnode。

工作原理

  • 无key情况:Vue 将使用一种最小化元素移动的算法,并尽可能地就地更新/复用相同类型的元素
  • 有key情况:将根据 key 的变化顺序来重新排列元素,并且将始终移除/销毁 key 已经不存在的元素

使用要求

同一个父元素下的子元素必须具有唯一的 key。重复的 key 将会导致渲染异常。

特殊用途

也可以用于强制替换一个元素/组件而不是复用它,在以下场景很有用:

  • 在适当的时候触发组件的生命周期钩子
  • 触发过渡

示例代码

vue
<transition>
  <span :key="text">{{ text }}</span>
</transition>

当 text 变化时,<span> 总是会被替换而不是更新,因此 transition 将会被触发。

参考文档

Vue官方文档 - 通过key管理状态

微信小程序中的wx:key

作用机制

如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。

取值方式

wx:key 的值以两种形式提供:

  1. 字符串形式:代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变
  2. 保留关键字 *this:代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字

工作机制

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

注意事项

如不提供 wx:key,会报一个 warning。如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。

参考文档

微信小程序官方文档 - wx:key

踩坑总结

核心问题

在uniapp开发微信小程序过程中,发现组件刷新存在以下限制:

  1. key的使用限制:微信小程序中,key需要搭配v-for使用才能触发组件的重新渲染
  2. v-if的局限性v-if只能刷新本页面非slot之外的标签,对于slot内的内容无法有效刷新

解决方案

  • 对于动态列表,务必添加wx:key属性
  • 对于需要强制刷新的组件,考虑使用key的变化来触发重新渲染
  • 避免过度依赖v-if来控制组件刷新,特别是在包含slot的场景下

最佳实践

  1. 动态列表必须添加唯一的key
  2. 静态列表可以忽略key的warning
  3. 需要强制刷新组件时,可以通过改变key值实现
  4. 谨慎使用v-if来控制包含slot的组件显示

Released under the MIT License.