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的使用。
注: 本文用于项目功能开发,仅供参考学习