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

Vue点击兄弟组件筛选按钮触发fetch更新后重绘子组件的问题

Vue兄弟组件点击筛选按钮重复触发列表刷新解决方案

问题根因

当前watch仅触发一次的核心原因是:父组件的keywords变量只有在传入的新关键词为真值且和旧值不同时才会更新,Vue的watch默认仅在监听的属性值发生变化时才会触发回调,若两次点击筛选按钮传入的关键词一致,filters属性没有变化,就不会触发拉取逻辑。

可选解决方案

方案1:新增刷新触发标识(推荐,兼容关键词不变也需要刷新的需求)

父组件代码修改

<template>
  <div class="container">
    <Filter @changedKeywords="reloadItems"></Filter>
    <!-- 新增refreshTag属性传给List组件 -->
    <List :platforms="platforms" :filters="keywords" :refresh-tag="refreshTag"></List>
  </div>
</template>

<script>
// 原有import逻辑保留
export default {
  name: "Holder",
  components: {Filter, List},
  methods: {
    reloadItems: function (data){
      if(data.keywords) {this.keywords = data.keywords};
      // 每次触发筛选事件都更新refreshTag,保证值一定变化
      this.refreshTag = Date.now();
    }
  },
  data(){
    return {
      keywords : null,
      refreshTag: 0 // 新增刷新标识变量
    }
  }
}
</script>

List组件代码修改

<script>
import Game from "./Game";
export default {
  name: "List",
  props: ['filters', 'platforms', 'refreshTag'], // 新增props接收刷新标识
  components: {Game},
  data() {
    return{
      list: [],
    }
  },
  watch: {
    // 监听refreshTag的变化,每次变化都触发拉取逻辑
    refreshTag: {
      async handler() {
        console.log('每次点击都会触发');
        const res = await fetch('/api/game/list/9', {
          method: 'POST',
          body: JSON.stringify({'filters' : this.filters})
        });
        this.list = await res.json();
      },
      immediate: true // 首次加载时自动触发一次
    }
  },
}
</script>

方案2:使用key强制重建组件(简单粗暴,适合小型列表场景)

直接给List组件绑定动态key,每次触发筛选就更新key,Vue会销毁旧的List组件实例,新建全新的实例,自动重新触发数据拉取逻辑:

<template>
  <div class="container">
    <Filter @changedKeywords="reloadItems"></Filter>
    <!-- 绑定动态key -->
    <List :platforms="platforms" :filters="keywords" :key="listKey"></List>
  </div>
</template>

<script>
// 原有import逻辑保留
export default {
  name: "Holder",
  components: {Filter, List},
  methods: {
    reloadItems: function (data){
      if(data.keywords) {this.keywords = data.keywords};
      this.listKey = Date.now();
    }
  },
  data(){
    return {
      keywords : null,
      listKey: 0
    }
  }
}
</script>

该方案不需要修改List组件代码,如果要首次加载自动拉取,给原有filters的watch加immediate: true即可。

方案3:修复现有逻辑(仅当关键词变化才需要刷新时使用)

如果业务逻辑确实只需要关键词变化时才刷新,先检查Filter组件changedKeywords事件的传值,确认每次点击筛选按钮都会传正确的data.keywords,同时确认两次传入的关键词不会完全一致。如果filters是引用类型(比如对象、数组),可以给watch加deep: true配置,监听内部属性的变化:

watch: {
  filters: {
    async handler() {
      // 原有拉取逻辑保留
    },
    deep: true,
    immediate: true
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:15:01