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

Vue.js单文件应用:Ajax响应后删除数组项的异步问题求助

从jQuery转Vue的新手?这两个核心问题帮你搞定!

刚从jQuery转Vue确实会有不少思维上的转换阵痛,我当初也踩过类似的坑,先帮你拆解一下问题,然后给你最优雅的解决方案:

核心问题1:异步删除时索引错乱

你说得对,用post.id定位是最佳方案——因为索引会随着数组项的删除/插入动态变化,而id是每个帖子的唯一标识,永远不会变。

核心问题2:动态添加isLoading不生效

Vue默认无法检测对象新增的属性(这是响应式原理的限制),你之前用splice强制更新的方式确实不优雅,正确的做法是用this.$set(Vue实例上的方法)来给帖子对象添加响应式属性。


修改后的完整代码

JavaScript部分

window.app = new Vue({
  el: '#app',
  data: {
    name: '',
    posts: [],
  },
  created() {
    this.fetchData();
  },
  methods:{
    fetchData() {
      axios.get('https://jsonplaceholder.typicode.com/posts').then(response => {
        // 给每个帖子初始添加isLoading属性,确保响应式
        this.posts = response.data.slice(0,20).map(post => ({
          ...post,
          isLoading: false
        }));
      });
    },
    removeItem(post) {
      // 用this.$set添加响应式属性,无需splice hack
      this.$set(post, 'isLoading', true);
      
      axios.post('//jsfiddle.net/echo/json/', "json='{status:success}'&delay=2")
        .then(() => {
          // 用id过滤数组,精准删除对应项,彻底避开索引问题
          this.posts = this.posts.filter(item => item.id !== post.id);
        })
        // 别忘了处理请求失败的情况,恢复按钮状态
        .catch(() => {
          this.$set(post, 'isLoading', false);
        });
    }
  },
  computed: {
    showAlert() {
      return this.name.length > 4 ? true : false
    }
  }
})

HTML部分(仅确保key用唯一id)

<div id="app">
  <div v-for="post in posts" :key="post.id">
    <b-card class="mb-2">
      <b-card-title>{{post.title}}</b-card-title>
      <b-card-text>{{post.body}}</b-card-text>
      <a href="#" @click.prevent="removeItem(post)" class="card-link">
        Remove
        <span v-show="post.isLoading" class="spinner"></span>
      </a>
    </b-card>
  </div>
</div>

关键改动说明

  1. 初始化时统一添加isLoading:在获取帖子数据后,用map给每个帖子加上isLoading: false,让属性从一开始就是响应式的,后续直接修改也能触发视图更新。如果不想初始化时加,用this.$set动态添加也是完全可行的。
  2. 用filter代替splice删除项:filter会返回排除目标项的新数组,不管数组之前有没有其他项被删除,都能精准匹配id删除目标帖子,彻底避免索引错乱的问题。
  3. 添加错误处理逻辑:异步请求可能失败,所以要在catch回调里把isLoading改回false,避免按钮一直显示加载状态。

思维转换小提示

jQuery是直接操作DOM和元素索引,而Vue是数据驱动视图——你只需要管好数据的变化,视图会自动同步更新。以后处理这类问题时,先想“我该怎么修改数据”,而不是“我该怎么操作DOM/索引”,慢慢就会适应Vue的思维模式啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:42:49