You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue列表中按状态条件展示指定项(支持切换功能)?

简洁实现Vue条件过滤列表的最优方案

你提到不想用嵌套v-if的繁琐写法,那**Vue的计算属性(computed)**绝对是解决这个问题的最佳方式——它不仅代码简洁,还自带缓存机制,性能比直接在模板里写过滤逻辑好得多。

先给你指出原代码里的一个小bug:点击事件里的showOnlyEnable少了个末尾的d,应该是showOnlyEnabled,不然点击切换会无效哦。

接下来是具体的实现步骤:

1. 添加计算属性处理列表过滤

在Vue实例里新增computed选项,定义一个filteredPeople属性,根据showOnlyEnabled的状态返回过滤后的数组:

computed: {
  filteredPeople() {
    // 如果开启"仅显示启用用户",就过滤出isEnabled为true的项,否则返回原数组
    return this.showOnlyEnabled 
      ? this.people.filter(person => person.isEnabled) 
      : this.people;
  }
}

2. 修改模板遍历计算属性

把模板里v-for遍历的原people数组换成我们的计算属性filteredPeople:

<ol>
  <li v-for="person in filteredPeople" :key="person.name">
    <label>
      <span>{{ person.name }}</span>
    </label>
  </li>
</ol>

完整修正后的代码

<div id="app"></div>

<script>
new Vue({
  el: "#app",
  template: `
    <h2>People:</h2>
    <span @click="showOnlyEnabled = !showOnlyEnabled">toggle enabled</span>
    <ol>
      <li v-for="person in filteredPeople" :key="person.name">
        <label>
          <span>{{ person.name }}</span>
        </label>
      </li>
    </ol>
  `,
  data: {
    showOnlyEnabled: false,
    people: [
      { name: "Joe", isEnabled: false },
      { name: "Jonie", isEnabled: false },
      { name: "Jill", isEnabled: true },
      { name: "Jack", isEnabled: true },
    ]
  },
  computed: {
    filteredPeople() {
      return this.showOnlyEnabled 
        ? this.people.filter(person => person.isEnabled) 
        : this.people;
    }
  },
  methods: {
    toggle: function(todo){
      todo.done = !todo.done
    }
  }
})
</script>

额外补充:不推荐的写法(仅作参考)

虽然也可以直接在v-for里写过滤逻辑,但这种方式每次组件渲染都会重新执行过滤函数,没有缓存,性能不如计算属性,所以不建议使用:

<li v-for="person in (showOnlyEnabled ? people.filter(p => p.isEnabled) : people)" :key="person.name">

这样写出来的代码既简洁又易维护,完全避免了嵌套v-if的冗余写法,而且符合Vue的最佳实践~

内容的提问来源于stack exchange,提问作者timpone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:39:12