2

原文地址:http://mtmzorro.github.io/201...

项目背景

  • 需要兼容到IE7(根据数据支撑重要说服抛弃IE6)

  • 上个版本传统 jQuery DOM 开发模式,经过无数手维护已经惨不忍睹

  • 核心业务流程,可维护性、健壮性要求高

  • 主要业务逻辑流程单页内完成

接到这个项目改版规划之后,首先想到的是引入一个 MVVM 框架来解放对 DOM 的操作,上个版本基本就是因为应该其他部门多次插手开发后造成可维护性急剧下降。

最早是计划使用 VUE + VUEX 来重构此项目(之后确实自己重构了一把),考虑到之前 VUE 项目中对 IE8 以下还是有一些不可控的潜在坑,就把视线转移到了 avalon 这个可以支持到 IE6 的框架上

事实证明,avalon 很好的完成了此项任务,在业务逻辑增加的前提下,整体项目代码比之前缩减了60%。业务组件模块化拆分复用后整体可维护性也得到了很大提升。先赞一个!

当然凡事都有相对的一面,此篇文字就主要记录自己在项目过程中的一些问题。

问题List

官网提供的 2.2.4 avalon.js IE8 下报错

使用 https://cdn.staticfile.org/av... IE8下一直报错,最后通过到avalon github,下载所使用的2.2.4版本自己压缩打包后解决。

组件slot在 2.2.4 版本中和API文档中表现差异较大

  • 官方demo 组件 slot https://segmentfault.com/a/11... 2.1.17版本下就可以 之后的2.2.4 版本中 slot 内外就没有通信方式了(但切换低版本 组件方式就全变)。

  • 为此专门重写一个 avalon.extendComponent 方法来实现组件的继承和扩展,解决组件复用时局部自定义的需求。

// avalon extendComponent 组件继承扩展
// Thanks aLoNeIT https://github.com/aLoNeIT/flyUI
avalon.extendComponent = function (sComName, sComParentName, sSettings) {

    oDefaults = sSettings.defaults;
    sTemplate = sSettings.template;

    var oParent = avalon.components[sComParentName];
    if (!oParent) return; //不存在组件则直接退出
    sTemplate = sTemplate || null;
    oDefaults.$parents = {};
    avalon.each(oParent.defaults, function (key, value) {
        oDefaults.$parents[sComParentName + "_" + key] = value;
    });
    oDefaults.inherited = function (sPropertyName, sParentName, oParams) {
        if (avalon.isString(sPropertyName) && avalon.isString(sParentName) && this.$parents[sParentName + "_" + sPropertyName]) return this.$parents[sParentName + "_" + sPropertyName];
        else return null;
    }
    var oConfig = { //子组件配置项
        displayName: sComName,
        parentName: sComParentName,
        defaults: oDefaults
    };
    if (sTemplate) oConfig.template = sTemplate;
    oParent.extend(oConfig);
};

IE8一下 直接使用兼容过的JSON.stringfy 处理 avalon对象上的数据可能会返回 undefined

自定义如下扩展方法去除掉avalon自身对象属性

// avalon getOriginObject 
// 去除avalon对象上原型链方法 用于解决IE8 json stringfy 对象数据时异常
avalon.getOriginObject = function(data){
    var tempObj = {};
    for(var i in data) { 
        if(data.hasOwnProperty(i)){
            tempObj[i] = data[i];
        }
    }
    return tempObj;
}

component 中模板只支持最外层一个html闭合结构 同级多个无法渲染

其实这个问题参考 VUE2.0 也要求组件模板最外层只有一个顶级标签

// OK 
avalon.component('ms-process-quick', {
        template: '<div></div>'
})        
  // 第二个div不会渲染      
avalon.component('ms-process-quick', {
        template: '<div></div><div></div>'
})      

for循环的模板中 外层有:class 内部判断时 循环内部的if会出现重复渲染(非必先,排除法才找到问题冲突点)

如下面的代码,外层class存在判断:class="@item.setGreyWhenBankInMaintence ? \'\' : \'test\'",造成<i :if="@item.debit">储蓄卡</i> <i :if="@item.credit">信用卡</i> 重复渲染两次。

'            <li data-order="3" class="pl-item" :class="@item.setGreyWhenBankInMaintence ? \'\' : \'test\'">',
'                <span :attr="{id: \'bank-\' + @item.bankCode.toLowerCase()}" class="bank-logo">{{@item.bankName}}</span>',
'                <em class="pl-i-info">',
'                   <i :if="@item.debit">储蓄卡</i>',
'                   <i :if="@item.credit">信用卡</i>',
'                </em>',
'            </li>',

IE浏览器(9、10、11)中 input password 类型在 display none的元素内,不完全重现,尽量考虑规避

IE浏览器(9、10、11)中 在input select 等form元素上 使用 if 有潜在的 avalon报错崩溃风险,尽量避免


mTmzorro
60 声望0 粉丝

console.log('什么都不如有颗向上乐观的心');