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>
相关推荐
Irene19912 天前
在 Vue3 中使用 Element Plus
vue3·element plus
冥界摄政王2 天前
Cesium学习第一章 安装下载 基于vue3引入Cesium项目开发
vue·vue3·html5·webgl·cesium
小安同学iter2 天前
Vue3 进阶核心:高级响应式工具 + 特殊内置组件核心解析
前端·javascript·vue.js·vue3·api
启扶农2 天前
lecen:一个更好的开源可视化系统搭建项目--页面设计器(表单设计器)--全低代码|所见即所得|利用可视化设计器构建你的应用系统-做一个懂你的人
低代码·vue3·拖拽·表单设计器·所见即所得·页面可视化·页面设计器
C_心欲无痕3 天前
vue3 - 类与样式的绑定
javascript·vue.js·vue3
C_心欲无痕4 天前
vue3 - defineExpose暴露给父组件属性和方法
前端·javascript·vue.js·vue3
Sheldon一蓑烟雨任平生4 天前
Vue3 低代码平台项目实战(上)
低代码·typescript·vue3·低代码平台·问卷调查·json schema
Sheldon一蓑烟雨任平生5 天前
Vue3 低代码平台项目实战(下)
低代码·typescript·vue3·低代码平台·json schema·vue3项目
C_心欲无痕6 天前
vue3 - useId生成唯一标识符
前端·javascript·vue.js·vue3
C_心欲无痕6 天前
vue3 - watchSyncEffect同步执行的响应式副作用
开发语言·前端·javascript·vue.js·vue3