记录组件封装思路 实现ECharts 组件的封装
写在前面:对于愈来愈火的前端框架,用起来着实是让人很舒心。对于大型项目来说,组件化思想更是尤为重要,那么学会组件的封装自然是必不可少。本文浅谈一下封装组件的思路以及心得,希望对大家有所帮助。
每个组件需要的参数都很固定,包含:基本参数+独有参数
我们要做的就是:分离基本参数,父组件向子组件传递基本参数和独有参数
父组件传递的一般为基本参数,自身的参数为独有参数
根据假设场景,做相应处理
具体封装代码(ECharts.vue)
<template> <div style="height:100%" ref="echart"></div> </template> <script> import echarts from 'echarts'; export default { props: { // 接收父组件传递的ECharts 数据 chartData: { //定义出需要动态传递的参数 type: Object, default() { return { xData: [], series: [], }; }, }, isAxisChart: { type: Boolean, default: true, }, }, data() { return { //返回要渲染的数据 echart: null, //# 含坐标轴的图表 axisOption: { xAxis: { //x轴数据 type: 'category', data: [], }, yAxis: [ //y轴数据(根据series 中的date 渲染) { type: 'value', }, ], series: [], //数据渲染的结构 }, //# 不含坐标轴的图表 noAxisOption: { series: [], }, }; }, computed: { //计算属性判断 是否渲染坐标轴 options() { return this.isAxisChart ? this.axisOption : this.noAxisOption; } }, watch: { chartData: { handler() { this.initChart(); }, deep: true, // 需要deep属性对 对象进行深度监听 } }, methods: { initChart() { //# 初始化容器时,初始化数据 this.initChartData(); //初始化容器(图标) if (this.echart) { //若容器存在,直接渲染数据(官方api 写入配置) this.echart.setOption(this.options); } else { this.echart = echarts.init(this.$refs.echart); this.echart.setOption(this.options); } }, initChartData() { //初始化数据 if (this.isAxisChart) { //#把自身的数据替换成父组件传过来的数据 this.axisOption.xAxis.data = this.chartData.xData; this.axisOption.series = this.chartData.series; } else { this.noAxisOption.series = this.chartData.series; } }, }, }; </script> <style lang='less' scoped> </style>父组件代码:
<el-card shadow="hover"> <echart style="height:260px" :chartData="echartData.user"></echart> </el-card> <el-card shadow="hover"> <!-- 要用isAxisChart 来告诉子组件渲染的图表格式 --> <echart style="height:260px" :chartData="echartData.video" :isAxisChart = "false"></echart> </el-card>注意:对于 ECharts 组件中的参数格式,可根据 ECharts 官网进行配置—ECharts官网
优化后的 ECharts 组件
<template> <div style="height:100%" ref="echart"></div> </template> <script> import echarts from 'echarts'; export default { props: { // 接收父组件传递的ECharts 数据 chartData: { //定义出需要动态传递的参数 type: Object, default() { return { xData: [], series: [], }; }, }, isAxisChart: { type: Boolean, default: true, }, }, computed: { //计算属性判断 是否渲染坐标轴 options() { return this.isAxisChart ? this.axisOption : this.noAxisOption; }, collapse() { return this.$store.state.isCollapse; }, }, data() { return { //返回要渲染的数据 echart: null, //# 含坐标轴的图表 axisOption: { tooltip: { tirgger: 'item', }, legend: { textStyle: { color: '#333', }, }, xAxis: { //x轴数据 type: 'category', data: [], axisLine: { lineStyle: { color: '#33CC00', }, }, }, yAxis: [ //y轴数据(根据series 中的date 渲染) { type: 'value', }, ], // 配置展示数据的颜色 color: [ '#CC66FF', '#33FF00', '#663300', '#FF3300', '#999900', '#FFFF00', ], series: [], //数据渲染的结构 }, //# 不含坐标轴的图表 noAxisOption: { tooltip: { tirgger: 'item', }, legend: { textStyle: { color: '#333', }, }, color: [ '#CC66FF', '#33FF00', '#663300', '#FF3300', '#999900', '#FFFF00', ], series: [], }, }; }, watch: { chartData: { handler() { this.initChart(); }, deep: true, }, collapse() { setTimeout(this.listenResize, 300); // 监听折叠变量(实现折叠响应式变化图标) }, }, methods: { initChart() { //# 初始化容器时,初始化数据 this.initChartData(); //初始化容器(图标) if (this.echart) { //若容器存在,直接渲染数据(官方api 写入配置) this.echart.setOption(this.options); } else { this.echart = echarts.init(this.$refs.echart); this.echart.setOption(this.options); } }, initChartData() { //初始化数据 if (this.isAxisChart) { //#把自身的数据替换成父组件传过来的数据 this.axisOption.xAxis.data = this.chartData.xData; this.axisOption.series = this.chartData.series; } else { this.noAxisOption.series = this.chartData.series; } }, listenResize() { //# 监听浏览器尺寸,做出响应式展示 this.echart ? this.echart.resize() : ''; }, }, mounted() { // 挂载钩子,判断窗口大小 window.addEventListener('resize', this.listenResize); }, destroyed() { // 挂载卸载钩子,防止内存泄漏 window.removeEventListener('resize', this.listenResize); }, }; </script> <style lang='less' scoped> </style>注意:优化后的组件,新增了自定义颜色以及响应式的处理
对于大部分组件的封装与 ECharts 组件的封装大同小异,我们要找到基本参数,然后逐步解析,本文结束。