vue数组套对象,在动态加入属性:属性值, 导致数据不更新

一 、案例效果

[{a: 1,b:2},{a: 1,b:2}, toggle:true]导致视图不更新且数据没有响应式。这种格式是数组套对象的,之后由于不想在遍历一层数据变成[{a: 1,b:2,toggle:true},{a: 1,b:2,oggle:true} ] ,就直接加在对象后面了【虽然这样写法不对,但是,有另外一种可以达到想到的效果】

二、实际效果

数组会变成在最后一个对象中加入需要的属性,即 [{a: 1,b:2},{ a: 1,b:2,toggle:true}]且具有响应式

三、复盘

如果你的数据结构是一个数组,其中最后一个元素是一个对象,包含 toggle 属性,而你希望修改这个 toggle 属性并让视图响应更新,但发现视图没有更新,这通常是因为 Vue 不能检测到数组索引和对象属性的变化。
在 Vue 2.x 中,Vue 不能自动检测以下变动的数组:
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
对于对象,Vue 不能检测到对象属性的添加或删除。
解决方法:
对于数组,使用 Vue.set 或 vm. s e t 方法来设置项值,或使用数组的 s p l i c e 方法。对于对象,如果你在创建实例之后添加新的属性到实例上,你应该使用 V u e . s e t 或 v m . set 方法来设置项值,或使用数组的 splice 方法。 对于对象,如果你在创建实例之后添加新的属性到实例上,你应该使用 Vue.set 或 vm. set方法来设置项值,或使用数组的splice方法。对于对象,如果你在创建实例之后添加新的属性到实例上,你应该使用Vue.setvm.set。
针对你的情况,如果你想修改数组中最后一个对象的 toggle 属性并确保视图更新,你应该使用 Vue.set 或 vm.$set。假设你的数组存储在 data 的 myArray 属性中,你可以这样做:

// 假设你想切换最后一个元素的 toggle 属性
this.$set(this.myArray[this.myArray.length - 1], 'toggle', !this.myArray[this.myArray.length - 1].toggle);

这样,Vue 就能够检测到 toggle 属性的变化,并且更新视图。

四、完整示例

<template>
  <div>
    <div v-for="(item, index) in myArray" :key="index">
      <!-- 假设你想展示每个对象的 toggle 状态 -->
      <p v-if="typeof item.toggle !== 'undefined'">Toggle: {{ item.toggle }}</p>
    </div>
    <button @click="toggleLastItem">切换最后一项的 Toggle</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      myArray: [{}, {}, { toggle: true }],
    };
  },
  methods: {
    toggleLastItem() {
      let lastIndex = this.myArray.length - 1;
      this.$set(this.myArray[lastIndex], 'toggle', !this.myArray[lastIndex].toggle);
    },
  },
};
</script>

在这个示例中,点击按钮会切换数组最后一个对象的 toggle 属性值,并且视图会相应地更新

五、应用场景

超过两条展示 展开收起

针对特定的数据结构,如 [{},{}, {toggle: true}],如果数组长度超过两条数据时,需要展示“展开/收起”按钮,并根据 toggle 属性的值动态展示全部数据或只展示前两条数据,可以通过以下步骤实现:

  1. 计算属性或者封装方法:创建一个计算属性来决定基于 toggle 状态展示的数据。
  2. 方法:实现一个方法来切换 toggle 状态。
  3. 模板:在模板中使用计算属性来展示数据,并添加一个按钮来控制展开/收起。
    示例代码如下:
<template>
  <div>
    <!-- 根据 需要循环的数组 展示数据 -->
    <div v-for="(item, index) in toggleArrLength(需要循环的数组)" :key="index">
      <!-- 展示每个项目的内容 -->
      {{ item.content }}
    </div>
    <!-- 当数组长度超过2时,展示展开/收起按钮 -->
    <button v-if="items.length > 2" @click="toggleHandle(需要循环的数组)">
      {{ 需要循环的数组[需要循环的数组.length - 1].toggle ? '收起' : '展开' }}
    </button>
  </div>
</template>

 private toggleArrLength(arrData: any) {
    let lastIndex = arrData.length - 1;
    return arrData[lastIndex].toggle ? arrData : arrData.slice(0, 2);
  }
   // 切换 toggle 状态
   private toggleHandle(data) {
    console.log('toggleMsg--item', data);
    let lastIndex = data.length - 1;
    this.$set(
      data[lastIndex],
      'toggle',
      !data[lastIndex].toggle,
    );
  }

样例

<template>
  <div>
    <!-- 根据 displayedItems 展示数据 -->
    <div v-for="(item, index) in displayedItems" :key="index">
      <!-- 展示每个项目的内容 -->
      {{ item.content }}
    </div>
    <!-- 当数组长度超过2时,展示展开/收起按钮 -->
    <button v-if="items.length > 2" @click="toggleItems">
      {{ items[items.length - 1].toggle ? '收起' : '展开' }}
    </button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 假设的数据结构,最后一个对象包含 toggle 属性
      items: [{ content: 'Item 1' }, { content: 'Item 2' }, { toggle: true }],
    };
  },
  computed: {
    // 根据 toggle 状态决定展示的数据
    displayedItems() {
      // 如果 toggle 为 true 或数组长度不超过2,展示全部项目
      if (this.items.length <= 2 || this.items[this.items.length - 1].toggle) {
        return this.items.slice(0, -1); // 不包括最后一个 toggle 对象
      } else {
        // 否则,只展示前两个项目
        return this.items.slice(0, 2);
      }
    },
  },
  methods: {
    // 切换 toggle 状态
    toggleItems() {
      let toggleItem = this.items[this.items.length - 1];
      toggleItem.toggle = !toggleItem.toggle;
    },
  },
};
</script>

结论: 在这个示例中:
items 数组包含了要展示的数据,最后一个对象是控制展开/收起的 toggle 状态。
displayedItems 计算属性根据 toggle 的值决定展示全部数据还是只展示前两条数据。
toggleItems 方法用于切换 toggle 状态。
模板中使用 v-for 根据 displayedItems 展示数据,并提供一个按钮来控制展开/收起,按钮的文本也根据 toggle 状态动态变化。
注意:这个示例假设除了最后一个对象用于控制展开/收起外,其他对象都是要展示的数据。如果你的数据结构有所不同,请相应调整代码。

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue中,当数组对象属性发生变化时,可以使用计算属性来实时更新视图。计算属性是基于依赖的缓存属性,它会根据它所依赖的数据自动更新。在计算属性中,你可以对数组对象进行处理并返回一个新的。 对于对象属性的变化,你可以使用Vue提供的响应式方法来添加新属性。这样新属性将变为响应式的,并触发视图更新。如果直接在对象上添加新属性(例如this.myObject.newProperty = 'hi'),Vue将无法检测到这个新增属性。 对于数组的变化,Vue无法检测到以下情况的变动: - 通过索引直接设置数组项的,例如:vm.items[indexOfItem] = newValue - 修改数组的长度,例如:vm.items.length = newLength 如果你想更新数组中的元素或对象中的属性,可以在methods中定义一个方法,在该方法中修改数组对象。这样的改变会被Vue检测到,并触发视图更新。 计算属性是一种更高级的属性,它可以根据依赖的数据动态计算出一个新的。计算属性可以通过get和set方法来定义。在计算属性的get方法中,你可以对数组对象进行处理,并返回一个新的。当依赖的数据发生变化时,计算属性会重新计算,并且只有在依赖的数据发生变化时才会触发视图更新。 总结起来,Vue中的计算属性可以用来处理数组对象属性变化,并且在依赖的数据发生变化时实时更新视图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值