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

Vue.js二次Ajax请求更新数据的最佳实践咨询

Vue 2.5 数据更新最佳实践优化方案

嘿,针对你用Vue 2.5.16实现数据更新时遇到的两个问题,我给你梳理下实用的优化思路,贴合Vue的响应式特性来搞:

一、无需手动操作的高效properties对象更新方式

首先得说,v-model确实不适合你这个场景——它主要是给表单元素做双向绑定用的,咱们这里是后端数据拉取更新,得用Vue响应式系统的正确姿势来优化:

  1. 并行请求提升加载速度
    你现在是先调用properties.view()拿缓存数据,再调用available()拿库存数据,其实这俩请求可以同时发起,用Promise.all并行处理,不用等第一个完成再跑第二个,能大幅缩短页面加载时间:

    // 页面加载时的初始化逻辑
    async initData() {
      const [viewRes, availableRes] = await Promise.all([
        axios.get('/properties/view'), // 替换成你的view接口实际地址
        axios.get(searchJs.getAttribute('webroot') + 'properties/available', {
          headers: {'Content-Type': 'application/json'}
        })
      ]);
      this.properties = viewRes.data;
      this.updateAvailableData(availableRes.data); // 单独抽离更新逻辑更清晰
    }
    
  2. 高效匹配数据,避免循环遍历浪费性能
    你现在用filter循环找匹配的property,数据多的时候效率很低。可以把已有的properties转成Map,用id作为key,直接快速查找:

    updateAvailableData(availableData) {
      const propMap = new Map(this.properties.map(p => [p.id, p]));
      availableData.forEach(p => {
        const targetProp = propMap.get(p.id);
        if (targetProp) {
          // 这里更新属性,后面讲深层更新的简洁写法
          this.updateRateData(targetProp, p.rate);
        }
      });
    }
    
  3. 利用Vue响应式特性,减少手动$set的使用
    如果你的properties数组里的对象本身是响应式的(从后端拿到后直接赋值给data里的properties,Vue已经做了响应式处理),那么只要直接修改对象的属性,Vue会自动更新视图,不需要每次都用$set——除非你是新增原本不存在的深层属性。

二、深层属性更新的简洁实现方式

你现在逐层构建对象确实麻烦,给你几个更简洁的方案:

方案1:直接赋值(适用于属性已存在的情况)

如果targetProp.rate.low.total已经存在(从properties.view()的缓存数据里就有这个结构),直接赋值就行:

updateRateData(targetProp, newRate) {
  targetProp.rate.low.total.nightly_avg = newRate.low.total.nightly_avg;
  targetProp.rate.low.total.original_nightly_avg = newRate.low.total.original_nightly_avg;
}

Vue会检测到这些属性的变化,自动更新视图。

方案2:展开运算符合并对象(保留原有属性,更新指定字段)

如果需要保留rate对象里的其他属性,只更新total里的两个字段,用ES6展开运算符很方便:

updateRateData(targetProp, newRate) {
  targetProp.rate = {
    ...targetProp.rate,
    low: {
      ...targetProp.rate.low,
      total: {
        ...targetProp.rate.low.total,
        nightly_avg: newRate.low.total.nightly_avg,
        original_nightly_avg: newRate.low.total.original_nightly_avg
      }
    }
  };
}

这种方式不会覆盖rate里的其他未修改属性,同时Vue会因为rate对象的引用变化触发视图更新。

方案3:用$set处理新增的深层属性(如果结构原本不存在)

如果缓存数据里没有rate.low.total这个结构,是第一次新增,那得用$set来保证响应式:

updateRateData(targetProp, newRate) {
  // 先确保rate.low存在,不存在就创建
  if (!targetProp.rate) this.$set(targetProp, 'rate', {});
  if (!targetProp.rate.low) this.$set(targetProp.rate, 'low', {});
  // 然后更新total里的字段
  this.$set(targetProp.rate.low, 'total', {
    nightly_avg: newRate.low.total.nightly_avg,
    original_nightly_avg: newRate.low.total.original_nightly_avg
  });
}

方案4:用工具函数简化深层赋值(比如lodash.set)

如果项目里已经引入了lodash,直接用_.set能一行搞定深层属性赋值,不管属性是否存在:

updateRateData(targetProp, newRate) {
  _.set(targetProp, 'rate.low.total.nightly_avg', newRate.low.total.nightly_avg);
  _.set(targetProp, 'rate.low.total.original_nightly_avg', newRate.low.total.original_nightly_avg);
}

不想引入lodash的话,也可以自己写个简单的深层赋值函数:

function setDeep(obj, path, value) {
  const keys = path.split('.');
  let current = obj;
  for (let i = 0; i < keys.length - 1; i++) {
    if (!current[keys[i]]) current[keys[i]] = {};
    current = current[keys[i]];
  }
  current[keys[keys.length - 1]] = value;
}
// 使用示例
setDeep(targetProp, 'rate.low.total.nightly_avg', newRate.low.total.nightly_avg);

整合后的完整代码示例

把上面的优化点整合起来,你的Vue实例可以改成这样:

var properties = new Vue({
  el: '#properties',
  data: {
    properties: []
  },
  mounted() {
    this.initData(); // 页面加载时初始化数据
  },
  methods: {
    async initData() {
      try {
        // 并行发起两个请求
        const [viewRes, availableRes] = await Promise.all([
          axios.get('/properties/view'), // 替换成你的view接口实际地址
          axios.get(searchJs.getAttribute('webroot') + 'properties/available', {
            headers: {'Content-Type': 'application/json'}
          })
        ]);
        this.properties = viewRes.data;
        this.updateAvailableData(availableRes.data);
      } catch (err) {
        console.error('数据加载失败:', err);
      }
    },
    updateAvailableData(availableData) {
      const propMap = new Map(this.properties.map(p => [p.id, p]));
      availableData.forEach(p => {
        const targetProp = propMap.get(p.id);
        if (targetProp) {
          this.updateRateData(targetProp, p.rate);
        }
      });
    },
    updateRateData(targetProp, newRate) {
      // 这里选你喜欢的方案,比如直接赋值(假设结构已存在)
      targetProp.rate.low.total.nightly_avg = newRate.low.total.nightly_avg;
      targetProp.rate.low.total.original_nightly_avg = newRate.low.total.original_nightly_avg;
      // 或者用展开运算符
      // targetProp.rate = {
      //   ...targetProp.rate,
      //   low: {
      //     ...targetProp.rate.low,
      //     total: {
      //       ...targetProp.rate.low.total,
      //       nightly_avg: newRate.low.total.nightly_avg,
      //       original_nightly_avg: newRate.low.total.original_nightly_avg
      //     }
      //   }
      // };
    }
  }
});

这样既提升了数据加载和更新的效率,又简化了深层属性的写法,完全贴合Vue 2的最佳实践~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:21:20