条件渲染与列表渲染

条件渲染与列表渲染

  • 熟练使用 v-if / v-else / v-else-ifv-show 控制元素显隐
  • 使用 v-for 遍历数组和对象,正确设置 key
  • 理解 key 的原理与最佳实践
  • 掌握列表的增删操作(pushfilter

1. 条件渲染

1.1 v-if / v-else / v-else-if

根据条件决定元素是否存在于 DOM 中 :条件为假时元素会被销毁 ,为真时重新创建

基本用法

vue 复制代码
<script setup>
import { ref } from 'vue'
const score = ref(85)
</script>

<template>
  <p v-if="score >= 90">优秀</p>
  <p v-else-if="score >= 75">良好</p>
  <p v-else-if="score >= 60">及格</p>
  <p v-else>不及格</p>
</template>

注意

  • v-else 必须紧跟在带有 v-ifv-else-if 的元素之后,否则无效。
  • 判断规则:从上到下,命中第一个为真的条件即停止(所以条件顺序很重要,无需写冗余的范围限定)。
  • 多个元素需同时控制时,使用 <template> 包裹,v-if 写在 template 上(<template> 本身不会渲染到 DOM)。
vue 复制代码
<template v-if="isLoggedIn">
  <h2>欢迎回来</h2>
  <button>退出登录</button>
</template>

1.2 v-show

v-show 也是控制显隐,但元素始终存在于 DOM 中 ,只是通过切换 display: none 来隐藏。

vue 复制代码
<template>
  <p v-show="isVip">会员专属内容</p>
</template>

限制 :不支持 v-else,不能用在 <template> 上。

1.3 选型指南

对比维度 v-if v-show
原理 条件假时元素销毁,真时重建 元素始终在 DOM,切 display
初始渲染开销 假时无开销(不渲染) 总是渲染,初始开销略大
切换开销 销毁+重建(较重) 只改一个 CSS 属性(极轻)
适用场景 很少切换(如登录状态、权限、空状态) 频繁切换(如折叠面板、Tab页、加载中)

选型口诀很少切换用 v-if,频繁切换用 v-show

拿不准时优先 v-if(更省内存)。


2. 列表渲染

2.1 v-for 遍历数组

基本语法v-for="item in items"v-for="(item, index) in items"先 item,后 index,index 从 0 开始)

vue 复制代码
<script setup>
import { ref } from 'vue'
const menus = ref(['仪表盘', '用户管理', '订单管理'])
</script>

<template>
  <ul>
    <li v-for="(menu, index) in menus" :key="menu">
      {{ index + 1 }}. {{ menu }}
    </li>
  </ul>
</template>

数组内容变化(增删),列表自动随数据更新。

2.2 v-for 遍历对象

vue 复制代码
<script setup>
const user = ref({ name: '张伟', role: '管理员', email:'zhangwei@example.com' })
</script>

<template>
  <ul>
    <li v-for="(value, key) in user" :key="key">{{ key }}:{{ value }}</li>
  </ul>
</template>

参数顺序:(value, key, index?),一般只用前两个。

2.3 禁止 v-ifv-for 同时使用

Vue3 中 v-if 优先级高于 v-for,写在同一个元素上会导致 v-if 无法获取到 v-for 的变量而报错。

错误示例

vue 复制代码
<li v-for="menu in menus" v-if="menu !== '系统设置'">{{ menu }}</li>

正确做法 :先用 computed 过滤数据,再循环:

vue 复制代码
<script setup>
const visibleMenus = computed(() => menus.value.filter(m => m !== '系统设置'))
</script>
<template>
  <li v-for="menu in visibleMenus" :key="menu">{{ menu }}</li>
</template>

3. key 的作用与选择

3.1 为什么需要 key

key 是每个列表项的唯一标识,帮助 Vue 准确追踪每个节点的身份,从而在更新时高效复用或重建 DOM。

  • 没有 key:Vue 按位置(index)对比更新,当列表顺序改变时可能复用错误的元素(导致状态错位)。
  • 有唯一 key:Vue 能精确识别每个元素,无论顺序如何变化都能正确更新。

3.2 用 index 当 key 的陷阱

使用 :key="index" 时,如果列表中间插入或删除,新插入项的 index 会挤占原来的位置,Vue 会误以为"原来第一行的元素"还是第一行,导致内容更新但状态(如勾选、输入框内容)仍然留在原位,出现"串数据"的 bug。

原则 :只要列表会变化(增删排序),千万别用 index 作 key

3.3 正确选 key 的方法

  • 优先使用数据中唯一的业务 id (如 user.iditem.sku
  • 若无现成 id,可在新增时手动生成一个唯一 id(如自增数值)
  • 仅在列表永不变化(静态展示)时,可以用 index

4. 列表增删操作

4.1 新增:push()

js 复制代码
const users = ref([...])
const addUser = () => {
  users.value.push({
    id: nextId++,         // 保证唯一 key
    name: '赵敏',
    role: '编辑'
  })
}

push 向响应式数组尾部添加元素,页面自动出现新行。

4.2 删除:filter()

js 复制代码
const removeUser = (id) => {
  // 返回不含该 id 的新数组,替换原数组
  users.value = users.value.filter(user => user.id !== id)
}
  • filter 返回新数组 (不修改原数组),显式赋值给 users.value 触发更新。
  • 不可只写 users.value.filter(...) 而不赋值,否则原数组不变。

5. 常见问题排查

现象 可能原因 解决办法
菜单点击高亮不生效 @click:class 中使用的变量名不一致 确保 activeMenu === menu 两边完全一致
右侧内容一直不变 v-else-if 条件写错或变量名拼写错误 检查 activeMenu === 'xxx' 的匹配字符串
列表不渲染 v-for 放错位置 / 数据是空数组 v-for 写在要重复的元素上;检查数据是否为空
新增后页面没反应 漏写 .valuepush 方法调用无效 确保 users.value.push(...)
删除后列表没变 filter 后未赋值 必须写成 users.value = users.value.filter(...)
控制台报错"Cannot read properties..." v-ifv-for 在同一元素 改用 computed 先过滤
列表增删后输入框/选框串位 key 使用了 index :key="index" 改为数据的唯一 id
相关推荐
__sjfzllv___1 小时前
在职前端Leader学习/转行 AI Agent -DAY28
前端
不爱说话郭德纲1 小时前
uni-app x iOS 扫码模糊怎么办?AVFoundation 灰尘级别摄像头助你超广角聚焦
前端·uni-app·app
柒和远方1 小时前
V062:WebGPU 端侧推理与单例模式:从 Transformers.js 把大模型装进浏览器,到 Worker 线程的流式对话
前端
huabuyu1 小时前
INP 自动化归因与自愈:如何自动定位、修复并验证一次卡顿
前端·javascript
何时梦醒1 小时前
第一篇:项目概览 — 在浏览器里跑大模型,端侧 AI 的革命来了
前端·人工智能
何时梦醒1 小时前
第二篇:工程化搭建 — Vite + React + TypeScript + TailwindCSS 全解析
前端·人工智能
只一1 小时前
React 性能优化精讲:useCallback 与 useMemo 彻底吃透(附实战案例)
前端·react.js
橘子星1 小时前
浏览器也能跑大模型:WebGPU + Transformers.js 本地运行 DeepSeek-R1
前端·人工智能
用户33144195556731 小时前
Rush Monorepo 构建缓存指南
前端