第26章:ECharts 自定义主题 + 页面一键切换主题(深色 / 浅色两套)

第26章:ECharts 自定义主题 + 页面一键切换主题(深色 / 浅色两套)

业务场景:后台管理平台,支持全局 / 单张图表切换深色、浅色主题,若依自带暗黑模式联动,复用我们封装好的 useEcharts。

原理:ECharts 支持预注册主题,初始化图表时指定 theme 名称;我们做两套主题,增加按钮一键切换。

第一步:准备 echarts 主题

  1. 官网主题编辑器:https://echarts.apache.org/zh/theme-builder.html
  2. 我们直接内置两套极简主题,不需要额外下载 js,代码内定义。

完整页面 Vue 代码

复制代码
<template>
  <div class="chart-container">
    <el-alert title="ECharts自定义主题切换:浅色/深色主题一键切换" type="info" style="margin-bottom:10px"/>
    <el-button type="primary" @click="toggleTheme">切换图表主题</el-button>
    <div
      ref="chartRef"
      style="width:100%;height:400px;border:1px solid #eee;margin-top:10px"
    ></div>
  </div>
</template>

<script setup>
import * as echarts from 'echarts'
import { ref, onMounted } from 'vue'
import { useEcharts } from '@/composables/echartHelper'

const { chartRef, setChartOption } = useEcharts()
// 标记当前主题
const isDark = ref(false)

// 浅色主题配置
const lightOption = {
  title: {
    text: "产品月度销量统计",
    left: "center",
    textStyle: { color: "#303133" }
  },
  tooltip: { trigger: "axis" },
  legend: { data: ["A产品","B产品"], bottom: 10, textStyle: { color: "#303133" } },
  grid: { left: "3%", right: "4%", bottom: "15%", containLabel: true },
  xAxis: {
    type: "category",
    data: ["1月","2月","3月","4月","5月","6月"],
    axisLine: { lineStyle:{color:'#ccc'} },
    axisLabel: { color: "#606266" }
  },
  yAxis: {
    type: "value",
    axisLine: { lineStyle:{color:'#ccc'} },
    axisLabel: { color: "#606266" }
  },
  series: [
    {
      name: "A产品",
      type: "bar",
      data: [120, 200, 150, 280, 190, 240],
      itemStyle: { color: "#409EFF" }
    },
    {
      name: "B产品",
      type: "bar",
      data: [80, 140, 220, 160, 250, 180],
      itemStyle: { color: "#67C23A" }
    }
  ]
}

// 深色主题配置
const darkOption = {
  backgroundColor: "#1f2937",
  title: {
    text: "产品月度销量统计",
    left: "center",
    textStyle: { color: "#ffffff" }
  },
  tooltip: { trigger: "axis", backgroundColor:"#333", textStyle:{color:"#fff"} },
  legend: { data: ["A产品","B产品"], bottom: 10, textStyle: { color: "#e5e7eb" } },
  grid: { left: "3%", right: "4%", bottom: "15%", containLabel: true },
  xAxis: {
    type: "category",
    data: ["1月","2月","3月","4月","5月","6月"],
    axisLine: { lineStyle:{color:'#4b5563'} },
    axisLabel: { color: "#d1d5db" }
  },
  yAxis: {
    type: "value",
    axisLine: { lineStyle:{color:'#4b5563'} },
    axisLabel: { color: "#d1d5db" }
  },
  series: [
    {
      name: "A产品",
      type: "bar",
      data: [120, 200, 150, 280, 190, 240],
      itemStyle: { color: "#3b82f6" }
    },
    {
      name: "B产品",
      type: "bar",
      data: [80, 140, 220, 160, 250, 180],
      itemStyle: { color: "#22c55e" }
    }
  ]
}

// 切换主题函数
async function toggleTheme() {
  isDark.value = !isDark.value
  if(isDark.value){
    await setChartOption(darkOption)
  }else{
    await setChartOption(lightOption)
  }
}

onMounted(async () => {
  await setChartOption(lightOption)
})
</script>

进阶知识点(若依暗黑模式联动)

若依 Vue3 自带全局暗黑主题,我们可以监听若依的暗黑变量,自动切换图表颜色,不需要手动点按钮:

复制代码
// 引入若依全局暗黑状态
import { useAppStore } from '@/stores/app'
const appStore = useAppStore()

// 监听暗黑模式变化
watch(()=>appStore.dark, (newVal)=>{
  if(newVal){
    setChartOption(darkOption)
  }else{
    setChartOption(lightOption)
  }
},{immediate:true})

注意:需要在顶部引入 import { watch } from 'vue'

知识点总结

  1. 两套 option,区分背景、文字、坐标轴颜色;深色图表必须设置backgroundColor
  2. 复用我们封装好的setChartOption,notMerge:true,切换主题时完整覆盖旧配置,不会残留样式
  3. 可以单独页面切换,也可以监听若依全局暗黑状态自动同步图表主题
  4. resize、实例销毁逻辑全部继承自 useEcharts,不用重复写

🧪 测试清单

  1. 保存页面,刷新浏览器
  2. 页面默认浅色柱状图,文字、坐标轴颜色正常
  3. 点击【切换图表主题】按钮,图表立刻切换深色背景,文字变白
  4. 多次点击,深浅来回切换无样式残留
  5. 窗口缩放,图表自适应
  6. 切换菜单,图表实例销毁,无内存泄漏
相关推荐
流烟默4 小时前
SSE 实战:在 SpringBoot + Vue 项目中零依赖实现轻量级实时消息推送
vue.js·spring boot·后端·sse
执子念的飞鱼4 小时前
纯前端预览 275 种文件格式是怎么做到的
前端·vue.js·react.js
vx_Biye_Design7 小时前
PHP中医养生馆预约系统60841-计算机课程设计、毕业设计
vue.js·spring boot·后端·mysql·php·课程设计·express
gc_229916 小时前
Vue框架学习(1:环境搭建)
vue.js
我的div丢了肿么办1 天前
element-plus表格使用:filter-method过滤导致出现无数据
前端·javascript·vue.js
贾公子1 天前
AI 内容检测 API 接入实战——异步任务、幂等键与轮询的正确写法
vue.js
星光不问赶路人1 天前
Vue 项目类型检查:深入理解 vue-tsc --build
前端·vue.js
WeiXin_DZbishe1 天前
基于springboot装修风格选择系统的设计与开发-计算机毕设【课程设计】77964
java·vue.js·spring boot·后端·python·php·课程设计
雪碧聊技术1 天前
Vue 一个页面中使用多个同类组件出现“串数据“现象?一个 key 就能解决
vue.js·v-show·一个页面使用多个相同组件·解决数据错乱·v-if、key
Java小卷1 天前
Vue3 动态表单支持弹框组件
前端·vue.js·低代码