[{"data":1,"prerenderedAt":118},["ShallowReactive",2],{"content:\u002Fposts\u002F2024\u002Fchart-echarts-in-vue2-component":3,"surround:\u002Fposts\u002F2024\u002Fchart-echarts-in-vue2-component":107},{"id":4,"title":5,"body":6,"canonical":86,"categories":87,"date":89,"description":90,"draft":91,"extension":92,"image":93,"meta":94,"navigation":95,"path":96,"permalink":86,"readingTime":97,"recommend":86,"references":86,"seo":102,"sitemap":103,"stem":104,"tags":105,"type":86,"updated":89,"__hash__":106},"content\u002Fposts\u002F2024\u002Fchart-echarts-in-vue2-component.md","ECharts 在 vue2 中的实践",{"type":7,"value":8,"toc":74},"minimark",[9,14,21,25,36,39,42,49,58,62,65,68],[10,11,13],"h2",{"id":12},"封装-echarts-容器组件","封装 ECharts 容器组件",[15,16,17],"p",{},[18,19,20],"strong",{},"监听图表大小变化使用了 ResizeObserver 函数监听容器大小变化，变化时调用 chart.resize() 重新渲染图表。",[22,23,24],"h3",{"id":24},"监听图表大小变化的代码",[26,27,33],"pre",{"className":28,"code":30,"language":31,"meta":32},[29],"language-js","\u002F\u002F 监听容器大小变化，实现图表自适应\nconst resizeObserver = new ResizeObserver((entries) => {\n    console.log(entries, \"容器大小变化\")\n    this.chart.resize()\n})\nresizeObserver.observe(this.$refs.container)\n","js","",[34,35,30],"code",{"__ignoreMap":32},[22,37,38],{"id":38},"容器组件完整代码",[15,40,41],{},"防抖节流函数",[26,43,47],{"className":44,"code":45,"language":31,"meta":46},[29],"\u002F\u002F 函数防抖\nfunction debounce(fn, wait = 500) {\n    let timeout = null\n    return function () {\n        \u002F\u002F eslint-disable-next-line prefer-rest-params\n        const args = arguments\n        if (timeout !== null)\n            clearTimeout(timeout)\n        timeout = setTimeout(() => {\n            fn.apply(this, args)\n        }, wait)\n    }\n}\n\n\u002F\u002F 函数节流\nfunction throttle(fn, delay = 500) {\n    let lastTime\n    let timer\n    return function () {\n        \u002F\u002F eslint-disable-next-line prefer-rest-params\n        const args = arguments\n        \u002F\u002F 记录当前函数触发的时间\n        const nowTime = Date.now()\n        if (lastTime && nowTime - lastTime \u003C delay) {\n            clearTimeout(timer)\n            timer = setTimeout(() => {\n                \u002F\u002F 记录上一次函数触发的时间\n                lastTime = nowTime\n            }, delay)\n        }\n        else {\n            lastTime = nowTime\n            fn.apply(this, args)\n        }\n    }\n}\nexport { debounce, throttle }\n","DebounceThrottle.js",[34,48,45],{"__ignoreMap":32},[26,50,56],{"className":51,"code":53,"language":54,"meta":55},[52],"language-html","\u003Ctemplate>\n  \u003Cdiv class=\"container\" ref=\"container\">\u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\n  import * as echarts from \"echarts\"\n  import { SVGRenderer, CanvasRenderer } from \"echarts\u002Frenderers\"\n  import { debounce } from \".\u002Futils\u002FDebounceThrottle.js\"\n\n  echarts.use([SVGRenderer, CanvasRenderer])\n\n  export default {\n    data() {\n      return {\n        chart: null,\n        resizeObserver: null,\n      }\n    },\n    props: {\n      options: {\n        type: Object,\n        default: () => {},\n        required: true,\n      },\n      render: {\n        type: String,\n        default: \"canvas\",\n        required: false,\n        validator(type) {\n          return [\"canvas\", \"svg\"].includes(type)\n        },\n      },\n    },\n    watch: {\n      options: {\n        handler(newOptions) {\n          console.log(\"options update\")\n          this.chart.setOption(newOptions)\n        },\n        deep: true,\n      },\n    },\n    methods: {},\n    mounted() {\n      this.chart = echarts.init(this.$refs.container, null, {\n        render: this.render,\n        locale: \"ZH\",\n        useDirtyRect: true,\n      })\n      this.chart.setOption(this.options)\n\n      \u002F\u002F 监听容器大小变化，实现图表自适应\n      if (window.ResizeObserver) {\n        this.resizeObserver = new ResizeObserver(\n          debounce((entries) => {\n            console.log(entries, \"容器大小变化\")\n            this.chart.resize()\n          })\n        )\n        this.resizeObserver.observe(this.$refs.container)\n      }\n    },\n    beforeDestroy() {\n      console.log(\"销毁\")\n      if (this.chart) {\n        this.chart.dispose()\n      }\n      if (window.ResizeObserver && this.resizeObserver) {\n        this.resizeObserver.unobserve(this.$refs.container)\n      }\n    },\n  }\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"less\" scoped>\n  .container {\n    width: 100%;\n    height: 100%;\n  }\n\u003C\u002Fstyle>\n","html","ChartContainer.vue",[34,57,53],{"__ignoreMap":32},[10,59,61],{"id":60},"使用-echarts-容器组件","使用 ECharts 容器组件",[15,63,64],{},"组件内部监听外部传入数据变化，变化后使用 watch 更新 options。",[22,66,67],{"id":67},"圆环图表示例代码",[26,69,72],{"className":70,"code":71,"language":54,"meta":32},[52],"\u003Ctemplate>\n  \u003CChartContainer :options=\"options\" \u002F>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\n  import ChartContainer from \".\u002FChartContainer.vue\"\n  export default {\n    components: {\n      ChartContainer,\n    },\n    props: {\n      pData: {\n        type: Array,\n        default: [],\n        required: false,\n      },\n    },\n    data() {\n      return {\n        options: {},\n      }\n    },\n    watch: {\n      pData: {\n        handler() {\n          this.options = this.barChartOptions()\n        },\n        immediate: true,\n      },\n    },\n    methods: {\n      barChartOptions() {\n        const data = this.pData.map((item) => {\n          return {\n            value: item.fieldCountNum,\n            name: item.fieldName,\n          }\n        })\n        return {\n          tooltip: {\n            trigger: \"item\",\n          },\n          legend: {\n            top: \"bottom\",\n            left: \"center\",\n          },\n          series: [\n            {\n              type: \"pie\",\n              radius: [\"35%\", \"60%\"],\n              padAngle: 3,\n              itemStyle: {\n                borderRadius: 5,\n              },\n              labelLine: {\n                show: true,\n              },\n              data,\n            },\n          ],\n        }\n      },\n    },\n  }\n\u003C\u002Fscript>\n",[34,73,71],{"__ignoreMap":32},{"title":32,"searchDepth":75,"depth":75,"links":76},4,[77,83],{"id":12,"depth":78,"text":13,"children":79},2,[80,82],{"id":24,"depth":81,"text":24},3,{"id":38,"depth":81,"text":38},{"id":60,"depth":78,"text":61,"children":84},[85],{"id":67,"depth":81,"text":67},null,[88],"代码","2024-04-16 20:02:27","封装一个 ECharts 容器组件，在使用时可以直接传递一个 options 对象，在组件内部自动初始化基础配置和监听图表大小变化、图表数据变化后自动重新渲染。",false,"md","https:\u002F\u002Fbitmc.uno\u002Fpicgo\u002F679adcf246a2d-78.webp",{},true,"\u002Fposts\u002F2024\u002Fchart-echarts-in-vue2-component",{"text":98,"minutes":99,"time":100,"words":101},"3 min read",2.75,165000,550,{"title":5,"description":90},{"loc":96},"posts\u002F2024\u002Fchart-echarts-in-vue2-component",[],"YGdHYItpiEd4IqUZn8Pnj5L29cN7jZlspcmZrR0LM4o",[108,113],{"title":109,"path":110,"stem":111,"date":112,"type":86,"children":-1},"最近学习到的小知识","\u002Fposts\u002F2024\u002Ftips","posts\u002F2024\u002Ftips","2024-04-13 11:54:18",{"title":114,"path":115,"stem":116,"date":117,"type":86,"children":-1},"leetcode 两数之和","\u002Fposts\u002F2024\u002Fleetcode-two-sum","posts\u002F2024\u002Fleetcode-two-sum","2024-05-18 11:00:25",1789642591997]