条件渲染与列表渲染 📅 2026/8/10 11:23:09 条件渲染与列表渲染熟练使用v-if/v-else/v-else-if与v-show控制元素显隐使用v-for遍历数组和对象正确设置key理解key的原理与最佳实践掌握列表的增删操作push、filter1. 条件渲染1.1v-if/v-else/v-else-if根据条件决定元素是否存在于 DOM 中条件为假时元素会被销毁为真时重新创建。基本用法script setup import { ref } from vue const score ref(85) /script template p v-ifscore 90优秀/p p v-else-ifscore 75良好/p p v-else-ifscore 60及格/p p v-else不及格/p /template注意v-else必须紧跟在带有v-if或v-else-if的元素之后否则无效。判断规则从上到下命中第一个为真的条件即停止所以条件顺序很重要无需写冗余的范围限定。多个元素需同时控制时使用template包裹v-if写在template上template本身不会渲染到 DOM。template v-ifisLoggedIn h2欢迎回来/h2 button退出登录/button /template1.2v-showv-show也是控制显隐但元素始终存在于 DOM 中只是通过切换display: none来隐藏。template p v-showisVip会员专属内容/p /template限制不支持v-else不能用在template上。1.3 选型指南对比维度v-ifv-show原理条件假时元素销毁真时重建元素始终在 DOM切display初始渲染开销假时无开销不渲染总是渲染初始开销略大切换开销销毁重建较重只改一个 CSS 属性极轻适用场景很少切换如登录状态、权限、空状态频繁切换如折叠面板、Tab页、加载中选型口诀很少切换用v-if频繁切换用v-show。拿不准时优先v-if更省内存。2. 列表渲染2.1v-for遍历数组基本语法v-foritem in items或v-for(item, index) in items先 item后 indexindex 从 0 开始script setup import { ref } from vue const menus ref([仪表盘, 用户管理, 订单管理]) /script template ul li v-for(menu, index) in menus :keymenu {{ index 1 }}. {{ menu }} /li /ul /template数组内容变化增删列表自动随数据更新。2.2v-for遍历对象script setup const user ref({ name: 张伟, role: 管理员, email:zhangweiexample.com }) /script template ul li v-for(value, key) in user :keykey{{ key }}{{ value }}/li /ul /template参数顺序(value, key, index?)一般只用前两个。2.3 禁止v-if与v-for同时使用Vue3 中v-if优先级高于v-for写在同一个元素上会导致v-if无法获取到v-for的变量而报错。错误示例li v-formenu in menus v-ifmenu ! 系统设置{{ menu }}/li正确做法先用computed过滤数据再循环script setup const visibleMenus computed(() menus.value.filter(m m ! 系统设置)) /script template li v-formenu in visibleMenus :keymenu{{ menu }}/li /template3.key的作用与选择3.1 为什么需要keykey是每个列表项的唯一标识帮助 Vue 准确追踪每个节点的身份从而在更新时高效复用或重建 DOM。没有 keyVue 按位置index对比更新当列表顺序改变时可能复用错误的元素导致状态错位。有唯一 keyVue 能精确识别每个元素无论顺序如何变化都能正确更新。3.2 用index当 key 的陷阱使用:keyindex时如果列表中间插入或删除新插入项的 index 会挤占原来的位置Vue 会误以为“原来第一行的元素”还是第一行导致内容更新但状态如勾选、输入框内容仍然留在原位出现“串数据”的 bug。原则只要列表会变化增删排序千万别用 index 作 key。3.3 正确选 key 的方法优先使用数据中唯一的业务 id如user.id、item.sku若无现成 id可在新增时手动生成一个唯一 id如自增数值仅在列表永不变化静态展示时可以用 index4. 列表增删操作4.1 新增push()constusersref([...])constaddUser(){users.value.push({id:nextId,// 保证唯一 keyname:赵敏,role:编辑})}push向响应式数组尾部添加元素页面自动出现新行。4.2 删除filter()constremoveUser(id){// 返回不含该 id 的新数组替换原数组users.valueusers.value.filter(useruser.id!id)}filter返回新数组不修改原数组显式赋值给users.value触发更新。不可只写users.value.filter(...)而不赋值否则原数组不变。5. 常见问题排查现象可能原因解决办法菜单点击高亮不生效click与:class中使用的变量名不一致确保activeMenu menu两边完全一致右侧内容一直不变v-else-if条件写错或变量名拼写错误检查activeMenu xxx的匹配字符串列表不渲染v-for放错位置 / 数据是空数组v-for写在要重复的元素上检查数据是否为空新增后页面没反应漏写.value或push方法调用无效确保users.value.push(...)删除后列表没变filter后未赋值必须写成users.value users.value.filter(...)控制台报错“Cannot read properties…”v-if和v-for在同一元素改用 computed 先过滤列表增删后输入框/选框串位key使用了index把:keyindex改为数据的唯一 id