前言
前文联动修改通过深层遍历匹配方式去解决,若表达内容庞大复杂就会显得很繁琐,而且性能不高。为解决这一问题,考虑通过订阅发布的方式去触发相关联动的改变。
改进内容
修改数据结构
1、添加option用于携带自身相关属性;
2、triggers为联动数组(便于绑定多个内容),用于联动相关元素,发布事件;
3、action为订阅内容,监听相应事件,修改自身状态
<template>
<div class="call_status">
<HdfComponent v-for="(item,index) in treeData" :key="index" :itemData="item"></HdfComponent>
</div>
</template>
<script>
import HdfComponent from './components/HdfComponent.vue'
export default {
data(){
return {
treeData:[{
name: 'name',
type: 'HdfComp',
label: '医生姓名',
options: {
value: '',
status: '1',
content: '',
child: [{
name: 'name',
type: 'HdfInput',
label: '医生姓名',
options: {
value: '',
status: '1',
content: '',
child: '',
triggers: [],
action: ''
}
}],
triggers: [],
action: ''
}
},{
name: 'sex',
type: 'HdfRadio',
label: '性别',
options: {
value: '',
status: '1',
content: [{
label: '男',
value: 1
},{
label: '女',
value: 0
}],
child: '',
triggers: ['isPregnant','edc1'],
action: ''
}
},{
name: 'area',
type: 'HdfInput',
label: '地区',
options: {
value: '',
status: '1',
content: '',
child: '',
triggers: [],
action: ''
}
},{
name: 'height',
type: 'HdfInput',
label: '身高',
unit: '厘米',
options: {
value: '',
status: '1',
content: '',
child: '',
triggers: [],
action: ''
}
},{
name: 'isPregnant',
type: 'HdfRadio',
label: '是否孕期',
options: {
value: '',
status: '0',
content: [{
label: '是',
value: 1
},{
label: '否',
value: 0
}],
child: '',
triggers: ['edc'],
action: `
this.$EventBus.$on('isPregnant', (data) => {
if(data === 0){
this.itemData.options.status = '1'
}else{
this.itemData.options.status = '0'
}
})
`
}
},{
name: 'edc',
type: 'HdfDatePicker',
label: '预产期',
options: {
value: '',
status: '0',
content: '',
child: '',
triggers: [],
action: `
this.$EventBus.$on('edc', (data) => {
if(data === 1){
this.itemData.options.status = '1'
}else{
this.itemData.options.status = '0'
}
})
this.$EventBus.$on('edc1', (data) => {
if(data === 1){
this.itemData.options.status = '0'
}
})
`
}
}]
}
},
components: {
HdfComponent
}
}
</script>
联动处理
1、订阅内容通过字符串的形式绑定,需要eval解析为代码;
2、遍历triggers依次发布相关事件进行触发。
<template>
<div>
<component class="itemContent" v-bind:is="itemData.type" @event1="change($event)" v-if="itemData.options.status==='1'" v-model="itemData"></component>
</div>
</template>
<script>
import moduleComponents from '../util/getBasicArr.js';
export default {
name: 'HdfComponent',
props:{
itemData:{
default: () => ({}),
type: Object
}
},
mounted(){
if(this.itemData.options.action){
eval(this.itemData.options.action)
}
},
methods: {
change(data) {
const triggers = this.itemData.options.triggers
if(triggers.length > 0){
triggers.forEach(item => {
this.$EventBus.$emit(item, data)
})
}
}
},
components: moduleComponents
}
</script>
<style lang="scss" scoped>
.itemContent{
padding: 10px;
}
</style>