问题是v-mode 不会刷新 比如input删除不了预设值 或者一下固定数据修改不了 一定是没有用不可变性(Immutability)是指对象在被创建后,其状态(即属性值)不能被改变的特性。换句

saleExplain.wxarticleTitle = matchedArticle.name
   if (matchedArticle) {
      wxarticleTitle = matchedArticle.name;
    }
  }
  return {
    ...saleExplain,
    wxarticleTitle
  };

比之下,第二个代码片段直接修改了原始的 saleExplain 对象,将 wxarticleTitle 属性赋值给它。虽然这样可以实现相同的功能

不可变性(Immutability)是指对象在被创建后,其状态(即属性值)不能被改变的特性。换句话说,一旦对象被创建,它的内容就无法被修改。如果需要改变对象的状态,必须创建一个新的对象,而不是修改现有的对象。

对比:两种设置 Vue 对象属性的方法

在 Vue 开发中,处理对象属性的更新时,有两种常见的方法:直接修改对象属性和使用不可变性原则。下面我们通过一个具体的示例来对比这两种方法的原理和效果。

示例代码对比
方法一:使用不可变性原则
async loadSaleExplains() {
  try {
    const saleExplains = await Spu.getSaleExplainsBySpuId(this.spuId);
    console.log(saleExplains);

    // 获取所有微信文章
    const allWxArticles = await wxarticle.getWxarticleList(0, 0, 0);

    // 为每个 saleExplain 设置 wxarticleTitle
    this.saleExplains = saleExplains.map(saleExplain => {
      let wxarticleTitle = '';
      if (saleExplain.wxarticle_id) {
        const matchedArticle = allWxArticles.items.find(article => article.id === saleExplain.wxarticle_id);
        if (matchedArticle) {
          wxarticleTitle = matchedArticle.name;
        }
      }
      return {
        ...saleExplain,
        wxarticleTitle
      };
    });

  } catch (error) {
    if (error.code === 10020) {
      this.$message.info('该spu暂无销售说明,请先添加');
    } else {
      this.$message.error('加载销售说明失败,请重试');
    }
    console.error(error);
  }
}
方法二:直接修改对象属性
async loadSaleExplains() {
  try {
    this.saleExplains = await Spu.getSaleExplainsBySpuId(this.spuId);
    console.log(this.saleExplains)

    // 获取所有微信文章
    const allWxArticles = await wxarticle.getWxarticleList(0, 0, 0)

    // 为每个 saleExplain 设置 wxarticleTitle
    this.saleExplains.forEach(saleExplain => {
      if (saleExplain.wxarticle_id) {
        const matchedArticle = allWxArticles.items.find(article => article.id === saleExplain.wxarticle_id)
        if (matchedArticle) {
          saleExplain.wxarticleTitle = matchedArticle.name
        }
      }
    })

  } catch (error) {
    if (error.code === 10020) {
      this.$message.info('该spu暂无销售说明,请先添加')
    } else {
      this.$message.error('加载销售说明失败,请重试')
    }
    console.error(error)
  }
}
不可变性原则的优势
  1. 保持数据不可变性

    • 在第一个代码片段中,通过 map 方法创建一个新数组,并返回一个新的对象,而不是直接修改原始对象。这样做确保了数据的不可变性。
    • 不可变性有助于避免意外的副作用,使代码更容易理解和维护。
  2. 更清晰的数据流

    • 创建新的对象可以清楚地看到数据的变化过程,每个阶段的数据都是独立的,不会影响之前的数据。
    • 这使得代码逻辑更加透明和可追踪。
  3. 更好的性能

    • 在比较对象是否相等时,不可变对象可以通过比较引用来实现,而不需要递归地比较每个属性,这可能带来性能上的优势。
  4. Vue 响应式系统的正确工作

    • 在 Vue 中,响应式系统依赖于对象的 getter 和 setter。当对象属性在初始化时定义好,Vue 可以正确地跟踪和响应属性的变化。
直接修改对象属性的劣势
  1. 违背不可变性原则

    • 在第二个代码片段中,直接修改了原始对象的属性,这违背了不可变性的原则,可能会导致意外的副作用。
  2. Vue 响应式系统的局限

    • 当通过直接赋值的方式为对象动态添加新属性时,Vue 无法自动为这些新属性创建 getter 和 setter。
    • 结果是,Vue 无法检测到这些属性的变化,导致视图无法更新。例如,当在 input 中删除 wxarticleTitle 的值时,Vue 无法检测到变化,导致视图没有更新。
解决方法

为了让 Vue 正确地跟踪和响应对象属性的变化,可以使用 Vue.set() 方法显式地添加新属性:

this.$set(saleExplain, 'wxarticleTitle', matchedArticle.name);

或者使用计算属性来获取 wxarticleTitle 的值,这样可以避免直接修改对象,并且计算属性会自动跟踪其依赖项的变化并触发更新。

总结

在 Vue 开发中,遵循不可变性原则和使用 Vue 提供的响应式方法,可以确保数据流的清晰性和代码的可维护性。通过对比上述两种方法,我们可以看到不可变性原则的优势,以及直接修改对象属性的潜在问题。为了确保 Vue 的响应式系统能够正常工作,建议尽量使用不可变性原则和 Vue 提供的方法来管理对象属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值