条件渲染与列表渲染

条件渲染与列表渲染

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

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-if 或 v-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-if 与 v-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.id、item.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 写在要重复的元素上;检查数据是否为空
新增后页面没反应 漏写 .value 或 push 方法调用无效 确保 users.value.push(...)
删除后列表没变 filter 后未赋值 必须写成 users.value = users.value.filter(...)
控制台报错"Cannot read properties..." v-if 和 v-for 在同一元素 改用 computed 先过滤
列表增删后输入框/选框串位 key 使用了 index 把 :key="index" 改为数据的唯一 id
相关推荐
高级程序源43 分钟前
django校园寻物通失物招领平台32261-计算机课程设计、毕业设计
vue.js·python·mysql·小程序·django·flask·课程设计
WeiXin_DZbishe1 小时前
基于springboot宠物领养系统-计算机毕设 附源码【课程设计】94217
vue.js·spring boot·python·django·php·课程设计
架构技术专栏1 小时前
Agent 工具调用:从工具声明到执行反馈
前端·人工智能·后端
别动我齐刘海2 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
志尊宝3 小时前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
WeiXin_DZbishe3 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
刘发财3 小时前
前端如何生成10000页PDF文件?
前端·javascript·开源
WeiXin_DZbishe4 小时前
基于Springboot+AI的kuall音乐广场的设计与实现-计算机毕设 附源码【课程设计】12715
vue.js·人工智能·spring boot·后端·python·php·课程设计
A接拉起0074 小时前
2026 年 JavaScript 开发者需要了解的知识
前端·javascript·后端
_馒头4 小时前
pixiJs游戏开发实践 - 跳棋小游戏
javascript·vue.js