34-监听数据渲染饼图以及饼图配置

下面我们来实现动态获取数据渲染饼图

首先我们先配置获取首页数据接口,新建一个 api/index.ts

ts 复制代码
import request from './request'

// 获取首页数据
export const getAdminStat = ():PromiseResponse<IndexDataItf> => {
    return request.get('/admin/stat')
}

新建类型 types/index.d.ts

ts 复制代码
interface IndexDataItf {
    salePie: {}[]
}

然后准备一下 mock/data/pie.json 数据

json 复制代码
{
    "salePie": [
        {
            "first_cid": 4,
            "fourteen_day_money": "19731832.03",
            "name": "家用电器",
            "sale_fourteen_days": "106517",
            "sale_seven_days": "47227",
            "sale_sixty_days": "527176",
            "sale_thirty_days": "208180",
            "sale_three_days": "10173",
            "sale_today": "3042",
            "sale_yesterday": "3592",
            "seven_days_money": "10329999.07",
            "sixty_days_money": "115535775.94",
            "thirty_days_money": "36986056.07",
            "today_money": "496742.20",
            "yesterday_money": "673293.80"
        },
        {
            "first_cid": 7,
            "fourteen_day_money": "15230450.19",
            "name": "手机数码",
            "sale_fourteen_days": "88432",
            "sale_seven_days": "39210",
            "sale_sixty_days": "468012",
            "sale_thirty_days": "181245",
            "sale_three_days": "8421",
            "sale_today": "2654",
            "sale_yesterday": "3187",
            "seven_days_money": "8123456.78",
            "sixty_days_money": "97210432.55",
            "thirty_days_money": "32998123.44",
            "today_money": "386512.70",
            "yesterday_money": "451203.11"
        },
        {
            "first_cid": 11,
            "fourteen_day_money": "9876543.21",
            "name": "服饰鞋包",
            "sale_fourteen_days": "75410",
            "sale_seven_days": "33100",
            "sale_sixty_days": "389765",
            "sale_thirty_days": "152398",
            "sale_three_days": "6932",
            "sale_today": "2199",
            "sale_yesterday": "2477",
            "seven_days_money": "6543210.00",
            "sixty_days_money": "80123456.78",
            "thirty_days_money": "28765012.34",
            "today_money": "312045.66",
            "yesterday_money": "333210.12"
        },
        {
            "first_cid": 15,
            "fourteen_day_money": "13124567.54",
            "name": "美妆护肤",
            "sale_fourteen_days": "69214",
            "sale_seven_days": "30217",
            "sale_sixty_days": "341287",
            "sale_thirty_days": "138765",
            "sale_three_days": "6123",
            "sale_today": "2045",
            "sale_yesterday": "2260",
            "seven_days_money": "7234567.89",
            "sixty_days_money": "86234567.10",
            "thirty_days_money": "26457890.23",
            "today_money": "298700.45",
            "yesterday_money": "312560.30"
        },
        {
            "first_cid": 19,
            "fourteen_day_money": "8754321.09",
            "name": "运动户外",
            "sale_fourteen_days": "58201",
            "sale_seven_days": "25743",
            "sale_sixty_days": "295678",
            "sale_thirty_days": "124390",
            "sale_three_days": "5344",
            "sale_today": "1788",
            "sale_yesterday": "1923",
            "seven_days_money": "5412345.67",
            "sixty_days_money": "70234567.89",
            "thirty_days_money": "23145678.90",
            "today_money": "254320.78",
            "yesterday_money": "266789.45"
        }
    ]
}

接着实现mock这个接口,新建文件 mock/modules/index.ts

ts 复制代码
import { type MockMethod } from 'vite-plugin-mock'
import fs from 'fs'
import path from 'path'

import { validateToken } from '../utils'

const pieDataFile = path.join(process.cwd(), 'src/mock/data/pie.json')

const readPieData = () => {
    try {
        const raw = fs.readFileSync(pieDataFile, 'utf-8')
        return JSON.parse(raw) as Record<string, unknown>
    } catch (e) {
        console.error('读取首页饼图数据失败', e)
        return { salePie: [] }
    }
}

export default [
    {
        url: '/api/admin/stat',
        method: 'get',
        response: ({ headers }: { headers: Record<string, string> }) => {
            const tokenCheck = validateToken(headers)
            if (!tokenCheck.valid) {
                return tokenCheck.response
            }

            const data = readPieData()
            return {
                code: 200,
                message: '获取首页统计数据成功',
                data
            }
        }
    }
] as MockMethod[]

准备写请求逻辑

html 复制代码
<template>
    <div class=''>
        <MyPie :data="salePie"></MyPie>
    </div>
</template>

<script lang='ts' setup>
import MyPie from './components/MyPie.vue'
import { reactive, toRefs } from 'vue'
import { getAdminStat} from '@/api/index'
import { ElMessage } from 'element-plus'

const state = reactive<{
    salePie: {}[]
}>({
    salePie: []
})

let { salePie } = toRefs(state)

getAdminStat().then((res) => {
    if(res.code === 200) {
        salePie.value = res.data.salePie
    } else {
        ElMessage.error('获取首页数据失败')
    }
})

</script>

<style lang='less' scoped>

</style>

子组件逻辑

html 复制代码
<template>
    <div id="pie" style="width: 100%;height:400px;"></div>
</template>

<script lang='ts' setup>
import { watch } from 'vue'
import * as echarts from 'echarts'

const props = defineProps<{
    data: {
        name: string
        today_money: string
    }[]
}>()

watch(() => props.data, () => {
    const arr = props.data.map(item => ({ name: item.name, value: item.today_money}))
    console.log('arr---->', arr)
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('pie'));

    // 指定图表的配置项和数据
    var option = {
        legend: {
            right: 10,
            top: 20,
            width: 300,
            height: 100,
            orient: 'vertical'
        },
        series: [
            {
                name: 'Access From',
                type: 'pie',
                radius: ['40%', '70%'],
                center: ['35%', '45%'],
                data: arr
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
})
</script>

<style lang='less' scoped>

</style>
相关推荐
java1234_小锋1 天前
Vue3专题 - 响应式基础
vue·vue3·响应式
春波petal2 天前
Vue3防抖搜索:从Lodash到customRef全解析
vue.js·vue3·防抖搜索
濮水大叔3 天前
不必把 Vue3 写成“麻花”:从状态碎片到对象协作,重新理解 Zova 的前端心智模型
前端·typescript·vue3·ioc·tsx·zova
听风3475 天前
智扫通机器人智能客服系统
vue3·fastapi·智能客服·agent项目
gis开发之家7 天前
《Vue3 从入门到大神40篇》Vue3 源码详解(十):diff 算法全解析 —— 为什么 Vue3 比 Vue2 更快?
javascript·算法·typescript·前端框架·vue3·vue3源码
想你依然心痛9 天前
让数据会说话,Vue 结合 ECharts 打造电力可视化大屏
echarts·vue3·数据大屏·电力可视化
路光.10 天前
Vue2升级Vue3处理原 UMD/CommonJS 打包文件,不是标准 ESM
前端·javascript·vue.js·vue3
gis开发之家11 天前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
布兰妮甜14 天前
从 0 搭建企业级 Vue3/Vite 脚手架(规范、eslint、husky、打包、环境变量全流程)
typescript·vue3·vite·脚手架·前端工程化
gis开发之家14 天前
《Vue3 从入门到大神35篇》Vue3 源码详解(五):effect 依赖收集原理——track 与 trigger 是如何工作的?
javascript·typescript·前端框架·vue3·vue3源码