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 将会被触发。
参考文档
微信小程序中的wx:key
作用机制
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key
来指定列表中项目的唯一的标识符。
取值方式
wx:key
的值以两种形式提供:
- 字符串形式:代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变
- 保留关键字
*this
:代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字
工作机制
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
注意事项
如不提供 wx:key
,会报一个 warning。如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
参考文档
踩坑总结
核心问题
在uniapp开发微信小程序过程中,发现组件刷新存在以下限制:
- key的使用限制:微信小程序中,key需要搭配
v-for
使用才能触发组件的重新渲染 - v-if的局限性:
v-if
只能刷新本页面非slot之外的标签,对于slot内的内容无法有效刷新
解决方案
- 对于动态列表,务必添加
wx:key
属性 - 对于需要强制刷新的组件,考虑使用key的变化来触发重新渲染
- 避免过度依赖v-if来控制组件刷新,特别是在包含slot的场景下
最佳实践
- 动态列表必须添加唯一的key
- 静态列表可以忽略key的warning
- 需要强制刷新组件时,可以通过改变key值实现
- 谨慎使用v-if来控制包含slot的组件显示