效果
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <!-- CSS only --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" /> <style> .red { color: red!important; } .search { width: 300px; margin: 20px 0; } .my-form { display: flex; margin: 20px 0; } .my-form input { flex: 1; margin-right: 20px; } .table > :not(:first-child) { border-top: none; } .contain { display: flex; padding: 10px; } .list-box { flex: 1; padding: 0 30px; } .list-box a { text-decoration: none; } .echarts-box { width: 600px; height: 400px; padding: 30px; margin: 0 auto; border: 1px solid #ccc; } tfoot { font-weight: bold; } @media screen and (max-width: 1000px) { .contain { flex-wrap: wrap; } .list-box { width: 100%; } .echarts-box { margin-top: 30px; } } </style> </head> <body> <div id="app"> <div class="contain"> <!-- 左侧列表 --> <div class="list-box"> <!-- 添加资产 --> <form class="my-form"> <input v-model.trim="name" type="text" class="form-control" placeholder="消费名称" /> <input v-model.number="price" type="text" class="form-control" placeholder="消费价格" /> <button v-on:click="add" type="button" class="btn btn-primary">添加账单</button> </form> <table class="table table-hover"> <thead> <tr> <th>编号</th> <th>消费名称</th> <th>消费价格</th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="(item,index) in list" :key="item.id"> <td>{{ index + 1 }}</td> <td>{{ item.name }}</td> <!-- 保留小数点后面2位 --> <td :class="{red: item.price >500}">{{ item.price.toFixed(2) }}</td> <td><a v-on:click.prevent="del(item.id)" href="javascript:;">删除</a></td> </tr> </tbody> <tfoot> <tr> <td colspan="4">消费总计:{{totalCount.toFixed(2)}}</td> </tr> </tfoot> </table> </div> <!-- 右侧图表 --> <div class="echarts-box" id="main"></div> </div> </div> <script src="//i2.wp.com/cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.common.js"></script> <script src="//i2.wp.com/cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script src="//i2.wp.com/cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script> <script> /** * 接口文档地址: * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058 * * 功能需求: * 1. 基本渲染 * 2. 添加功能 * 发送请求添加数据,重新渲染 * 3. 删除功能 * 4. 饼图渲染; * 初始化饼图,根据数据实时更新 */ const app = new Vue({ el: '#app', data: { list:[], name:'', price:'', }, computed:{ totalCount(){ return this.list.reduce((sum,item)=>sum+item.price,0 ) } }, // 请求数据 存储到list中 created(){ this.getList() }, mounted(){ this.myChart = echarts.init(document.querySelector('#main')) this.myChart.setOption( { // 标题 title: { text: '消费账单列表', left: 'center' }, // 提示框 tooltip: { trigger: 'item' }, // 图例,左面显示 legend: { orient: 'vertical', left: 'left' }, series: [ { name: '消费账单', type: 'pie', radius: '80%', //圆的半径 data: [ ], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ] } ) }, methods:{ // 封装获取列表数据 async getList(){ const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{ params:{ creator:'zhiyuan' } }) this.list = res.data.data // 更新图表 this.myChart.setOption({ series: [ { data: this.list.map(item=>({value:item.price,name:item.name})) } ] }) }, async del(id){ const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`) // 重新渲染 this.getList() }, async add(){ if(!this.name){ alert('请输入消费名称') return } if(typeof this.price !== 'number'){ alert('价格输入不规范') return } const res =await axios.post('https://applet-base-api-t.itheima.net/bill',{ creator:"zhiyuan", name:this.name, price:this.price }) // 重新渲染 this.getList() this.name='', this.price='' } } }) </script> </body> </html>