🎬 HoRain 云小助手个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

一、v-for基础用法

1. 遍历数组

2. 遍历对象

二、关键属性 :key

三、在 上使用 v-for

四、循环嵌套

五、遍历数字范围

六、v-for与 v-if的结合使用

七、动态操作数组

八、性能优化技巧

九、实用示例:待办事项列表

关键要点


以下是 Vue.js 循环渲染的完整指南,主要使用 v-for指令来基于数据源重复渲染元素。

一、v-for基础用法

v-for指令基于一个数组(或对象)来重复渲染元素。基本语法:v-for="(item, index) in items"

1. 遍历数组

<template>
  <div>
    <h3>商品列表</h3>
    <ul>
      <!-- 基本用法:item 是当前项,index 是索引 -->
      <li v-for="(product, index) in products" :key="product.id">
        {{ index + 1 }}. {{ product.name }} - ¥{{ product.price }}
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const products = ref([
  { id: 1, name: '笔记本电脑', price: 5999 },
  { id: 2, name: '智能手机', price: 3999 },
  { id: 3, name: '无线耳机', price: 899 },
]);
</script>

2. 遍历对象

<template>
  <div>
    <h3>用户信息</h3>
    <ul>
      <!-- value: 属性值, key: 属性名, index: 索引 -->
      <li v-for="(value, key, index) in userInfo" :key="key">
        {{ index + 1 }}. {{ key }}: {{ value }}
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const userInfo = ref({
  name: '张三',
  age: 25,
  email: 'zhangsan@example.com',
  city: '北京'
});
</script>

二、关键属性 :key

始终为 v-for的元素提供 :key属性,这是 Vue 识别节点身份、高效更新 DOM 的关键。

<template>
  <div>
    <!-- 使用唯一标识作为 key(推荐) -->
    <div v-for="item in items" :key="item.id">{{ item.name }}</div>
    
    <!-- 使用索引作为 key(不推荐,除非列表是静态的) -->
    <div v-for="(item, index) in items" :key="index">{{ item.name }}</div>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const items = ref([
  { id: 101, name: '项目A' },
  { id: 102, name: '项目B' },
  { id: 103, name: '项目C' },
]);
</script>

三、在 <template>上使用 v-for

可以在 <template>标签上使用 v-for来渲染多个元素,而不添加额外的 DOM 元素。

<template>
  <div>
    <!-- 渲染多个元素而不包裹额外div -->
    <template v-for="item in items" :key="item.id">
      <h4>{{ item.title }}</h4>
      <p>{{ item.content }}</p>
      <hr />
    </template>
  </div>
</template>

四、循环嵌套

<template>
  <div>
    <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>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const categories = ref([
  {
    id: 1,
    name: '电子产品',
    products: [
      { id: 101, name: '手机' },
      { id: 102, name: '电脑' }
    ]
  },
  {
    id: 2,
    name: '书籍',
    products: [
      { id: 201, name: 'Vue.js指南' },
      { id: 202, name: 'JavaScript高级编程' }
    ]
  }
]);
</script>

五、遍历数字范围

v-for也可以接受一个整数,用于重复渲染指定次数。

<template>
  <div>
    <!-- 渲染 5 次 -->
    <span v-for="n in 5" :key="n">{{ n }} </span>
    <!-- 输出: 1 2 3 4 5 -->
  </div>
</template>

六、v-forv-if的结合使用

不推荐在同一元素上同时使用 v-forv-if。正确的做法是:

<template>
  <div>
    <!-- 错误:不要在同一元素上同时使用 -->
    <!-- <li v-for="user in users" v-if="user.isActive" :key="user.id">{{ user.name }}</li> -->
    
    <!-- 正确方法1:使用计算属性过滤 -->
    <ul>
      <li v-for="user in activeUsers" :key="user.id">{{ user.name }}</li>
    </ul>
    
    <!-- 正确方法2:在外层使用 <template> 包裹 -->
    <template v-for="user in users" :key="user.id">
      <li v-if="user.isActive">{{ user.name }}</li>
    </template>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue';

const users = ref([
  { id: 1, name: 'Alice', isActive: true },
  { id: 2, name: 'Bob', isActive: false },
  { id: 3, name: 'Charlie', isActive: true },
]);

// 通过计算属性过滤
const activeUsers = computed(() => users.value.filter(user => user.isActive));
</script>

七、动态操作数组

Vue 能检测到以下数组方法的变化,并触发视图更新:

<template>
  <div>
    <ul>
      <li v-for="item in items" :key="item.id">{{ item.name }}</li>
    </ul>
    
    <button @click="addItem">添加项目</button>
    <button @click="removeFirst">删除第一个</button>
    <button @click="reverseItems">反转列表</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const items = ref([
  { id: 1, name: '项目A' },
  { id: 2, name: '项目B' },
  { id: 3, name: '项目C' },
]);

const addItem = () => {
  const newId = items.value.length + 1;
  // push - 添加到最后
  items.value.push({ id: newId, name: `项目${newId}` });
};

const removeFirst = () => {
  // shift - 移除第一个
  items.value.shift();
};

const reverseItems = () => {
  // reverse - 反转数组
  items.value.reverse();
};
</script>

八、性能优化技巧

  1. 始终使用 :key,且避免使用索引作为 key(除非列表是静态的)

  2. 避免在 v-for中使用复杂表达式,可以使用计算属性

  3. 大型列表使用虚拟滚动(如 vue-virtual-scroller

  4. 使用 v-forv-if时注意优先级v-for优先级更高)

九、实用示例:待办事项列表

<template>
  <div>
    <h3>待办事项 ({{ remainingCount }}/{{ todos.length }})</h3>
    
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加新任务..." />
    
    <ul>
      <li v-for="todo in filteredTodos" :key="todo.id">
        <input type="checkbox" v-model="todo.completed" />
        <span :class="{ completed: todo.completed }">{{ todo.text }}</span>
        <button @click="removeTodo(todo.id)">删除</button>
      </li>
    </ul>
    
    <div>
      <button @click="filter = 'all'">全部</button>
      <button @click="filter = 'active'">未完成</button>
      <button @click="filter = 'completed'">已完成</button>
    </div>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue';

let nextId = 3;
const newTodo = ref('');
const filter = ref('all'); // 'all', 'active', 'completed'

const todos = ref([
  { id: 1, text: '学习Vue.js', completed: true },
  { id: 2, text: '练习循环渲染', completed: false },
]);

const addTodo = () => {
  if (newTodo.value.trim()) {
    todos.value.push({
      id: nextId++,
      text: newTodo.value,
      completed: false
    });
    newTodo.value = '';
  }
};

const removeTodo = (id) => {
  const index = todos.value.findIndex(todo => todo.id === id);
  if (index !== -1) {
    todos.value.splice(index, 1);
  }
};

// 计算属性:过滤待办事项
const filteredTodos = computed(() => {
  switch (filter.value) {
    case 'active':
      return todos.value.filter(todo => !todo.completed);
    case 'completed':
      return todos.value.filter(todo => todo.completed);
    default:
      return todos.value;
  }
});

// 计算属性:剩余数量
const remainingCount = computed(() => {
  return todos.value.filter(todo => !todo.completed).length;
});
</script>

<style>
.completed {
  text-decoration: line-through;
  color: #888;
}
</style>

关键要点

  1. v-for是 Vue 中实现列表渲染的核心指令

  2. 始终为循环项提供唯一的 :key,确保高效更新

  3. 可以遍历数组对象数字范围

  4. 避免在 v-for中直接使用 v-if,改用计算属性或 <template>包裹

  5. 结合计算属性和方法,可以创建复杂的动态列表

  6. 注意数组变化检测的限制,使用响应式方法修改数组

循环渲染是构建动态界面的基础,合理使用可以创建各种数据驱动的列表、表格和网格布局。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐