Vue 3 条件与循环渲染技巧(五)

在 Vue 3 中,条件渲染和循环渲染是两个非常重要的功能,可以帮助开发者根据不同的条件动态地显示或隐藏元素,以及根据数据源生成多个相同的元素。本文将详细介绍如何在 Vue 3 中使用这些功能,并提供实际应用示例。

条件渲染

v-if 指令

v-if 指令用于根据条件性地渲染元素。当条件为 true 时,元素会被渲染到 DOM 中;当条件为 false 时,元素不会被渲染。v-if 适用于条件变化不频繁的情况,因为它会销毁和重建元素,性能开销较大。

<div id="app">
  <p v-if="seen">现在你看到我了</p>
</div><script>
const app = {
  data() {
    return {
      seen: true // 改为 false,信息就无法显示
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

在这个例子中,v-if 指令将根据 seen 的值(true 或 false)来决定是否插入 <p> 元素。

v-show 指令

v-show 指令也用于根据条件性地显示或隐藏元素,但它始终会将元素渲染到 DOM 中,只是通过 CSS 的 display 属性来控制元素的显示和隐藏。因此,v-show 适用于条件变化频繁的情况,因为它只需要切换样式,性能更好。

<h1 v-show="ok">Hello!</h1>

v-else 和 v-else-if 指令

v-else 和 v-else-if 指令用于处理多个条件分支,必须紧跟在 v-if 或 v-else-if 之后。

<div id="app">
  <div v-if="Math.random() > 0.5">随机数大于 0.5</div>
  <div v-else>随机数小于等于 0.5</div>
</div><script>
Vue.createApp().mount('#app')
</script>

在这个例子中,v-else 指令用于在前一个 v-if 表达式为 false 时渲染元素。

多个条件分支

v-else-if 可以用于添加额外的条件判断,可以连续使用多个 v-else-if。

<div id="app">
  <div v-if="type === 'A'">A</div>
  <div v-else-if="type === 'B'">B</div>
  <div v-else-if="type === 'C'">C</div>
  <div v-else>Not A/B/C</div>
</div><script>
const app = {
  data() {
    return {
      type: "C" // 可以改为其他值
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

循环渲染

v-for 指令

v-for 指令用于遍历数组或对象,生成对应数量的元素。它是 Vue 3 中最常用的循环指令。

遍历数组

<div id="app">

<ul>
    <li v-for="(item, index) in items" :key="item.id">{{ item.text }}</li>
  </ul>
</div><script>
const app = {
  data() {
    return {
      items: [
        { id: 1, text: 'Google' },
        { id: 2, text: 'Runoob' },
        { id: 3, text: 'Taobao' }
      ]
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

在这个例子中,v-for 指令遍历 items 数组,并为每个元素生成一个 <li> 元素。key 属性用于标识每个元素的唯一性,帮助 Vue 更高效地更新 DOM。

遍历对象

<div id="app">

<ul>
    <li v-for="(value, key, index) in object" :key="key">{{ index }}. {{ key }} : {{ value }}</li>
  </ul>
</div><script>
const app = {
  data() {
    return {
      object: {
        name: '菜鸟教程',
        url: 'http://www.runoob.com',
        slogan: '学的不仅是技术,更是梦想!'
      }
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

在这个例子中,v-for 指令遍历 object 对象,并为每个属性生成一个 <li> 元素。key、value 和 index 分别表示属性名、属性值和索引。

遍历整数

v-for 也可以用于遍历整数,生成指定数量的元素。

<div id="app">

<ul>
    <li v-for="n in 10" :key="n">{{ n }}</li>
  </ul>
</div><script>
Vue.createApp().mount('#app')
</script>

过滤和排序

你可以在 v-for 中使用计算属性来过滤或排序数组。

<div id="app">

<ul>
    <li v-for="n in evenNumbers" :key="n">{{ n }}</li>
  </ul>
</div><script>
const app = {
  data() {
    return {
      numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    }
  },
  computed: {
    evenNumbers() {
      return this.numbers.filter(number => number % 2 === 0)
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

在这个例子中,evenNumbers 计算属性返回一个只包含偶数的数组,v-for 指令遍历这个数组并生成对应的 <li> 元素。

v-for 和 v-if 的联合使用

v-for 和 v-if 可以联合使用,但需要注意的是,v-for 的优先级高于 v-if,这意味着 v-if 会分别重复运行于每个 v-for 循环中。

<div id="app">
  <select @change="changeVal($event)" v-model="selOption">
    <template v-for="(site, index) in sites" :key="site.id">
      <option v-if="index === 1" :value="site.name" selected>{{ site.name }}</option>
      <option v-else :value="site.name">{{ site.name }}</option>
    </template>
  </select>

<div>您选中了: {{ selOption }}</div>
</div><script>
const app = {
  data() {
    return {
      selOption: "Runoob",
      sites: [
        { id: 1, name: "Google" },
        { id: 2, name: "Runoob" },
        { id: 3, name: "Taobao" }
      ]
    }
  },
  methods: {
    changeVal(event) {
      this.selOption = event.target.value;
      alert("你选中了" + this.selOption);
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

在这个例子中,v-for 指令遍历 sites 数组,v-if 指令用于设置默认选中值。

在组件上使用 v-for

你可以在自定义组件上使用 v-for,但需要注意的是,组件有自己独立的作用域,因此需要通过 props 传递数据。

<div id="todo-list-example">
  <form @submit.prevent="addNewTodo">
    <label for="new-todo">Add a todo</label>
    <input v-model="newTodoText" id="new-todo" placeholder="E.g. Feed the cat" />
    <button>Add</button>
  </form>

<ul>
    <todo-item v-for="(todo, index) in todos" :key="todo.id" :title="todo.title" @remove="todos.splice(index, 1)">
    </todo-item>
  </ul>
</div><script>
const TodoItem = {
  props: ['title'],
  template: '
<li>{{ title }} <button @click="$emit(\'remove\')">Remove</button></li>'
}

const app = {
  components: {
    TodoItem
  },
  data() {
    return {
      newTodoText: '',
      todos: [
        { id: 1, title: 'Feed the cat' },
        { id: 2, title: 'Buy groceries' }
      ]
    }
  },
  methods: {
    addNewTodo() {
      const text = this.newTodoText.trim()
      if (text) {
        this.todos.push({
          id: Date.now(),
          title: text
        })
        this.newTodoText = ''
      }
    }
  }
}

Vue.createApp(app).mount('#todo-list-example')
</script>

在这个例子中,TodoItem 组件通过 props 接收 title 属性,并通过 $emit 触发 remove 事件来删除待办事项。

总结

本文详细介绍了 Vue 3 中的条件渲染和循环渲染功能,包括 v-if、v-show、v-else、v-else-if 和 v-for 指令的使用方法和注意事项。通过这些指令,你可以根据不同的条件动态地显示或隐藏元素,以及根据数据源生成多个相同的元素。希望本文能帮助你在实际项目中更好地利用这些功能。