背景:按钮是通用组件,与页面是分离的。整个页面分为上下两个部分。放大效果是由Element中的Collapse折叠面板扩展来的。
- 状态有几种?
- 页面如何获得当前状态?
- 状态最终如何转递到按钮。
观察扩展组件drilldown-tabs-view,上半部分只有一级父组件;下半部分有多级。
按钮状态 | 顶部页面参数 | 底部页面参数 |
---|---|---|
disabled(禁用) | 底部没有tab情况 | 无 |
Enlarge (放大) | 底部有tab并且上下各占一半页面 | 上下各占一半页面 |
Zoom-out(缩小) | 底部有页面并且,顶部为放大的状态 | 底部为放大的状态 |
- 问题1:有几种状态?
通过以上逻辑可以得出:决定顶部状态的参数有二。一是tab的有无;二是顶部页面放大或缩小。由于底部有状态必须是在tab存在的前提条件下,所以,决定底部状态的参数只有底部页面放大或缩小。将以上表格转换为:
按钮状态 | 顶部页面参数 | 底部页面参数 |
---|---|---|
disabled(禁用) | tabs.length === 0 | 无 |
Enlarge (放大) | activeNames.length === 2 && tabs.length > 0 | this.activeNames.length === 2 |
Zoom-out(缩小) | activeNames.length === 1 && tabs.length > 0 | this.activeNames.length === 1 |
- 问题2:页面如何获得当前状态?
页面是放大还是缩小的状态取决于activeNames数组。而最终可以确定该数组的值是在drilldown-tabs-view这个组件中。 drilldown-tabs-view组件中是由一个x-collapse组成,上半部分是一个插槽。也就是说drilldown-tabs-view组件可以通过 $emit给父组件抛出一个事件并把我们需要的值传递过去;而下半部分是一个component-link-tab组件,component-link-tab里面又包了层component组件,再下一级才是下半部分的页面。所以如果要获取到状态值,可以给component-link-tab组件添加一个属性,通过这个属性将activeNames传到页面。
- 问题3:状态最终如何转递到按钮。
由于按钮是封装到toolbar组件中的,由toolbar通过获取配置文件的属性值,自动生成按钮。所以,可以通过toolbar中的trigger()方法将值传递到EmitEventButton中
- 配置按钮状态:
在mock_toolbar_metadata.js文件中设置按钮Enlarge
Enlarge: { id: 'enlarge', widget: 'emitEvent', position: 'right', label: '', type: 'primary', size: 'mini', tooltipDisabled: false, tooltipPlacement: 'bottom', tooltipEffect: 'dark', collapseStatus: { dis_icons: { icon: 'el-icon-zoom-out', tooltipContent: 'Zoom_Out' }, enl_icons: { icon: 'el-icon-zoom-in', tooltipContent: 'Enlarge' }, zoom_icons: {icon: 'el-icon-zoom-out', tooltipContent: 'Zoom_Out'} }
关键参数:
id: 'enlarge', widget: 'emitEvent', collapseStatus: { dis_icons: { icon: 'el-icon-zoom-out', tooltipContent: 'Zoom_Out' }, enl_icons: { icon: 'el-icon-zoom-in', tooltipContent: 'Enlarge' }, zoom_icons: {icon: 'el-icon-zoom-out', tooltipContent: 'Zoom_Out'} }
- 顶部页面获取按钮状态
drilldown-tabs-view组件中activeNames和tabs.legth被修改就抛出事件并将传递修改后的值,代码实现:
created () {
this.emitEventHandler('tab_length_change', this)
},
handleHeaderTop () {
const only_top = ['1']
const top_bottom = this.tabs.length > 0 ? ['1', '2'] : ['1']
this.activeNames = this.activeNames.length === 1 ? top_bottom : only_top
this.emitEventHandler('tab_length_change', this)
}
watch: {
'tabs.length': {
immediate: false,
handler: function (val, oldVal) {
if (val === 0) {
this.activeNames = ['1']
}
this.emitEventHandler('tab_length_change', this)
}
}
}
顶部页面监听事件tab_length_change执行collapse_change方法,代码实现
<drilldown-tabs-view ref="drilldownTabsView" :mainViewHeight="height[0]" :tabsViewHeight="height[1]" @tab_length_change="collapse_change">
collapse_change (instance) {
const activeNames = instance.activeNames
const tabs = instance.tabs
// 设置上折叠板3种状态
if (activeNames.indexOf('1') === -1) {
return
} else {
if (tabs.length === 0) {
this.collapseStatus = 'dis_icons'
} else if (activeNames.length === 2 && tabs.length > 0) {
this.collapseStatus = 'enl_icons'
} else if (activeNames.length === 1 && tabs.length > 0) {
this.collapseStatus = 'zoom_icons'
}
}
if (this.toolbar && this.toolbar[0] && this.toolbar[0].id) {
if (this.$refs[this.toolbar[0].id]) {
this.$refs[this.toolbar[0].id].trigger('enlarge', 'setIcon', this.collapseStatus)
}
}
}
- 按钮setIcon方法实现:
<template>
<click-button :type="type"
:icon="icon || icons"
:loading="loading"
:disabled="disabled || internalDisabled"
:plain="plain"
:round="round"
:circle="circle"
:size="size"
:label="$label ? $t($label) : label"
:tooltip-disabled="tooltipDisabled"
:tooltip-content="$t(tooltipInternalContent) || $t(Tooltip_Internal_Content)"
:tooltip-placement="tooltipPlacement"
:tooltip-effect="tooltipEffect"
@click="click"></click-button>
</template>
setIcon (status) {
if (status === 'dis_icons') {
this.internalDisabled = true
} else {
this.internalDisabled = false
}
this.icons = this.collapseStatus[status].icon
this.Tooltip_Internal_Content = this.collapseStatus[status].tooltipContent
}
- 底部设置状态值
监听父组件传递的属性值,属性值发生变化时,修改按钮状态值并传递给按钮
'instance': {
immediate: false,
handler: function (val) {
this.activeNames = val
this.collapse_change()
}
}
collapse_change () {
// 设置折叠板2种状态
if (this.activeNames.indexOf('2') === -1) {
return
} else {
if (this.activeNames.length === 2) {
this.collapseStatus = 'enl_icons'
} else if (this.activeNames.length === 1) {
this.collapseStatus = 'zoom_icons'
}
}
if (this.toolbar && this.toolbar[0] && this.toolbar[0].id) {
if (this.$refs[this.toolbar[0].id]) {
this.$refs[this.toolbar[0].id].trigger('enlarge', 'setIcon', this.collapseStatus)
}
}
}
注意:页面根据不同性质都设置了按钮的默认值,页面首次进入不存在属性值变化,导致toolbar接收不到当前状态值。可以使用以下方式解决改问题:
mounted () {
this.$nextTick(() => {
this.load_data()
if (this.toolbar && this.toolbar[0] && this.toolbar[0].id) {
if (this.$refs[this.toolbar[0].id]) {
this.$refs[this.toolbar[0].id].trigger('enlarge', 'setIcon', this.collapseStatus)
}
}
})
},
最终效果: