与Vue对象数组的反应性

时间:2020-07-02 22:31:05

标签: vue.js reactive

希望您安全健康!

我正在研究vue定制组件,其中使用v-for渲染每个资产(子组件)的子卡。每个子卡都有一个复选框,该复选框与最终用户选择卡有关。

现在,父级具有全选和取消全选功能,可以选中/取消选中所有子卡。

我可能使用了错误的方法。但是selectAll和unselect All不会更新所选属性的状态。

父母补偿:

模板

<div class="cotent-wrapper">
  <div v-for="(item, index) in assetsList" :key="index">
    <asset-item :data="item" update-selction="updateSelectedAsset($event) ">
    </asset-item>
  </div>
</div>

脚本

data() {
   return {
      selectedAssets: []
   }
},
computed: {
   ...mapGetters({
      assetsList: 'AssetList'
   })
},
methods: {
        ...mapActions({
            fetchAssets: 'getContentDeliveryAssets'
        }),
        markAll: function(selected) {
            if (selected) {
                this.assetsList.forEach(item => item['selected'] = true)
            } else
                this.assetsList.forEach(item => item['selected'] = false)
        }
    }

子组件

模板

<div class="asset-card">
    <b-form-checkbox size="lg" v-model="sel" :id="data.asset_id" @change="updateSelection()"></b-form-checkbox>
    <div class="img-wrap "><img :src="data.asset_url" /></div>
</div>

脚本

data() {
        return {
            data: {},
            sel: false
        }
    },
    watch: {
        // eslint-disable-next-line
        data: {
            handle: function(newVal) { // watch it
                console.log(newVal)
                    // this.sel = newVal
            },
            deep: true
        }
    },

1 个答案:

答案 0 :(得分:0)

由于assetsList来自您的Vuex商店的AssetList吸气剂,因此您不应该进行直接更改。如果将Vuex设置为strict mode,实际上将开始引发错误。

相反,您应该为markAll创建一个变体,然后从您的组件中提交它。

例如

// store
export default new Vuex.Store({
  strict: true, // always a good idea
  state: {
    AssetList: [] // just guessing here
  },
  getters: {
    AssetList: state => state.AssetList // also guessing
  },
  mutations: {
    markAll: (state, selected) => {
      // it's best to treat state as immutable and assign new values
      // rather than try to change them
      state.AssetList = state.AssetList.map(item => ({
        ...item,
        selected
      }))
    }
  }
})

以及您的组件中

methods: {
  ...mapMutations(['markAll']),
  ...mapActions({
    fetchAssets: 'getContentDeliveryAssets'
  }
}

要处理单个项目的更改,显然您需要另一个突变

mutations: {
  markItem: (state, { item, selected }) => {
    const storeItem = state.AssetList.find(storeItem => storeItem === item)
    if (storeItem) storeItem.selected = selected
  },
  // markAll...
}

在您的子组件中,将计算属性与 getter setter 一起使用来处理更改事件

<b-form-checkbox
  size="lg"
  v-model="sel"
  :id="data.asset_id"></b-form-checkbox>
import { mapMutations } from 'vuex'
export default {
  props: { data: Object },
  computed: {
    sel: {
      get () { return this.data.selected },
      set (selected) { this.markItem({ item: this.data, selected }) }
    }
  },
  methods: mapMutations(['markItem'])
}