不推荐

在同一元素上使用 v-if 和 v-for

  1. const App = {
  2. data() {
  3. return {
  4. todoList: [
  5. {
  6. id: 1,
  7. content: 'CONCTENT 1',
  8. completed: false
  9. },
  10. {
  11. id: 2,
  12. content: 'CONCTENT 2',
  13. completed: true
  14. },
  15. {
  16. id: 3,
  17. content: 'CONCTENT 3',
  18. completed: false
  19. }
  20. ]
  21. }
  22. },
  23. template: `
  24. <ul>
  25. <li
  26. v-for="todo of todoList" :key="todo.id"
  27. v-if="!todo.completed"
  28. >
  29. {{ todo.content }}
  30. </li>
  31. </ul>
  32. `
  33. }
  34. Vue.createApp(App).mount('#app');

会报错,在渲染的阶段 v-if 是拿不到 todo

Vue3

v-if 权限是大于 v-for,即 v-if 静态式内部的变量是没办法从 v-for 表达式中获取

Vue2

v-for 权限是大于 v-if,v-for 比 v-if 有更高的优先级

为何到 Vue3 作出这样的改变

  • 在逻辑层级来看,if > for

if 是决定渲染不渲染,而 for 是怎么渲染

  • 性能问题
    如果先渲染再,决定是否渲染会造成性能浪费

但最后是结论还是不要把 v-if 和 v-for 在同组件中连用,可以看下面的解决方法。

解决方法

使用 <template>

  1. {
  2. // ...
  3. template: `
  4. <ul>
  5. <template v-for="todo of todoList" :key="todo.id">
  6. <li v-if="!todo.completed">
  7. {{ todo.content }}
  8. </li>
  9. </template>
  10. </ul>
  11. `
  12. }

使用 computed

  1. {
  2. // ...
  3. template: `
  4. <ul>
  5. <li v-for="todo of NotCompletedTodoList" :key="todo.id"
  6. {{ todo.content }}
  7. </li>
  8. </ul>
  9. `,
  10. computed: {
  11. NotCompletedTodoList() {
  12. return this.todoList.filter(item => !item.completed);
  13. }
  14. }
  15. }