vue2.0项目实战--$set的正确使用及类似购物车的功能开发

vue项目开发过程中,遇到一个需要开发类似购物车的功能,需要根据后台返回数据中对象的一个标识来判断当前数据是否选中,并根据这个标识去删除对应的数据,同时控制操作的icon在不同状态展示不同的样式,如下图:

后台接口并不会返回对应的标识,这时我想到了自己动态给这条数据添加一个属性 flag 用来判断:

<Col :span="2">
    <span v-if="!item.flag" class="app__icon-btn app__icon-plus" @click='channelClick(item)'></span>
    <span v-if="item.flag" class="app__icon-btn app__icon-choose" @click='channelClick(item)'></span>
</Col>
channelClick(item) {
    this.$set(item,'flag','Y');
    //item.flag = 'Y';
    this.offerChannel.push(item);
},

写这个事件的过程中,开始用的是item.flag = 'Y',发现选中列表数据并没与实时刷新,这时我查了一些资料发现这种方式不对,换成

this.$set(item,'flag','Y');
就可以了。深度了解了一下:

直接给数据对象新增属性,并赋值操作,虽然可以新增属性,但是不会触发视图更新,如下:

mounted () {
    this.item.flag= 'Y'
}

原因是:受 ES5 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

要处理这种情况,我们可以使用$set()方法,既可以新增属性,又可以触发视图更新。

但是,值得注意的是,网上一些资料写的$set()用法存在一些问题,导致在新接触这个方法的时候会走一些弯路!

错误写法:this.$set(key,value)(ps: 可能是vue1.0的写法)

mounted () {
    this.$set(this.item.flag, 'Y')
}

正确写法:this.$set(this.data,”key”,value’)

mounted () {
    this.$set(this.item,'flag', 'Y')
}

 

这个写法当时的项目很多地方用到,当然这种控制状态还有别的方式,用过滤来判断已选列表的这条数据在未选列表是否存在,如下:

<Col :span="2">
    <span :class="[policySel('rule',item) ? 'app__icon-btn app__icon-choose' : 'app__icon-btn app__icon-plus']"  ></span>
</Col>
policySel(val){
    return this.policyTemplateObjChoose.filter(item => item.policyTemplateCode == val.policyTemplateCode)[0] ? true : false;
},

实现的效果是一样的,但是可以避免$set的使用。

注: 本文用于项目功能开发,仅供参考学习






posted @ 2018-11-23 15:43  望兰鸟  阅读(781)  评论(0编辑  收藏  举报