背景
是在某次APP更新,需要完成订单里面,批量商品的评价功能。其实之前也写过类似的界面,不过因为需要评价的事物,是固定一个的,所以页面布局也是写死的,而现在是由后台动态传过来的未知数量,需要js动态生成待评价的商品模块。
问题分析
根据VUE2.X版本:“受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的”。
所以我在实现这个业务的过程中,就遇到了数据已经重新赋值了,但是dom没有刷新的问题。经过查询资料以及短暂的思考,大概思路如下:先获取到所有的商品数据,比如productList
,然后每次修改的时候,深度克隆一个对象比如tempList
,根据传过来的角标值修改tempList
的属性,接着通过Vue.$set
方法,将tempList
赋值给productList
,最后视图成功更新。
代码梳理
定义深度克隆的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| metheds: { deepClone: function (original, target){ var target = target || {}; for(var prop in original){ if(original.hasOwnProperty(prop)){ if(typeof original[prop] === 'object'){ if(Object.prototype.toString.call(original[prop]) === '[object Array]'){ target[prop] = []; }else{ target[prop] = {}; } this.deepClone(original[prop],target[prop]); }else{ target[prop] = original[prop]; } } } return target; } }
|
获取到订单商品数据
bigRate
方法是在点击星星,然后给商品评分的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| created: { this.init(); } methods: { init: function () { var _this = this; _this.productList = _this.orderData.goods; _this.productList.forEach(function(item){ item["score"] = 0; }); } bigRate: function (index2,index) { var _this = this; var m = _this.deepClone(_this.productList[index]); m.score = index2 + 1; vm.$set(vm.productList, index, m) } }
|
问题
在写这篇博文的时候,我突然想起来,貌似前端代码还是不够严谨,因为后台传来的对象个数是动态的,现在数据量小,一个订单下面顶多挂十来个商品,如果是一百多个商品(后台在下单环节并没有做商品种类数量的限制),一是不知道现在页面会不会有问题;二是,如果如果要分页,就需要动态更新productList
,要多加个事件。
刚就该问题,咨询了公司的产品,他回复是他自己也没具体思考过这个事情,不过据说某东的做法,就是如果商品过多,评论页会进行分页评论。然而打开APP,发现某东现在改版了,现在的业务是直接按照单个商品的种类进行评论的————那么问题来了,若是在某东上买十双鞋,难不成我要评论十次啊 :fearful:
小结
周一开始关注VUE3.0的消息,正好关于这个问题进行了改进,点赞 :laughing:,很期待新版本的到来。
”2.x的响应式是基于Object.defineProperty实现的代理,兼容主流浏览器和ie9以上的ie浏览器,能够监听数据对象的变化,但是监听不到对象属性的增删、数组元素和长度的变化,同时会在vue初始化的时候把所有的Observer都建立好,才能观察到数据对象属性的变化。
针对上面的问题,3.0进行了革命性的变更,采用了ES2015的Proxy来代替Object.defineProperty,可以做到监听对象属性的增删和数组元素和长度的修改,还可以监听Map、Set、WeakSet、WeakMap,同时还实现了惰性的监听,不会在初始化的时候创建所有的Observer,而是会在用到的时候才去监听。但是,虽然主流的浏览器都支持Proxy,ie系列却还是不兼容,所以针对ie11,vue3.0决定做单独的适配,暴露出来的api一样,但是底层实现还是Object.defineProperty,这样导致了ie11还是有2.x的问题。但是绝大部分情况下,3.0带来的好处已经能够体验到了。
响应式方面,vue3.0做了实现机制的变更,采用ES2015的Proxy,不但解决了vue2.x中的问题,还是得性能有了进一步提升。虽然有一些兼容问题,但是通过适配的方式解决掉了。此外,还暴露了observable的api来创建响应式对象,可以替代掉event bus,来做一些跨组件的通信。”
还有个就是,我还没有深入了解深度克隆的含义,晚上回去要好好学习下这个概念。
参考文章