最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3+vite+JS使用Echarts封裝一個(gè)餅圖完整代碼(父子組件聯(lián)動(dòng))

 更新時(shí)間:2026年03月13日 08:28:38   作者:還是大劍師蘭特  
在Vue中繪制餅圖有多種方式,其中最常用的是使用第三方圖表庫(kù),如ECharts、Chart.js等,下面這篇文章主要介紹了vue3+vite+JS使用Echarts封裝一個(gè)餅圖(父子組件聯(lián)動(dòng))的相關(guān)資料,需要的朋友可以參考下

前言

本文要在vue3+vite+JS項(xiàng)目中,使用Echarts封裝一個(gè)餅圖子組件,父組件中引入子組件并傳入數(shù)據(jù)。傳入的數(shù)據(jù)包括標(biāo)題、高度、寬度、餅圖數(shù)據(jù),resize監(jiān)聽(tīng)尺寸。子組件監(jiān)聽(tīng)餅圖數(shù)據(jù)的變化,來(lái)更新子組件的顯示內(nèi)容。

一、實(shí)現(xiàn)思路

  1. 子組件封裝:基于 ECharts 封裝餅圖組件,接收父組件傳入的標(biāo)題、寬高、餅圖數(shù)據(jù)等 props;
  2. 響應(yīng)式處理:監(jiān)聽(tīng)餅圖數(shù)據(jù)變化,自動(dòng)更新圖表;監(jiān)聽(tīng)窗口 resize 事件,自適應(yīng)調(diào)整圖表尺寸;
  3. 父組件使用:導(dǎo)入子組件,傳入自定義數(shù)據(jù),實(shí)現(xiàn)靈活配置。

二、完整代碼實(shí)現(xiàn)

1. 安裝 ECharts 依賴

npm install echarts --save
# 或 yarn add echarts

2. 餅圖子組件(PieChart.vue)

<template>
  <!-- 圖表容器,寬高由父組件傳入 -->
  <div 
    ref="chartRef" 
    class="pie-chart-container"
    :style="{ width: width + 'px', height: height + 'px' }"
  ></div>
</template>

<script setup>
import { ref, watch, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'

// 定義接收的 props
const props = defineProps({
  // 餅圖標(biāo)題
  title: {
    type: String,
    default: '餅圖示例'
  },
  // 圖表寬度(px)
  width: {
    type: Number,
    default: 400
  },
  // 圖表高度(px)
  height: {
    type: Number,
    default: 300
  },
  // 餅圖數(shù)據(jù)(格式:[{ name: '分類1', value: 100 }, ...])
  chartData: {
    type: Array,
    required: true,
    validator: (val) => {
      // 簡(jiǎn)單校驗(yàn)數(shù)據(jù)格式
      return val.every(item => item.hasOwnProperty('name') && item.hasOwnProperty('value'))
    }
  }
})

// 圖表實(shí)例引用
const chartRef = ref(null)
// ECharts 實(shí)例
let chartInstance = null

// 初始化圖表
const initChart = () => {
  // 確保容器存在
  if (!chartRef.value) return
  
  // 初始化 ECharts 實(shí)例
  chartInstance = echarts.init(chartRef.value)
  
  // 設(shè)置圖表配置項(xiàng)
  const option = {
    title: {
      text: props.title,
      left: 'center' // 標(biāo)題居中
    },
    tooltip: {
      trigger: 'item', // 鼠標(biāo)懸浮提示
      formatter: '{a} 
: {c} (wppm3vysvbp%)' // 提示格式:名稱:數(shù)值(百分比)
    },
    legend: {
      orient: 'vertical', // 圖例垂直排列
      left: 'left' // 圖例居左
    },
    series: [
      {
        name: props.title,
        type: 'pie',
        radius: ['40%', '70%'], // 餅圖內(nèi)外半徑
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: 16,
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data: props.chartData // 餅圖數(shù)據(jù)
      }
    ]
  }
  
  // 渲染圖表
  chartInstance.setOption(option)
}

// 更新圖表(數(shù)據(jù)變化時(shí)調(diào)用)
const updateChart = () => {
  if (!chartInstance) return
  
  // 僅更新數(shù)據(jù)相關(guān)配置,避免重復(fù)初始化
  chartInstance.setOption({
    title: { text: props.title },
    series: [{ data: props.chartData }]
  })
}

// 監(jiān)聽(tīng)窗口 resize,自適應(yīng)調(diào)整圖表尺寸
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

// 生命周期:掛載時(shí)初始化圖表 + 監(jiān)聽(tīng) resize
onMounted(() => {
  initChart()
  window.addEventListener('resize', handleResize)
})

// 生命周期:卸載時(shí)銷毀實(shí)例 + 移除監(jiān)聽(tīng)
onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose() // 銷毀 ECharts 實(shí)例,釋放內(nèi)存
    chartInstance = null
  }
  window.removeEventListener('resize', handleResize)
})

// 監(jiān)聽(tīng) props 變化,更新圖表
watch(
  // 監(jiān)聽(tīng)標(biāo)題、寬高、數(shù)據(jù)的變化
  [() => props.title, () => props.width, () => props.height, () => props.chartData],
  () => {
    // 寬高變化時(shí)先銷毀再重新初始化,數(shù)據(jù)/標(biāo)題變化時(shí)僅更新配置
    if (props.width || props.height) {
      chartInstance?.dispose()
      initChart()
    } else {
      updateChart()
    }
  },
  {
    deep: true // 深度監(jiān)聽(tīng)數(shù)組/對(duì)象變化
  }
)
</script>

<style scoped>
.pie-chart-container {
  /* 防止容器內(nèi)邊距影響尺寸 */
  box-sizing: border-box;
  /* 解決圖表容器閃爍問(wèn)題 */
  transition: all 0.3s ease;
}
</style>

3. 父組件(ParentPage.vue)

<template>
  <div class="parent-page">
    <h2>餅圖組件使用示例</h2>
    
    <!-- 操作區(qū):修改數(shù)據(jù)/尺寸 -->
    <div class="control-panel">
      <button @click="changeChartData">切換餅圖數(shù)據(jù)</button>
      <button @click="changeChartSize">修改圖表尺寸</button>
      <button @click="changeChartTitle">修改圖表標(biāo)題</button>
    </div>
    
    <!-- 引入餅圖子組件,傳入配置 -->
    <PieChart 
      :title="chartTitle"
      :width="chartWidth"
      :height="chartHeight"
      :chart-data="chartData"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'
// 導(dǎo)入餅圖子組件
import PieChart from './PieChart.vue'

// 定義餅圖配置數(shù)據(jù)(響應(yīng)式)
const chartTitle = ref('各部門人數(shù)分布')
const chartWidth = ref(500)
const chartHeight = ref(400)

// 初始餅圖數(shù)據(jù)
const chartData = ref([
  { name: '技術(shù)部', value: 30 },
  { name: '產(chǎn)品部', value: 15 },
  { name: '市場(chǎng)部', value: 20 },
  { name: '財(cái)務(wù)部', value: 8 },
  { name: '人事部', value: 7 }
])

// 模擬:切換餅圖數(shù)據(jù)
const changeChartData = () => {
  chartData.value = [
    { name: '技術(shù)部', value: 40 },
    { name: '產(chǎn)品部', value: 10 },
    { name: '市場(chǎng)部', value: 25 },
    { name: '財(cái)務(wù)部', value: 5 },
    { name: '人事部', value: 10 },
    { name: '運(yùn)營(yíng)部', value: 10 } // 新增分類
  ]
}

// 模擬:修改圖表尺寸
const changeChartSize = () => {
  chartWidth.value = 600
  chartHeight.value = 450
}

// 模擬:修改圖表標(biāo)題
const changeChartTitle = () => {
  chartTitle.value = '各部門人數(shù)分布(更新后)'
}
</script>

<style scoped>
.parent-page {
  padding: 20px;
}

.control-panel {
  margin-bottom: 20px;
}

.control-panel button {
  margin-right: 10px;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: #409eff;
  color: #fff;
  cursor: pointer;
}

.control-panel button:hover {
  background: #66b1ff;
}
</style>

三、關(guān)鍵代碼解釋

  1. 子組件核心邏輯

    • props 定義:明確接收標(biāo)題、寬高、餅圖數(shù)據(jù),且對(duì) chartData 做格式校驗(yàn),確保數(shù)據(jù)合法性;
    • 圖表初始化initChart 方法創(chuàng)建 ECharts 實(shí)例并配置基礎(chǔ)樣式,updateChart 方法僅更新數(shù)據(jù)/標(biāo)題,避免重復(fù)初始化;
    • 響應(yīng)式監(jiān)聽(tīng):通過(guò) watch 深度監(jiān)聽(tīng) props 變化,寬高變化時(shí)重新初始化圖表,數(shù)據(jù)/標(biāo)題變化時(shí)僅更新配置;
    • 生命周期管理onMounted 時(shí)初始化圖表并添加 resize 監(jiān)聽(tīng),onUnmounted 時(shí)銷毀 ECharts 實(shí)例、移除監(jiān)聽(tīng),防止內(nèi)存泄漏;
    • resize 適配:監(jiān)聽(tīng)窗口尺寸變化,調(diào)用 chartInstance.resize() 自動(dòng)調(diào)整圖表大小。
  2. 父組件核心邏輯

    • 定義響應(yīng)式數(shù)據(jù)(標(biāo)題、寬高、餅圖數(shù)據(jù)),傳入子組件;
    • 提供按鈕模擬數(shù)據(jù)/尺寸/標(biāo)題變化,驗(yàn)證子組件的響應(yīng)式更新能力。

四、使用注意事項(xiàng)

  1. 數(shù)據(jù)格式:父組件傳入的 chartData 必須是 [{ name: 'xxx', value: xxx }, ...] 格式,子組件已做基礎(chǔ)校驗(yàn);
  2. 內(nèi)存泄漏:子組件在 onUnmounted 中銷毀 ECharts 實(shí)例、移除 resize 監(jiān)聽(tīng),避免頁(yè)面卸載后殘留事件;
  3. 自適應(yīng)優(yōu)化:如果需要監(jiān)聽(tīng)父容器尺寸變化(而非窗口),可結(jié)合 element-resize-detector 庫(kù)實(shí)現(xiàn);
  4. 樣式適配:子組件容器的寬高使用 px 單位,若需百分比,可修改 props 類型為 String(如 width: '100%')。

五、封裝總結(jié)

  1. 子組件封裝了 ECharts 餅圖的核心邏輯,通過(guò) props 接收父組件配置,具備數(shù)據(jù)響應(yīng)式更新、窗口 resize 自適應(yīng)能力;
  2. 父組件可靈活傳入自定義數(shù)據(jù),通過(guò)修改響應(yīng)式數(shù)據(jù)即可觸發(fā)子組件更新,使用簡(jiǎn)單;
  3. 關(guān)鍵優(yōu)化點(diǎn):銷毀 ECharts 實(shí)例、移除事件監(jiān)聽(tīng),避免內(nèi)存泄漏;深度監(jiān)聽(tīng)數(shù)據(jù)變化,保證圖表實(shí)時(shí)更新。

到此這篇關(guān)于vue3+vite+JS使用Echarts封裝一個(gè)餅圖(父子組件聯(lián)動(dòng))的文章就介紹到這了,更多相關(guān)vue3+vite+JS用Echarts封裝餅圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

芜湖县| 汽车| 军事| 叙永县| 潍坊市| 沙雅县| 马关县| 建德市| 忻州市| 棋牌| 富锦市| 镇江市| 齐河县| 商城县| 福安市| 江陵县| 都昌县| 东海县| 论坛| 从江县| 九寨沟县| 镇宁| 罗甸县| 鲁山县| 敖汉旗| 西吉县| 南充市| 南安市| 吕梁市| 洛隆县| 宜章县| 大兴区| 和田市| 平阳县| 石河子市| 吴忠市| 云浮市| 灵寿县| 濮阳市| 陕西省| 柳河县|