下图是初版,火山图的代码。可以看出,里面的变量,逻辑,函数存在冗余,基本上都是改了参数,同样的get和set,去刷新图表;对于往后继续开发十几二十个图表,会很麻烦。因此需要将这一些基本配置:字体,颜色,样式,大小,下拉色卡 / Vuex的相关参数,方法进行代码封装。
- 封装
fontSetting
组件,将图表标题,x轴标题,y轴标题,x轴标签,y轴标签的自定义配置,进行统一管理
vue"><!--父组件使用fontSetting-->
<!--传入参数:chart-type:用于判断图表类型,如果是饼图是没有x,y轴的相关参数的settings:echarts的一些配置信息,具体来说就是一个对象里面,包含了之前的所有”fontSize, fontFamily ... ...“
-->
<font-settings :chart-type="'GeenLen'" :settings="geenLenOptions.settings" /><!--子组件,fontSetting.vue-->
<div class="itemList"><div class="item" v-for="(item, index) in fontSettings" :key="index"><div class="font-title">{{ item.label }}</div><div class="font-controls"><div class="control-item" v-if="item.textKey"><span>文本:</span><el-inputv-model="settings[item.textKey]"size="medium"@input="value => handleFontChange(item.textKey, value)"></el-input></div><div class="control-item"><span>字体:</span><el-selectv-model="settings[item.familyKey]"size="large"@change="value => handleFontChange(item.familyKey, value)"><el-optionv-for="font in fontFamilies":key="font.value":label="font.label":value="font.value"></el-option></el-select></div><div class="control-item"><span>大小:</span><el-input-numberv-model="settings[item.sizeKey]":min="8":max="72"size="medium"@change="value => handleFontChange(item.sizeKey, value)"></el-input-number></div><div class="control-item"><span>颜色:</span><el-color-pickerv-model="settings[item.colorKey]"size="medium"@change="value => handleFontChange(item.colorKey, value)"></el-color-picker></div><div class="control-item"><span>样式:</span><el-switchv-model="settings[item.styleKey]"active-value="italic"inactive-value="normal"active-text="斜体"@change="value => handleFontChange(item.styleKey, value)"></el-switch></div></div></div>
</div>
//子组件的相关参数和方法
//接收父组件的传值
props: {settings: {type: Object,required: true},chartType: {type: String,required: true}
},
//自定义参数配置
data() {return {fontSettings: [{ label: '图表标题',textKey: 'title',familyKey: 'titleFontFamily',sizeKey: 'titleFontSize',colorKey: 'titleFontColor',styleKey: 'titleFontStyle'},{ label: 'X轴标题',textKey: 'xAxisTitle',familyKey: 'xAxisTitleFontFamily',sizeKey: 'xAxisTitleFontSize',colorKey: 'xAxisTitleFontColor',styleKey: 'xAxisTitleFontStyle'},{ label: 'Y轴标题',textKey: 'yAxisTitle',familyKey: 'yAxisTitleFontFamily',sizeKey: 'yAxisTitleFontSize',colorKey: 'yAxisTitleFontColor',styleKey: 'yAxisTitleFontStyle'},{ label: 'X轴标签字体',familyKey: 'xAxisLabelFontFamily',sizeKey: 'xAxisLabelFontSize',colorKey: 'xAxisLabelFontColor',styleKey: 'xAxisLabelFontStyle'},{ label: 'Y轴标签字体',familyKey: 'yAxisLabelFontFamily',sizeKey: 'yAxisLabelFontSize',colorKey: 'yAxisLabelFontColor',styleKey: 'yAxisLabelFontStyle'}],fontFamilies: [{ label: 'Arial', value: 'Arial' },{ label: 'Times New Roman', value: 'Times New Roman' },{ label: '微软雅黑', value: 'Microsoft YaHei' },{ label: '宋体', value: 'SimSun' },{ label: '黑体', value: 'SimHei' }]};
},
//判断哪些图表不需要x/y轴配置
mounted() {if (this.chartType === 'GeenLen') {this.fontSettings = this.fontSettings.filter(item => item.label == '图表标题');}
},methods: {...mapActions('echartEncapsulation', ['updateStyle', 'setOptions', 'setSetting']),handleFontChange(key, value) {//change事件触发时,更新父组件的settings对象,并且将修改后的值更新到Vuex中this.$emit('update:settings', {...this.settings,[key]: value});this.updateStyle({target: 'readsRegion',key,value});}
}
//vuex
updateStyle({ commit }, { key, value }) {commit('SET_STYLE', { key, value });
},
SET_STYLE(state, { key, value }) {state.insertSizeOptions.settings[key] = value;
},
封装色卡组件
colorList
,实现在多个图表中,切换整体色系风格。色卡选择器的代码和上一篇博文是一致的,区别就是:传入chart-type
参数,用于触发不同的事件回调函数。
this.$emit(``change${this.chartType},
selectedColors.colors);
vue"><!--父组件使用colorList-->
<ColorList :chart-type="'GeenLen'" @changeGeenLen="handleColorChange"></ColorList>
<!--兄弟组件中,对于$emit触发的函数,进行处理-->
this.$bus.$on('updateColorGoBar', (colors) => {this.colorList = colors
});
beforeDestroy() {
// 组件销毁前移除事件监听this.$bus.$off('updateColorGoBar');
},
vue"><!--子组件colorList-->
<template><div class="color-template-select"><el-selectv-model="selectedValue":placeholder="placeholder"@change="handleTemplateChange":style="{ width: width }"ref="selectRef"><el-optionv-for="(template, index) in colorTemplates":key="index":label="template.name":value="template.name"><div style="display: flex; gap: 5px"><divv-for="(color, colorIndex) in template.colors":key="colorIndex"class="color-box":style="{backgroundColor: color,width: '20px',height: '20px',}"></div></div></el-option></el-select></div>
</template><script>
export default {name: 'ColorTemplateSelect',props: {width: {type: String,default: '250px'},placeholder: {type: String,default: ''},chartType: {type: String,default: ''}},data() {return {selectedValue: '',selectSVG: '',colorTemplates: [],},],};},mounted() {const defaultColors = this.colorTemplates[0].colors;// this.$emit('changeGoBar', defaultColors);this.$emit(`change${this.chartType}`, defaultColors);this.getSvgString(defaultColors);},methods: {handleTemplateChange() {const selectedColors = this.colorTemplates.find((template) => template.name === this.selectedValue);if (selectedColors) {// console.log(this.chartType,"-----");this.$emit(`change${this.chartType}`, selectedColors.colors);// this.$emit('changeGoBar', selectedColors.colors);this.selectedValue = "";this.getSvgString(selectedColors.colors);}},}
};
</script>
- 全局更新
this.$store.dispatch("echartEncapsulation/setSetting", {target: "goBar",settings: initialSettings,
});
setSetting({ commit }, { target, settings }) {commit('SET_SETTINGS', { target, settings });
}
SET_SETTINGS(state, { target, settings }) {state[`${target}Options`].settings = settings;
}
相当于此前,一个图表的配置,相关函数,重复逻辑可能会有上千行,如果存在十几二十个图表,对于后期维护极差,在封装后,基本能够减少80%的代码量,并且减少后续开发投入的精力