Vue阶段练习:初始化渲染、获取焦点、记账清单

阶段练习主要承接Vue 生命周期-CSDN博客 ,学习完该部分内容后,进行自我检测,每个练习主要分为效果显示、需求分析、静态代码、完整代码、总结 四个部分,效果显示和准备代码已给出,我们需要完成“完整代码”部分。

练习1:初始化渲染

一进页面,就获取该网址中的信息并显示在页面上

http://hmajax.itheima.net/api/news

效果显示

静态代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>029生命周期created应用新闻列表</title><style>* {margin: 0;padding: 0;list-style: none;}.news {display: flex;height: 120px;width: 600px;margin: 0 auto;padding: 20px 0;cursor: pointer;}.news .left {flex: 1;display: flex;flex-direction: column;justify-content: space-between;padding-right: 10px;}.news .left .title {font-size: 20px;}.news .left .info {color: #999999;}.news .left .info span {margin-right: 20px;}.news .right {width: 160px;height: 120px;}.news .right img {width: 100%;height: 100%;object-fit: cover;}</style>
</head>
<body><div id="app"><ul><li class="news"><div class="left"><div class="title">5G商用在即,三大运营商营收持续下降</div><div class="info"><span>新京报经济新闻</span><span>2222-10-28 11:50:28</span></div></div><div class="right"><img src="http://ajax-api.itheima.net/public/images/0.webp" alt=""></div></li><li class="news"><div class="left"><div class="title">5G商用在即,三大运营商营收持续下降</div><div class="info"><span>新京报经济新闻</span><span>2222-10-28 11:50:28</span></div></div><div class="right"><img src="http://ajax-api.itheima.net/public/images/0.webp" alt=""></div></li><li class="news"><div class="left"><div class="title">5G商用在即,三大运营商营收持续下降</div><div class="info"><span>新京报经济新闻</span><span>2222-10-28 11:50:28</span></div></div><div class="right"><img src="http://ajax-api.itheima.net/public/images/0.webp" alt=""></div></li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>const app = new Vue({el: '#app',data: {list: []}})</script>
</body>
</html>

完整代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>029生命周期created应用新闻列表</title><style>* {margin: 0;padding: 0;list-style: none;}.news {display: flex;height: 120px;width: 600px;margin: 0 auto;padding: 20px 0;cursor: pointer;}.news .left {flex: 1;display: flex;flex-direction: column;justify-content: space-between;padding-right: 10px;}.news .left .title {font-size: 20px;}.news .left .info {color: #999999;}.news .left .info span {margin-right: 20px;}.news .right {width: 160px;height: 120px;}.news .right img {width: 100%;height: 100%;object-fit: cover;}</style>
</head>
<body><div id="app"><ul><li v-for="(item, index) in list" :key="item.id" class="news"><div class="left"><div class="title">{{item.title}}</div><div class="info"><span>{{item.source}}</span><span>{{item.time}}</span></div></div><div class="right"><img :src="item.img" alt=""></div></li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>// 接口地址:http://hmajax.itheima.net/api/news// 请求方式:getconst app = new Vue({el: '#app',data: {list: []},async created(){ const res = await axios.get('http://hmajax.itheima.net/api/news')this.list=res.data.data}})</script>
</body>
</html>

分析

  • async用于声明异步函数
  • await关键字用于等待该网络请求完成,直到获取到数据或发生错误
  • axios.get()方法用于发送网络请求,向指定的url发送get请求,并返回一个Promise对象,该对象在数据成功返回时解析为包含响应数据的对象

为什么这里需要异步操作?

因为从网络请求获取数据,为了避免阻塞主线程,需要使用异步操作来执行网络请求,并在数据返回后更新界面。

为什么在created函数中获取数据?

在Vue.js中,created 生命周期钩子是在实例被创建之后被调用的。因此,在created钩子中获取数据是一个常见的做法,因为此时Vue实例已经创建完成,但尚未挂载到DOM上,所以在这个时候获取数据不会阻塞页面渲染。这样做可以确保在页面渲染完成之前就能获取到需要的数据,并在数据准备就绪后立即对页面进行更新。

使用async和await关键字可以让异步操作看起来像同步操作一样顺序执行,使得代码更加清晰易读。在created钩子中使用async/await可以确保异步数据加载完成后再进行下一步操作,以避免数据未就绪时对页面进行更新造成的问题。

练习2:获取焦点

一进入页面就获取焦点

效果显示

静态代码


<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>029生命周期mounted应用输入框获取焦点</title><!-- 初始化样式 --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset.css@2.0.2/reset.min.css"><!-- 核心样式 --><style>html,body {height: 100%;}.search-container {position: absolute;top: 30%;left: 50%;transform: translate(-50%, -50%);text-align: center;}.search-container .search-box {display: flex;}.search-container img {margin-bottom: 30px;}.search-container .search-box input {width: 512px;height: 16px;padding: 12px 16px;font-size: 16px;margin: 0;vertical-align: top;outline: 0;box-shadow: none;border-radius: 10px 0 0 10px;border: 2px solid #c4c7ce;background: #fff;color: #222;overflow: hidden;box-sizing: content-box;-webkit-tap-highlight-color: transparent;}.search-container .search-box button {cursor: pointer;width: 112px;height: 44px;line-height: 41px;line-height: 42px;background-color: #ad2a27;border-radius: 0 10px 10px 0;font-size: 17px;box-shadow: none;font-weight: 400;border: 0;outline: 0;letter-spacing: normal;color: white;}body {background: no-repeat center /cover;background-color: #edf0f5;}</style>
</head><body>
<div class="container" id="app"><div class="search-container"><img src="https://www.itheima.com/images/logo.png" alt=""><div class="search-box"><input type="text" v-model="words" id="inp"><button>搜索一下</button></div></div>
</div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>const app = new Vue({el: '#app',data: {words: ''}})
</script></body></html>

完整代码


<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>029生命周期mounted应用输入框获取焦点</title><!-- 初始化样式 --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset.css@2.0.2/reset.min.css"><!-- 核心样式 --><style>html,body {height: 100%;}.search-container {position: absolute;top: 30%;left: 50%;transform: translate(-50%, -50%);text-align: center;}.search-container .search-box {display: flex;}.search-container img {margin-bottom: 30px;}.search-container .search-box input {width: 512px;height: 16px;padding: 12px 16px;font-size: 16px;margin: 0;vertical-align: top;outline: 0;box-shadow: none;border-radius: 10px 0 0 10px;border: 2px solid #c4c7ce;background: #fff;color: #222;overflow: hidden;box-sizing: content-box;-webkit-tap-highlight-color: transparent;}.search-container .search-box button {cursor: pointer;width: 112px;height: 44px;line-height: 41px;line-height: 42px;background-color: #ad2a27;border-radius: 0 10px 10px 0;font-size: 17px;box-shadow: none;font-weight: 400;border: 0;outline: 0;letter-spacing: normal;color: white;}body {background: no-repeat center /cover;background-color: #edf0f5;}</style>
</head><body>
<div class="container" id="app"><div class="search-container"><div class="search-box"><input type="text" v-model="words" id="inp"><button>搜索一下</button></div></div>
</div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>const app = new Vue({el: '#app',data: {words: ''},mounted () {document.querySelector('#inp').focus()}})
</script></body></html>

分析

等input框渲染出来 mounted 钩子

让input框获取焦点 inp.focus()

autofocus在Vue中无用

练习3:记账清单

https://applet-base-api-t.itheima.net/bill

效果显示

静态代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>030练习:记账清单</title><!-- CSS only --><linkrel="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><td>1</td><td>帽子</td><td>99.00</td><td><a href="javascript:;">删除</a></td></tr><tr><td>2</td><td>大衣</td><td class="red">199.00</td><td><a href="javascript:;">删除</a></td></tr></tbody><tfoot><tr><td colspan="4">消费总计: 298.00</td></tr></tfoot></table></div><!-- 右侧图表 --><div class="echarts-box" id="main"></div></div></div><script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>const app = new Vue({el: '#app',data: {},})</script></body>
</html>

完整代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>030练习:记账清单</title><!-- CSS only --><linkrel="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="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>const app = new Vue({el: '#app',data: {list: [],name: '',price: ''},computed: {totalPrice () {return this.list.reduce((sum, item) => sum + item.price, 0)}},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: '50%', // 半径data: [// { value: 1048, name: '球鞋' },// { value: 735, name: '防晒霜' }],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: '。。'}})this.list = res.data.data// 更新图表this.myChart.setOption({// 数据项series: [{// data: [//   { value: 1048, name: '球鞋' },//   { value: 735, 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})// 重新渲染一次this.getList()this.name = ''this.price = ''},async del (id) {// 根据 id 发送删除请求const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)// 重新渲染this.getList()}}})</script></body>
</html>

功能需求:发请求

基本渲染

  1. 立刻发送请求获取数据,created
  2. 拿到数据存到data的响应式数据中
  3. 结合数据,进行渲染v-for
  4. 消费统计,计算属性

this.list.reduce((sum, item) => sum + item.price, 0)

添加功能

  1. 收集表单数据 v-model
  2. 给添加按钮注册点击事件,发送添加请求
  3. 需要重新渲染

<input v-model.trim="name" type="text" class="form-control" placeholder="消费名称" />

去空格

<input v-model.number="price" type="text" class="form-control" placeholder="消费价格" />

取数字

将请求封装成方法,便于调用  this.getList()

删除功能

  1. 注册点击事件,传参传 id
  2. 根据 id 发送删除请求
  3. 需要重新渲染

饼图渲染

  1. 初始化一个饼图 echarts.init(dom)  mounted钩子实现
  2. 根据数据实时更新饼图 echarts.setOption({ ... })

Apache ECharts

data: this.list.map(item => ({ value: item.price, name: item.name}))

将this.list 数组中的每个元素转换为一个新的对象,该对象包含两个属性:value和name,分别对应原始元素中的price和name属性。最终返回一个新数组,其中每个元素都是这样的对象

({})这么写才会被判定为对象

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt---day2-信号与槽

1、思维导图 2、 拖拽式 源文件 #include "mywidget.h" #include "ui_mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::MyWidget) { ui->setupUi(this); //按钮2 this->btn2new QPushButton("按钮2",th…

一键静音,iPhone勿扰模式助你远离干扰

在现代社会的快节奏生活中&#xff0c;我们时常被各种各样的通知、铃声和提示音所打扰&#xff0c;无法专注地工作或享受宁静的时光。而iPhone的勿扰模式功能&#xff0c;就像是一位贴心的助手&#xff0c;能够一键帮你屏蔽这些干扰&#xff0c;让你在需要的时候拥有一个清静的…

MyBatis入门例子

1、建立与数据库对应的POJO类 2、建立mybatis的配置文件 修改后如下&#xff1a; 3、创建POJO对象和Mysql数据的表之间的映射配置 4、建一个测试方法 实现从数据库中取数一条数据&#xff0c;封装成User对象返回 注意点&#xff1a; 这点&#xff0c;大家应该不陌生了&#x…

【系统架构师】-选择题(十四)

1、某企业开发信息管理系统平台进行 E-R 图设计&#xff0c;人力部门定义的是员工实体具有属性&#xff1a;员工号、姓名、性别、出生日期、联系方式和部门,培训部门定义的培训师实体具有属性:培训师号&#xff0c;姓名和职称&#xff0c;其中职称{初级培训师&#xff0c;中级培…

Quora 首席执行官亚当·德安杰洛 (Adam D’Angelo) 谈论了 AI、聊天机器人平台 Poe,以及 OpenAI 为什么不是竞争对手

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)

文章目录 一、目标检测介绍二、YOLOv7介绍三、源码/论文获取四、环境搭建4.1 环境检测 五、数据集准备六、 模型训练七、模型验证八、模型测试九、错误总结9.1 错误1-numpy jas mp attribute int9.2 错误2-测试代码未能跑出检测框9.3 错误3- Command git tag returned non-zero…

C语言猜数字游戏

用C语言实现猜数字游戏&#xff0c;电脑随机给出一个范围内的数字&#xff0c;用户在终端输入数字&#xff0c;去猜大小&#xff1b;对比数字&#xff0c;电脑给出提示偏大还是偏小&#xff1b;不断循环&#xff0c;直到正确 #include <stdio.h> #include <time.h>…

智慧之巅:大数据与算力中心的融合演进

智慧之巅&#xff1a;大数据与算力中心的融合演进 1 引言 在这个数据驱动的时代&#xff0c;我们站在了一个前所未有的历史节点上。大数据和算力中心&#xff0c;这两个曾经各自为政的领域&#xff0c;如今正以一种前所未有的方式交织在一起&#xff0c;共同推动着数字经济的蓬…

python中如何遍历字典

1. 遍历字典的键key ① >>> d{list:[1, 2, 3],1:123,111:python3,tuple:(4, 5, 6)} >>> for key in d:print(str(key):str(d[key])) list:[1, 2, 3] 1:123 111:python3 tuple:(4, 5, 6) ② >>> d{list:[1, 2, 3],1:123,111:python3,tuple:(4, 5, 6…

5.12 VUE项目实现Google 第三方登录

VUE项目实现Google 第三方登录 目录一、Google开发者平台配置1. 新建项目2. 配置 OAuth 权限请求页面并选择范围3. 启动API 和 服务 二、 登录代码实现1. 参考Google官网文档2. Google官网代码生成器3. 项目中实装 目录 一、Google开发者平台配置 Google Cloud: https://conso…

Web Component fancy-components

css-doodle 组件库 fancy-components 组件库使用 yarn add fancy-components使用&#xff1a; import { FcBubbles } from fancy-components new FcBubbles() //要用哪个就new哪个 new 这里可能会报错eslink,eslintrc.js中处理报错 module.exports {rules: {no-new: off} …

《Mask2Former》算法详解

文章地址&#xff1a;《Masked-attention Mask Transformer for Universal Image Segmentation》 代码地址&#xff1a;https://github.com/facebookresearch/Mask2Former 文章为发表在CVPR2022的一篇文章。从名字可以看出文章像提出一个可以统一处理各种分割任务&#xff08;…