使用Vue实现记账清单和数据可视化图标渲染

记账清单和图标渲染

功能需求:
  1. 基本渲染

    ​ * (1) 立刻发送请求获取数据 created

    ​ * (2) 拿到数据,存到data的响应式数据中

    ​ * (3) 结合数据,进行渲染 v-for

    ​ * (4) 消费统计 => 计算属性

  2. 添加功能

    ​ * (1) 收集表单数据 v-model

    ​ * (2) 给添加按钮注册点击事件,发送添加请求

    ​ * (3) 需要重新渲染

  3. 删除功能

    ​ * (1) 注册点击事件,传参传 id

    ​ * (2) 根据 id 发送删除请求

    ​ * (3) 需要重新渲染

  4. 饼图渲染

    ​ * (1) 初始化一个饼图 echarts.init(dom) mounted钩子实现

    ​ * (2) 根据数据实时更新饼图 echarts.setOption({ ... })



项目代码

容器视图代码

html 复制代码
  <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 @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>
              <td :class="{ red: item.price > 500 }">{{ item.price.toFixed(2) }}</td>
              <td><a @click="del(item.id)" href="javascript:;">删除</a></td>
            </tr>
          </tbody>
          <tfoot>
            <tr>
              <td colspan="4">消费总计: {{ totalPrice.toFixed(2) }}</td>
            </tr>
          </tfoot>
        </table>
      </div>

      <!-- 右侧图表 -->
      <div class="echarts-box" id="main"></div>
    </div>
  </div>

Vue实例代码

javascript 复制代码
    const app = new Vue({
      el: '#app',
      data: {
        list: [],
        name: '',
        price: ''
      },

      // 计算属性
      computed: {
        totalPrice() {
          return this.list.reduce((sum, item) => sum + item.price, 0)
        }
      },
      // 1、渲染
      created() {
        this.getList()
      },
      //自己封装的方法。
      methods: {
        // 封装渲染函数
        async getList() {
          // 发送渲染请求,获取数据
          const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {
            params: {
              creator: '刘不住'
            }
          })
          // 将结果赋值给实例上面的数据。
          this.list = res.data.data

          // 异步 更新图标  
          this.myChart.setOption({
            // 数据项
            series: [
              {
                data: this.list.map(item => ({ value: item.price, name: item.name }))
              }
            ]

          })
        },
        // 2、添加
        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: '刘不住',
            name: this.name,
            price: this.price
          })
          // 添加完成后,重新渲染一次
          this.getList()
          // 重置输入框
          this.name = ''
          this.price = ''
        },
        // 3、删除
        del(id) {
          // 发起删除请求
          axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
          // 调用渲染API
          this.getList()
          alert('删除成功')
        }
      },
      mounted() {
        // 将myChart挂载在实例上,就相当于实例中所有所用于都可以访问使用
        this.myChart = echarts.init(document.querySelector('#main'))
        // 配置项数据
        option = {
          // 标题
          title: {
            text: '消费账单列表',
            subtext: 'Fake Data',
            left: 'center'
          },
          tooltip: {
            trigger: 'item'
          },
          legend: {
            orient: '消费账单',
            left: 'left'
          },
          // 数据项
          series: [
            {
              name: 'Access From',
              type: 'pie',
              radius: '50%',
              data: [
                // { value: 1048, name: 'Search Engine' },
                // { value: 735, name: 'Direct' },
                // { value: 580, name: 'Email' },
                // { value: 484, name: 'Union Ads' },
                // { value: 300, name: 'Video Ads' }
              ],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        }
        this.myChart.setOption(option)
      }
    })
  </script>

相关推荐
菜根Sec14 分钟前
XSS跨站脚本攻击漏洞练习
前端·xss
web1508541593518 分钟前
vue 集成 webrtc-streamer 播放视频流 - 解决阿里云内外网访问视频流问题
vue.js·阿里云·webrtc
m0_7482571821 分钟前
Spring Boot FileUpLoad and Interceptor(文件上传和拦截器,Web入门知识)
前端·spring boot·后端
桃园码工39 分钟前
15_HTML5 表单属性 --[HTML5 API 学习之旅]
前端·html5·表单属性
百万蹄蹄向前冲1 小时前
2024不一样的VUE3期末考查
前端·javascript·程序员
轻口味2 小时前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami2 小时前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡2 小时前
lodash常用函数
前端·javascript
emoji1111112 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼3 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs