当前位置: 首页 > news >正文

Vue 3 列表渲染:概念与用法详解

一、核心概念

1.1 什么是列表渲染

列表渲染是将数组或对象的数据映射到 DOM 元素的过程,Vue 3 使用 v-for 指令来实现这一功能。

1.2 主要特性

  • 基于数据源动态生成多个元素

  • 自动响应数据变化

  • 支持多种数据源类型

  • 提供唯一 key 管理

二、基本用法

2.1 数组渲染

<template><!-- 基本用法 --><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul><!-- 获取索引 --><ul><li v-for="(item, index) in items" :key="item.id">{{ index + 1 }}. {{ item.name }}</li></ul>
</template><script setup>
import { ref } from 'vue'const items = ref([{ id: 1, name: '项目一' },{ id: 2, name: '项目二' },{ id: 3, name: '项目三' }
])
</script>

2.2 对象渲染

<template><!-- 对象基本渲染 --><ul><li v-for="(value, key) in userInfo" :key="key">{{ key }}: {{ value }}</li></ul><!-- 带索引的对象渲染 --><ul><li v-for="(value, key, index) in userInfo" :key="key">{{ index }}. {{ key }}: {{ value }}</li></ul>
</template><script setup>
import { ref } from 'vue'const userInfo = ref({name: '张三',age: 25,email: 'zhangsan@example.com'
})
</script>

2.3 使用数字范围

<template><!-- 渲染 1-10 --><div><span v-for="n in 10" :key="n">{{ n }}</span></div><!-- 渲染指定范围 --><div><span v-for="n in [5, 10, 15, 20]" :key="n">{{ n }}</span></div>
</template>

三、关键属性 :key 的重要性

3.1 为什么需要 key

<template><!-- 正确使用 key --><div><div v-for="item in items" :key="item.id"  <!-- 推荐使用唯一标识 -->class="item">{{ item.content }}</div></div><!-- 不推荐的做法 --><div><div v-for="(item, index) in items" :key="index"    <!-- 仅在列表稳定时使用 -->class="item">{{ item.content }}</div></div>
</template><script setup>
const items = ref([{ id: 'unique-1', content: '内容一' },{ id: 'unique-2', content: '内容二' }
])
</script>

3.2 key 的最佳实践

  1. 使用唯一标识符(如数据库 ID)

  2. 避免使用数组索引(除非列表从不重新排序)

  3. key 值应该是字符串或数字

四、高级用法

4.1 与 v-if 结合使用

<template><!-- 不推荐:v-for 和 v-if 在同一元素上 --><div><!-- 这种写法性能较差 --><div v-for="item in items" v-if="item.isActive" :key="item.id">{{ item.name }}</div></div><!-- 推荐:使用计算属性或 template 包裹 --><div><template v-for="item in items" :key="item.id"><div v-if="item.isActive">{{ item.name }}</div></template></div>
</template><script setup>
import { computed } from 'vue'// 更好的方式:使用计算属性
const activeItems = computed(() => {return items.value.filter(item => item.isActive)
})
</script>

4.2 在组件上使用 v-for

<template><!-- 自定义组件列表 --><ProjectItemv-for="project in projects":key="project.id":project="project"@select="handleSelect"/>
</template><script setup>
import ProjectItem from './ProjectItem.vue'const projects = ref([{ id: 1, title: '项目A' },{ id: 2, title: '项目B' }
])const handleSelect = (project) => {console.log('选中项目:', project)
}
</script>

4.3 嵌套循环

<template><div v-for="category in categories" :key="category.id"><h3>{{ category.name }}</h3><ul><li v-for="product in category.products" :key="product.id">{{ product.name }}</li></ul></div>
</template><script setup>
const categories = ref([{id: 1,name: '电子产品',products: [{ id: 101, name: '手机' },{ id: 102, name: '电脑' }]},{id: 2,name: '书籍',products: [{ id: 201, name: 'Vue 3 指南' },{ id: 202, name: 'JavaScript 高级编程' }]}
])
</script>

五、性能优化

5.1 使用计算属性减少渲染

<script setup>
import { computed, ref } from 'vue'const rawItems = ref([{ id: 1, name: 'Item 1', active: true },{ id: 2, name: 'Item 2', active: false },{ id: 3, name: 'Item 3', active: true }
])// 使用计算属性过滤和排序
const displayItems = computed(() => {return rawItems.value.filter(item => item.active).sort((a, b) => a.name.localeCompare(b.name))
})
</script>

5.2 虚拟滚动(大数据量)

<template><!-- 使用第三方库如 vue-virtual-scroller --><RecycleScrollerclass="scroller":items="largeList":item-size="50"key-field="id"><template #default="{ item }"><div class="item">{{ item.name }}</div></template></RecycleScroller>
</template><script setup>
import { ref } from 'vue'const largeList = ref(Array.from({ length: 10000 }, (_, i) => ({id: i + 1,name: `项目 ${i + 1}`}))
)
</script><style scoped>
.scroller {height: 400px;
}
.item {height: 50px;line-height: 50px;border-bottom: 1px solid #eee;
}
</style>

六、响应式更新

6.1 数组更新检测

<script setup>
import { ref } from 'vue'const items = ref(['A', 'B', 'C'])// 这些方法会触发视图更新
const updateArray = () => {// 变异方法(自动触发更新)items.value.push('D')      // 添加items.value.pop()          // 移除最后一个items.value.shift()        // 移除第一个items.value.unshift('Z')   // 添加到开头items.value.splice(1, 1)   // 删除/替换items.value.sort()         // 排序items.value.reverse()      // 反转// 非变异方法(需要重新赋值)items.value = items.value.filter(item => item !== 'B')items.value = items.value.concat(['E', 'F'])items.value = [...items.value, 'G']
}
</script>

6.2 对象更新检测

<script setup>
import { reactive } from 'vue'const user = reactive({name: '张三',age: 25
})// 添加新属性(需要特殊处理)
const addProperty = () => {// 方法1:使用 Vue.set(Vue 2 风格)// import { set } from 'vue'// set(user, 'email', 'test@example.com')// 方法2:直接赋值(推荐)user.email = 'test@example.com'// 方法3:使用 Object.assignObject.assign(user, { address: '北京' })
}
</script>

七、实际应用示例

7.1 待办事项列表

<template><div class="todo-app"><input v-model="newTodo"@keyup.enter="addTodo"placeholder="添加新任务"/><ul><li v-for="(todo, index) in todos" :key="todo.id":class="{ completed: todo.completed }"><input type="checkbox" v-model="todo.completed"/><span>{{ todo.text }}</span><button @click="removeTodo(index)">删除</button></li></ul><div>总计: {{ totalTodos }}, 完成: {{ completedTodos }}</div></div>
</template><script setup>
import { ref, computed } from 'vue'const newTodo = ref('')
const todos = ref([])
let idCounter = 1const addTodo = () => {if (newTodo.value.trim()) {todos.value.push({id: idCounter++,text: newTodo.value,completed: false})newTodo.value = ''}
}const removeTodo = (index) => {todos.value.splice(index, 1)
}const totalTodos = computed(() => todos.value.length)
const completedTodos = computed(() => todos.value.filter(todo => todo.completed).length
)
</script><style scoped>
.todo-app {max-width: 400px;margin: 0 auto;
}.completed {text-decoration: line-through;color: #999;
}li {display: flex;align-items: center;gap: 10px;margin: 5px 0;
}
</style>

八、注意事项

  1. 避免同时使用 v-for 和 v-if:优先使用计算属性过滤数据

  2. 始终提供唯一的 key:提高性能,避免渲染问题

  3. 避免直接修改数组长度:使用 splice 代替

  4. 大数据量使用虚拟滚动:提升渲染性能

  5. 复杂数据结构考虑组件化:提高可维护性

总结

Vue 3 的列表渲染功能强大而灵活,通过 v-for 指令可以轻松处理各种数据结构的渲染需求。合理使用 key、结合计算属性优化性能、遵循最佳实践,可以构建出高效且易维护的列表界面。

记住核心原则:让数据驱动视图,Vue 会自动处理数据变化到视图更新的过程。

http://www.jsqmd.com/news/366011/

相关文章:

  • 2026年会计培训老牌机构怎么选,全国靠谱的品牌在这里 - 工业品网
  • 2026年深圳宝格丽手表维修服务评测与排名:非官方维修网点选择指南与避坑要点 - 十大品牌推荐
  • 2026年深圳帝舵手表维修推荐榜单:非官方维修网点服务评测与选择指南 - 十大品牌推荐
  • 2026年靠谱工单系统哪家好?优质工单软件选型指南 - 品牌2025
  • 分析江苏诚信的玻璃钢编绕拉挤管道服务商,费用情况大揭秘 - mypinpai
  • 2026年深圳宝玑手表维修推荐评测:非官方维修网点服务与售后选择指南 - 十大品牌推荐
  • 笔记本结构
  • 2026年深圳宝珀手表维修非官方网点推荐评测:售后网点服务排行榜单解析 - 十大品牌推荐
  • 2026年深圳热门的石墨烯制造企业排名,石墨烯发热片厂家推荐哪家? - 工业品牌热点
  • 2026年深圳柏莱士手表维修推荐榜单:非官方维修点评测与网点服务指南 - 十大品牌推荐
  • 2026年石家庄知名的巨量推广公司排名,费用怎么收 - 工业设备
  • 2026年合肥摄影学校品牌推荐,哪里有摄影学校及专业摄影学校哪家好 - 工业推荐榜
  • 2026年全国水溶肥厂家权威榜单 智能定制与全场景适配双管齐下 深耕农业赋能种植户 - 深度智识库
  • 2026年深圳贝伦斯手表维修评测推荐:非官方维修网点服务与售后中心选择指南 - 十大品牌推荐
  • 2026年深圳搬家公司评测推荐榜单:告别杂乱与隐形消费,轻松搬迁指南 - 十大品牌推荐
  • 2026年深圳波尔手表维修评测推荐:非官方维修网点服务排行榜单深度解析 - 十大品牌推荐
  • 2026年深度解析中正金码:一家汽车智能自动化装备供应商的三十年技术积淀与市场布局 - 十大品牌推荐
  • MATLAB环境下基于能量分离和的自适应滤波的多分量AM-FM信号解调 程序运行环境为MATL...
  • 北京某公司全球三维系统私有化部署项目
  • 2026年深圳爱马仕手表维修推荐榜单:非官方维修网点服务评测与选择指南 - 十大品牌推荐
  • 2026年深圳伯爵手表维修评测与推荐榜单:非官方维修点选择指南与避坑策略 - 十大品牌推荐
  • Java高频面试题:SpringBoot可以同时处理多少请求?
  • 2026年论文降AI不变意思怎么做?手把手教你语义保留改写
  • 2026年降AIGC保留原文实测:8000字论文改完意思一字不差
  • 2026年深度解析中正金码:一家汽车智能自动化装备供应商的技术与市场定位 - 十大品牌推荐
  • 2026年论文降AI不变意思有多重要?改废了可能要重写
  • 2026年降AI保持学术性:专业术语怎么处理才不被误改
  • 2026年深度解析中正金码:一家汽车智能自动化装备供应商的成长路径与市场定位 - 十大品牌推荐
  • 2026年论文降AI不变意思:哪些段落必须改哪些可以不动
  • 暖气片费用多少,夏洛克厂家价格实惠售后完善 - 工业设备