重构设备操作弹出框
设备总共有40多个一级类型 80多个二级类型 每个一级类型的操作各不相同,二级类型的操作也有细微的不同 后续可能还会增加设备 公司之前的代码多达2w行 现在已成shi山 代码也基本告别了复用,template 充斥这大量的v-else-if 也难以维护 现在有两处要使用设备操作弹出框 复用已经根本不切实际 唯有重构
说说之前代码弊病
二级类型直接写成一个数组通过indexof去匹配设备
举个例子
现有两个设备
-
灯
-
普通灯
操作 开\关\配对
-
冷暖灯
操作 开\关\配对\亮度\色温
-
-
空调
-
普通空调
开\关\温度\配对\模式\风速
-
。。。。
到底该如何重构,因为之前学习过react瞬间相当了jsx 再结合vue官网cn.vuejs.org/v2/guide/re… 于是乎果断使用了jsx,使用方法、依赖请参考github.com/vuejs/jsx
说干就干
-
封装dialog
//index.jsx
props: {
dialogVisible: Boolean
deviceInfo:Object //设备info 应当存在 一级类型 二级类型 设备id
},
render(h){
const component = deviceOperationGenerator(h,devFirstType,devSecondType,jdlDeviceId)
// js的弊病出现了 没有类型约束 还得学ts 封装一个打印信息函数 思路:判断deviceInfo 是否存在一级类型 二级类型 设备id 如上不存在应该console.error()
return (
<el-dialog>
{conmponent}
</el-dialog>
)
}
-
实现核心
//core.js deviceOperationGenerator
const deviceOperationGenerator = function(h,devFirstType,devSecondType,jdlDeviceId){
// 策略模式 判断一级类型 根据一级类型进入二级类型 当增加一级类型只需按照这个的代码规范即可
const components = {
1:() => switchGenerator(h,devSecondType,jdlDeviceId),
2:() => scoketGenerator(h,devSecondType,jdlDeviceId),
3:() => doorLockGenertor(h,devSecondType,jdlDeviceId),
4:() => airConditionerGenertor(h,devSecondType,jdlDeviceId),
6:() => curtainGenertor(h,devSecondType,jdlDeviceId),
8:() => securityGatewayGenerator(h,devSecondType,jdlDeviceId),
10:() => infraredAlarmGenertor(h,devSecondType,jdlDeviceId),
17:() => controlBoxGenertor(h,devSecondType,jdlDeviceId),
23:() => lampGenerator(h,devSecondType,jdlDeviceId),
31:() => adjustingLampGenertor(h,devSecondType,jdlDeviceId),
notfound:<div style="color:green;font-size:16px;">功能正在加紧开发敬请稍后...</div>
}
// 容错处理
if(components[devFirstType]){
return components[devFirstType]
}
return components['notfound']
}
export default deviceOperationGenerator
-
二级类型函数实现 跟一级类型类似
略
-
使用混入+slot减少重复代码
tips: 这里也出现了js的弊病 没有类型约束 只有通过约定了 我在设备弹窗那个组件写了README.md
//基础组件 窗帘
<template>
<div>
<div class="flex">
<el-button type="primary" @click="clickBtn('开')">开</el-button>
<el-button type="primary" @click="clickBtn('关')">关</el-button>
<el-button type="primary" @click="clickBtn('暂停')">暂停</el-button>
<slot name="button"/>
</div>
<div>
<slot name="slider"/>
</div>
</div>
</template>
<script>
import { simpleOperationMixin } from '../mixin'
export default {
props:{
deviceId:Number
},
mixins:[simpleOperationMixin]
}
</script>
<style scoped>
.flex{
display: flex;
}
</style>
//基于基础组件实现增加其他控制
<template>
<Curtain :deviceId="deviceId">
<div slot="button" style="margin-left:10px">
<el-button type="primary" @click="clickBtn('正装')">正转</el-button>
<el-button type="primary" @click="clickBtn('反转')">反转</el-button>
<el-button type="primary" @click="pair">配对</el-button>
</div>
<div slot="slider">
<el-form label-position="right" >
<el-form-item label-width="130px" label="转速调整:">
<el-slider @change="changeSlider" v-model="form.devPercentage" :max="99" :min="1" :step="10" style="width: 80%">
</el-slider>
</el-form-item>
</el-form>
</div>
</Curtain>
</template>
<script>
import Curtain from './curtain.vue'
import { simpleOperationMixin,sliderMixin } from '../mixin'
export default {
props:{
deviceId:Number
},
components:{
Curtain
},
mixins:[simpleOperationMixin,sliderMixin],
data(){
return {
form:{
devId:this.deviceId,
devPercentage:50
}
}
}
}
</script>