vue学习日记13:记账清单,渲染添加删除

news2024/9/21 10:56:33

一.需求说明

二、实践

1.基本渲染

 

(1)代码

<!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/bootstrap@5.1.3/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 type="text" class="form-control" placeholder="消费名称" />
            <input type="text" class="form-control" placeholder="消费价格" />
            <button 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 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>
    <script src="../echarts.min.js"></script>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
      /**
       * 接口文档地址:
       * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
       * 
       * 功能需求:
       * 1. 基本渲染
       *    (1)立刻发送求情获取数据 created
       *    (2)拿到数据,存到data的响应式数据中
       *    (3)结合数据,进行渲染 v-for
       *    (4)消费统计 => 计算属性
       * 2. 添加功能
       * 3. 删除功能
       * 4. 饼图渲染
       */
      const app = new Vue({
        el: '#app',
        data: {
          list: []
        },
        computed:{
          totalPrice(){
            return this.list.reduce((sum,item) => sum + item.price,0)
          }
        },
        async created(){
          const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
            params:{
              creator: '尹凡'
            }
          })
          console.log(res)
          this.list = res.data.data
        },
      })
    </script>
  </body>
</html>

(2)展示

 

2.添加功能

(1)代码

<!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/bootstrap@5.1.3/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 @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 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>
    <script src="../echarts.min.js"></script>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
      /**
       * 接口文档地址:
       * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
       * 
       * 功能需求:
       * 1. 基本渲染
       *    (1)立刻发送求情获取数据 created
       *    (2)拿到数据,存到data的响应式数据中
       *    (3)结合数据,进行渲染 v-for
       *    (4)消费统计 => 计算属性
       * 2. 添加功能
       *    (1)收集表单数据 v-model
       *    (2)给添加按钮注册点击事件,发送添加请求
       *    (3)需不需要重新渲染??  --->需要重新渲染  发请求后后端数据会改变
       * 3. 删除功能
       * 4. 饼图渲染
       */
      const app = new Vue({
        el: '#app',
        data: {
          list: [],
          name: '',
          price:'',
        },
        computed:{
          totalPrice(){
            return this.list.reduce((sum,item) => sum + item.price,0)
          }
        },
        created(){
          //多次调用渲染封装成函数
          // const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
          //   params:{
          //     creator: '尹凡'
          //   }
          // })
          // console.log(res)
          // this.list = res.data.data

          this.getList()
        },
        methods:{
          async getList(){
            const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
              params:{
                creator: '尹凡'
              }
            })
            console.log(res)
            this.list = res.data.data
          },
          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,
            })
            console.log(res)
            // 重新渲染一次
            this.getList()
            
            this.name=''
            this.price=''
          }
        }
      })
    </script>
  </body>
</html>

(2)展示

 

3.删除功能

(1)代码

写的时候忘记放了 可以去饼图渲染的代码看 已经包含了

(2)展示

4.饼图渲染

(1)代码--也是该练习的完整代码

<!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/bootstrap@5.1.3/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 @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>
    <script src="../echarts.min.js"></script>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
      /**
       * 接口文档地址:
       * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
       * 
       * 功能需求:
       * 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({ ... })
       *
       */
      const app = new Vue({
        el: '#app',
        data: {
          list: [],
          name: '',
          price:'',
        },
        computed:{
          totalPrice(){
            return this.list.reduce((sum,item) => sum + item.price,0)
          }
        },
        created(){
          //多次调用渲染封装成函数
          // const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
          //   params:{
          //     creator: '尹凡'
          //   }
          // })
          // console.log(res)
          // this.list = res.data.data

          this.getList()
        },
        //操作dom
        mounted() {
          this.myChart = echarts.init(document.querySelector('#main'))
          this.myChart.setOption({
            title: {
              //大标题
              text: '消费账单列表',
              subtext: '子标题',
              left: 'center'
            },
            //提示框
            tooltip: {
              trigger: 'item'
            },
            //图例
            legend: {
              orient: 'vertical',
              left: 'left'
            },
            //数据项
            series: [
              {
                name: '消费账单',
                type: 'pie',
                radius: '50%', //圆的半径
                data: [
                  // { value: 1048, name: 'Search Engine' },
                  // { value: 735, name: 'Direct' },
                ],
                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: '尹凡'
              }
            })
            console.log(res)
            this.list = res.data.data
            console.log(this.list)

            //更新图表
            this.myChart.setOption({
              //数据项 层级结构不能自己改最好复制  不变的内容可以直接删了 只保留需要更改的
              series: [
                {

                  // data: [
                  //   { value: 1048, name: 'Search Engine' },
                  //   { value: 735, name: 'Direct' },
                  // ],

                  //{ value: item.price, name: item.name } 用()扩起来 当作一个对象
                  data: this.list.map(item => ({ value: item.price, name: item.name }))
                }
              ]
            })
          },
          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,
            })
            console.log(res)
            // 重新渲染一次
            this.getList()

            this.name=''
            this.price=''
          },
          async del (id){
            //根据id 发送删除请求 id不希望写死 用反引号``  而不是''
            const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`,)

            console.log(res)
            //重新渲染
            this.getList()
          }
        }
      })
    </script>
  </body>
</html>

(2)展示

 

 三、案例总结

-----------------------------------------------------------------------------------------------------------------------------

注:本人是根据黑马程序员的B站教程来学习的,
链接:https://www.bilibili.com/video/BV1HV4y1a7n4/?spm_id_from=333.999.0.0

本文章仅仅是个人学习笔记 无任何其他用途 特此说明 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1535350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA安全(偏基础)

SQL注入 SQLI(SQL Injection)&#xff0c; SQL注入是因为程序未能正确对用户的输入进行检查&#xff0c;将用户的输入以拼接的方式带入SQL语句&#xff0c;导致了SQL注入的产生。攻击者可通过SQL注入直接获取数据库信息&#xff0c;造成信息泄漏。 JDBC JDBC有两个方法获取s…

实时数仓之实时数仓架构(Doris)

目前比较流行的实时数仓架构有两类,其中一类是以Flink+Doris为核心的实时数仓架构方案;另一类是以湖仓一体架构为核心的实时数仓架构方案。本文针对Flink+Doris架构进行介绍,这套架构的特点是组件涉及相对较少,架构简单,实时性更高,且易于Lambda架构实现,Doris本身可以支…

Vue3中基本数据类型为什么需要.value,,,引用类型不需要.value

1、在v3中使用基本数据类型&#xff08;如数字、字符串、布尔值&#xff09;时&#xff0c;如果你希望响应式地更新数据并触发视图更新,需要使用ref包裹基本数据类型,然后将基本数据类型转化为响应式对象;- - - 因此当你使用ref包裹基本数据类型时,实际上得到的是一个包含.valu…

解读 Xend Finance:向 RWA 叙事拓展,构建更具包容性的 DeFi 体系

在二十世纪后&#xff0c;非洲地区陆续爆发了主权运动&#xff0c;这也让非洲大陆逐渐摆脱“殖民地”的标签。目前&#xff0c;非洲大陆公有 54 个主权国家&#xff0c;接近 15 亿且仍在飙升的人口规模&#xff0c;其 GDP 已经与印度相当&#xff0c;且仍旧处于飞速的发展进程中…

计算机服务器中了mkp勒索病毒怎么办,mkp勒索病毒解密工具流程

在网络飞速发展的时代&#xff0c;越来越多的企业离不开网络&#xff0c;利用网络可以为企业更好地开展各项工作业务&#xff0c;帮助企业有效调整发展方向与规划&#xff0c;但网络是一把双刃剑&#xff0c;在为人们提供便利的同时&#xff0c;也为企业的数据安全带来严重威胁…

【Apache ShenYu源码】如何实现负载均衡模块设计

ShenYu是一个异步的&#xff0c;高性能的&#xff0c;跨语言的&#xff0c;响应式的 API 网关。有关ShenYu的介绍可以戳这。 一、前瞻 今天我们尝试不同的代码阅读方式&#xff0c;按模块来去阅读源码&#xff0c;看看效果如何。 本次阅读锁定在shenyu-loadbalancer&#xf…

Qt登录页面

#include "mywidget.h" #include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget) {ui->setupUi(this);//接收动图QMovie *mv new QMovie(":/pictrue/luori.gif");ui->loglab->setMovie(…

ssm项目(tomcat项目),定时任务(每天运行一次)相同时间多次重复运行job 的bug

目录标题 一、原因 一、原因 debug本地调试没有出现定时任务多次运行的bug&#xff0c;上传到服务器就出现多次运行的bug。&#xff08;war的方式部署到tomcat&#xff09; 一开始我以为是代码原因&#xff0c;或者是linux和win环境不同运行定时任务的方式不一样。 但是自己…

Chronicles 是什么数据库

可以理解的是 Chronicles 是 EPIC 公司根据 IRIS 进行魔改后的一个 DBMS。 简单的来说 Chronicles 就是一个数据库管理系统&#xff0c;但这个数据库管理系统不是我们常说的关系数据库的管理系统。 数据库结构 只要对数据库有所了解的都知道数据库通常就是 2 个部分&#xf…

基于Springboot的银行客户管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的银行客户管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

马斯克开源Grok-1

Grok-1是由马斯克AI创企xAI发布的第一代大语言模型&#xff0c;它以其巨大的参数量——高达3140亿&#xff0c;引起了全球范围内的广泛关注。这一参数量远超其他知名模型&#xff0c;如OpenAI的GPT-3.5&#xff0c;后者仅有1750亿参数。在2024年3月17日&#xff0c;马斯克宣布将…

进程的终止

进程的退出&#xff08;main函数的退出&#xff09; main函数的返回值叫做进程的退出码&#xff0c;该退出码表示进程执行的情况。例如&#xff1a;一个函数返回一个值时&#xff0c;我们要知道函数的执行情况&#xff0c;可以去看函数的返回值。 例子&#xff1a; 1 #include…

多数据源 - dynamic-datasource | 进阶 - 动态解析数据源

文章目录 内置解析器自定义解析器相关文章🗯️ 上节回顾:前节中,了解了 dynamic-datasource 的动态添加/移除数据源。 👉 本节目标:了解 dynamic-datasource 的进阶用法 - 动态解析数据源。 动态解析数据源:指数据源切换是不固定的,可以根据域名,根据 header 参数,根…

Linux系统编程(笔记)

1、认识计算机系统&#xff08;上&#xff09; 1.1、计算机系统由软硬件构成 1.2、总线 1.3、I/O设备 1.4、内存 1.5、处理器 1.6、计算机硬件组成 2、认识计算机系统&#xff08;下&#xff09; 2.1、什么是操作系统 2.2、Linux内核模块 2.3、操作系统管理硬件&#xff08;职…

Tensorflow2.0笔记 - 链式法则例子

本笔记简单记录链式法则的原理&#xff0c;关于链式法则&#xff0c;本身和高等数学中的链式求导法则是一样的&#xff0c;深度学习中相关资料可以参考这里&#xff1a; 【深度学习之美22】BP算法详解之链式法则 - 知乎10.5 什么是计算图&#xff1f;我们知道&#xff0c; 神经…

sizeof()的使用

sizeof() 可以计算元素个数 msdn对sizeof的原解释 sizeof是C语言中的一个关键字&#xff0c;计算类型或变量大小&#xff0c;单位是字节 #include <stido.h>int main() {int arr[10] { 0 };printf("%d\n", sizeof(arr));return 0; } 这里输出的值是 40&am…

Java安全 反序列化(4) CC1链-LazyMap版

Java安全 反序列化(4) CC1链-LazyMap版 实验环境:存在漏洞的版本 commons-collections3.1-3.2.1 jdk 8u71之后已修复不可利⽤ 文章目录 Java安全 反序列化(4) CC1链-LazyMap版一.跟踪挖掘CC1_LazyMap原理二.完整CC1_Lazy版Poc 接着上一篇文章我们通过ChainedTransFormer实现任意…

社科赛斯考研:二十二载岁月铸辉煌,穿越周期的生命力之源

在考研培训行业的浩瀚海洋中&#xff0c;社科赛斯考研犹如一艘稳健的巨轮&#xff0c;历经二十二载风礼&#xff0c;依然破浪前行。在考研市场竞争白热化与学生对于考研机构要求越来越高的双重影响下&#xff0c;社科赛斯考研却以一种分蘖成长的姿态&#xff0c;扎根、壮大&…

JavaWeb的MVC设计模式

JavaWeb的MVC设计模式学习笔记 JSP Model1 在JSP Model1架构中&#xff0c;JSP页面既充当了视图&#xff08;View&#xff09;的角色&#xff0c;又包含了处理业务逻辑和数据处理的代码&#xff0c;承担了Controller和Model的责任。这种架构简单直接&#xff0c;适用于小型项…

C++开发基础——函数指针回调函数

一&#xff0c;函数指针 1.函数指针的概念 与数组类似&#xff0c;函数在内存中也有地址&#xff0c;函数在内存中的地址是其机器语言代码的开始位置&#xff0c;而函数指针则存储函数的内存地址作为变量。函数指针可以被当作一个值赋给另一个变量&#xff0c;也可以作为实参…