记一次element-ui源码修改,radio和checkbox兼容对象数组形式
首先要实现的需求:
后台返回的接口数据
{ "list": [ { "name": "副主任", //职务名称 "positionId": 8, //职位id "partyOrgName": "第三党支部", //组织名称 "partyOrgId": 3 //组织id } ], "name": "第三党支部", //组织名称 "partyOrgId": 3 //组织id }, { "list": [ { "name": "委员", "positionId": 3, "partyOrgName": "第二党支部", "partyOrgId": 2 }, { "name": "第一书记", "positionId": 5, "partyOrgName": "第二党支部", "partyOrgId": 2 }, { "name": "副主任", "positionId": 6, "partyOrgName": "第二党支部", "partyOrgId": 2 }, { "name": "第一书记", "positionId": 7, "partyOrgName": "第二党支部", "partyOrgId": 2 } ], "name": "第二党支部", "partyOrgId": 2 },
因为是二维数组的单选,所以采用radio-group的形式去做,aLLData存放全部的组织架构列表,把勾选的放在checkList里
<el-container class="select-container"> <div class="left-aside"> <div class="check-group" v-for="(item, index) in aLLData" :key="index"> <p>{{item.name}}</p> <el-radio-group v-model="checkedList[item.partyOrgId]" @change="groupChange"> <ul> <li v-for="(subItem,index) in item.list" :key="index"> <el-radio :label="subItem">{{subItem.name}}</el-radio> </li> </ul> </el-radio-group> </div> </div> <div class="middle-line"></div> <div class="right-main"> <p>请勾选职位</p> <ul class="selected-List"> <li class="select-item" v-for="(item,index) in checkedList" :key="index"> <p>{{item.partyOrgName}}-{{item.name}}</p> <i class="iconfont icon-shanchu" @click="delChecked(index)"></i> </li> </ul> </div> </el-container>
props:接受全部数据
props: { aLLData: { type: Array, default: [], }, },
data:checkList双向绑定被勾选的数据
data() { return { checkedList: {}, }; },
感觉很容易就实现了haha~~
再写一个删除方法就完工:
delChecked(index) { this.$delete(this.checkedList, index); },
原本以为这就结束了,然后编辑的时候需要回显,回显的时候radio-radio一直勾选不上
打开控制台,发现input value中已经有值了,但是input和label缺少一个is-checked
能成功切换到另一个并勾选
翻看radio的文档,发现只允许绑定string/number/boolean,并不支持对象的绑定
于是考虑修改element的源码,让其能够简单兼容对象的绑定
1.首先克隆项目,到本地
https://github.com/ElemeFE/element
2.npm/cnpm install安装依赖
3.打开element-dev下packages,radio,src下的radio.vue,可以看到is-checked绑定的就是model===label,然而两个同样的对象是否相等无法用===或者==判断
于是增加一个判断,把对象转换成string再判断一次:
4. 改好之后执行cnpm run dist,如果有报错可能是lint报错,打开package.json,找到dist命令,把里面的& lint删除再执行命令
"dist": "npm run clean && npm run build:file && webpack --config build/webpack.conf.js && webpack --config build/webpack.common.js && webpack --config build/webpack.component.js && npm run build:utils && npm run build:umd && npm run build:theme",
5.然后把生成的lib文件夹,整个替换到自己项目的nodel_modules的element-ui的lib文件夹(如果装有多个版本的element-ui,则需替换项目中package.json对应的版本中的lib)
6.再重新运行,发现已经OK了
7.补充一下:
后来发现公司用jenkins自动构建的时候会重新npm i下载全部依赖后构建,所以自己node_modules中的文件夹的修改并不起效果。。。
于是想了两个解决方案
一个是项目根目录新建一个native_modules文件夹,把修改好element-ui的lib文件夹放进这里,同时main.js文件对element-ui的引用换成如下,可以实现效果
import ElementUI from '@/../native_modules/element/lib/index.js';
另一个是直接给自己的改好的element-ui建一个npm,引用线上地址,也ok
<script src="https://cdn.jsdelivr.net/npm/garden-element-ui@1.0.0/lib/index.js"></script>
cdn加载各种依赖方法:在vue.config.js中的configureWebpack里的externals加上element-ui
configureWebpack: { name: name, resolve: { alias: { "@": resolve("src") } }, externals: { vue: 'Vue', "vue-router": "VueRouter", vuex: "Vuex", moment: "moment", axios: "axios", 'element-ui': 'ELEMENT', 'Qs': 'Qs', echarts: 'echarts', lodash: '_', } },