潮州网站建设可以访问境外的浏览器
【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!
博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!
吾等采石之人,应怀大教堂之心,愿我们奔赴在各自的热爱里…
一、案例介绍
分享原因:最近看到这样的实时显示的系统觉得很有趣,分享给vue前端初学者实践学习 具体的效果如图所示
数据分析:数据来源于第三方官方提供的API接口,我们调用即可获取对应接口,拿到显示出来即实时展示
百度一下有很多可以直接调用的第三方接口
实时最新疫情数据接口
https://c.m.163.com/ug/api/wuhan/app/data/list-total
实时播报:时间线的对应接口
https://ent.163.com/special/00035080/virus_report_data.js
二、后端代码
后端使用HttpClient创建对象,执行对应的请求即可~
@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {@ApiOperation("/HttpClient使用代码案例")@GetMapping("/getData")public Result getJsonTypeData(@RequestParam(name = "url", required = true) String url) throws Exception {Result result = new Result();//创建HttpClient对象CloseableHttpClient httpClient = HttpClients.createDefault();//设置请求传输超时时间RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();//创建get请求HttpGet httpGet = new HttpGet(url);//设置配置httpGet.setConfig(requestConfig);// 执行请求HttpResponse httpResponse = httpClient.execute(httpGet);//判断响应信息是否正确if (httpResponse.getStatusLine().getStatusCode() == 200) {String jsonResult = EntityUtils.toString(httpResponse.getEntity());JSONObject jsonObject = JSONObject.parseObject(jsonResult);result.setData(jsonObject);result.setCode(200);}return result;}@ApiOperation("/实时播报:时间线的对应接口:此处仅给右下角显示使用")@GetMapping("/getTimeLine")public Result getNoJsonType(@RequestParam(name = "url", required = true) String url) throws IOException {Result result = new Result();//创建HttpClient对象CloseableHttpClient httpClient = HttpClients.createDefault();RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(5000).setRedirectsEnabled(true).build();HttpGet httpGet = new HttpGet(url);httpGet.setConfig(requestConfig);HttpResponse httpResponse = httpClient.execute(httpGet);if (httpResponse.getStatusLine().getStatusCode() == 200) {String jsonResult = EntityUtils.toString(httpResponse.getEntity());result.setData(jsonResult);result.setCode(200);}return result;}
}
三、前端代码
主页面代码以及效果
<template><div class="container"><el-card class="box-card1"><div slot="header" class="title">全国疫情数据(含港澳台)</div><div class="list-total"><div class="item cover_input"><h4>境外输入</h4><div class="number">{{ total.input }}</div><p class="added">较昨日<span>+{{ today.input }}</span></p></div><div class="item cover_nosymptom"><h4>无症状感染者</h4><div class="number">{{ extData.noSymptom }}</div><p class="added">较昨日<span>+{{ extData.incrNoSymptom }}</span></p></div><div class="item cover_today_confirm"><h4>现有确诊</h4><div class="number">{{ total.confirm - total.dead - total.heal }}</div><p class="added">较昨日<span>+{{ today.storeConfirm }}</span></p></div><div class="item cover_confirm"><h4>累计确诊</h4><div class="number">{{ total.confirm }}</div><p class="added">较昨日<span>+{{ today.confirm }}</span></p></div><div class="item cover_dead"><h4>累计死亡</h4><div class="number">{{ total.dead }}</div><p class="added">较昨日<span>+{{ today.dead }}</span></p></div><div class="item cover_heal"><h4>累计治愈</h4><div class="number">{{ total.heal }}</div><p class="added">较昨日<span>+{{ today.heal }}</span></p></div></div><div class="cover_time">截至{{ lastUpdateTime }}</div></el-card><china-map></china-map><line-chart id="line-chart"></line-chart><time-line id="time-line"></time-line></div>
</template><script>import request from "@/utils/request";import LineChart from './components/lineChart.vue'import ChinaMap from './components/map.vue'import TimeLine from './components/timeLine.vue'export default {name: 'Statistics',components: {LineChart,ChinaMap,TimeLine,},data() {return {total: {},today: {},extData: {},lastUpdateTime: '',}},created() {this.getInfo()},mounted() {},methods: {getInfo() {request.get("/demo/getData", {params: {url: 'https://c.m.163.com/ug/api/wuhan/app/data/list-total',}}).then(data => {this.today = data.data.data.chinaTotal.todaythis.total = data.data.data.chinaTotal.totalthis.extData = data.data.data.chinaTotal.extDatathis.lastUpdateTime = data.data.data.lastUpdateTime})},},}
</script>
<style lang="scss" scoped>.box-card1 {width: 440px;float: left;margin-left: 20px;}.list-total {display: flex;flex-wrap: wrap;justify-content: space-around;}.title {color: #333;font-size: 24px;}.item {width: 120px;height: 100px;margin-bottom: 15px;border: 1px dashed #ccc;display: flex;flex-direction: column;justify-content: center;align-content: space-around;}h4 {text-align: center;color: #333;}.number {text-align: center;color: #ffa352;font-weight: 700;font-size: 26px;}.added {text-align: center;color: #999;}.added span {color: #ffa352;}.cover_nosymptom .added span {color: #791618;}.cover_nosymptom .number {color: #791618;}.cover_today_confirm .number {color: #e44a3d;}.cover_today_confirm .added span {color: #e44a3d;}.cover_confirm .number {color: #a31d13;}.cover_confirm .added span {color: #a31d13;}.cover_dead .number {color: #333;}.cover_dead .added span {color: #333;}.cover_heal .number {color: #34aa70;}.cover_heal .added span {color: #34aa70;}.cover_time {color: #a9a9a9;}
</style>
疫情地图显示效果
对应前端代码
<template><el-card class="box-card"><div id="map"></div></el-card>
</template><script>import * as echarts from 'echarts'import china from 'echarts/map/js/china'import request from "@/utils/request";let option = {title: {text: '中国疫情图',},series: [{name: '现有确诊', //控制鼠标hover上去显示的固定文本type: 'map', //告诉echarts需要渲染一个地图mapType: 'china', //告诉echarts要渲染注册的china地图label: {show: true, //控制是否显示省份的名称color: '#333', // 设置显示每个省份的字体颜色},itemStyle: {borderColor: '#e8e8e8', //每个省份的边界的颜色},emphasis: {//控制鼠标移入的版块的颜色color: '#fff', //移入该模块的字体颜色itemStyle: {areaColor: '#83b5e7', //鼠标hover到模块上的背景色},},data: [], //每个板块的数据},],visualMap: [{type: 'piecewise', //左下角的分段显示show: true,pieces: [{min: 10000,max: 1000000,label: '≥ 10000人',color: '#7f1100',},{min: 1000,max: 9999,label: '1000 - 9999人',color: '#bd1316',},{min: 500,max: 999,label: '500 - 999人',color: '#e64b45',},{min: 100,max: 499,label: '100 - 499人',color: '#ff8c71',},{min: 10,max: 99,label: '10 - 99人',color: '#fdd2a0',},{min: 1,max: 9,label: '1 - 9人',color: '#fff2cf',},{min: 0,max: 0,label: '0',color: '#ffffff',},],color: ['#fafafa', '#7f1100'],},],tooltip: {//控制鼠标hover上去显示信息trigger: 'item',formatter: function (params) {//自定义悬浮窗的显示内容return params.name + '<br/>' + params.seriesName + ':' + params.value},},}export default {// 组件名称name: 'ChinaMap',// 组件参数 接收来自父组件的数据props: {},// 组件状态值data() {return {}},// 计算属性computed: {},// 侦听器watch: {},// 以下是生命周期钩子/*** 组件实例创建完成,属性已绑定,但DOM还未生成,$ el属性还不存在*/created() {},/*** el 被新创建的 vm.$ el 替换,并挂载到实例上去之后调用该钩子。* 如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$ el 也在文档内。*/mounted() {this.getData()this.myEcharts = echarts.init(document.getElementById('map'))this.myEcharts.setOption(option)},// 组件方法methods: {getData() {request.get("/demo/getData", {params: {url: 'https://c.m.163.com/ug/api/wuhan/app/data/list-total',}}).then(data => {let list = data.data.data.areaTree[2].children.map((item) => ({name: item.name,value: item.total.confirm - item.total.heal - item.total.dead,}))option.series[0].data = listthis.myEcharts.setOption(option)})},},}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<!--使用了scoped属性之后,父组件的style样式将不会渗透到子组件中,-->
<!--然而子组件的根节点元素会同时被设置了scoped的父css样式和设置了scoped的子css样式影响,-->
<!--这么设计的目的是父组件可以对子组件根元素进行布局。-->
<style scoped>#map {width: 100%;height: 400px;background-color: #f3f3f3;}.box-card {width: 750px;float: left;margin-left: 20px;}
</style>
折线图显示效果
折线图对应代码
<template><el-card class="card-linechart"><div id="linechart"></div></el-card>
</template><script>import * as echarts from 'echarts'import request from "@/utils/request";var option = {title: {text: '全国疫情新增趋势',},tooltip: {trigger: 'axis',},legend: {right: '20px',data: ['确诊', '疑似'],},xAxis: {type: 'category',boundaryGap: false,data: [],},yAxis: {type: 'value',data: ['0', '20', '40', '60', '80', '100', '120', '140'],},series: [{name: '确诊',type: 'line',data: [],},{name: '疑似',type: 'line',data: [],},],}export default {// 组件名称name: 'LineChart',// 组件参数 接收来自父组件的数据props: {},// 组件状态值data() {return {chinaDayList: [],}},// 计算属性computed: {},// 侦听器watch: {},// 以下是生命周期钩子/*** 组件实例创建完成,属性已绑定,但DOM还未生成,$ el属性还不存在*/created() {},/*** el 被新创建的 vm.$ el 替换,并挂载到实例上去之后调用该钩子。* 如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$ el 也在文档内。*/mounted() {this.getData()this.myChart = echarts.init(document.getElementById('linechart'))this.myChart.setOption(option)},// 组件方法methods: {getData() {request.get("/demo/getData", {params: {url: 'https://c.m.163.com/ug/api/wuhan/app/data/list-total',}}).then(data => {this.chinaDayList = data.data.data.chinaDayListoption.series[0].data = []option.series[1].data = []option.xAxis.data = []this.chinaDayList.forEach((item, index) => {option.xAxis.data.push(item.date)option.series[0].data.push(item.today.confirm)option.series[1].data.push(item.today.suspect)})this.myChart.setOption(option)})},},}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<!--使用了scoped属性之后,父组件的style样式将不会渗透到子组件中,-->
<!--然而子组件的根节点元素会同时被设置了scoped的父css样式和设置了scoped的子css样式影响,-->
<!--这么设计的目的是父组件可以对子组件根元素进行布局。-->
<style scoped>.card-linechart {float: left;width: 500px;}#linechart {width: 100%;height: 400px;}
</style>
时间线实现效果
时间线实现前端代码
<template><el-card class="box-timeline"><div slot="header" class="bobao">实时播报</div><el-timeline class="time-container"><el-timeline-itemv-for="(item, index) in timeLineList":key="index":timestamp="item.time"placement="top"><el-card class="content"><div class="tit">{{ item.title }}</div><a :href="item.link" target="_blank" class="detail">查看详细报道</a></el-card></el-timeline-item></el-timeline></el-card>
</template><script>import request from "@/utils/request";export default {// 组件名称name: 'TimeLine',// 组件参数 接收来自父组件的数据props: {},// 组件状态值data() {return {timeLineList: [],}},// 计算属性computed: {},// 侦听器watch: {},// 以下是生命周期钩子/*** 组件实例创建完成,属性已绑定,但DOM还未生成,$ el属性还不存在*/created() {this.getData()},/*** el 被新创建的 vm.$ el 替换,并挂载到实例上去之后调用该钩子。* 如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$ el 也在文档内。*/mounted() {},// 组件方法methods: {getData() {request.get("/demo/getTimeLine", {params: {url: 'https://ent.163.com/special/00035080/virus_report_data.js',}}).then(data => {let str = data.datathis.timeLineList = eval('(' + str.slice(str.indexOf('(') + 1, -1) + ')').list.slice(0, 10)})},},}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<!--使用了scoped属性之后,父组件的style样式将不会渗透到子组件中,-->
<!--然而子组件的根节点元素会同时被设置了scoped的父css样式和设置了scoped的子css样式影响,-->
<!--这么设计的目的是父组件可以对子组件根元素进行布局。-->
<style scoped>.box-timeline {width: 500px;float: left;margin-left: 20px;}.bobao {height: 20px;font-weight: 700;font-size: 18px;}.time-container {/* width: 100%; */height: 400px;overflow: auto;}.content {width: 340px;background-color: #f4f4f4;border-radius: 8px;}.tit {font-weight: 600;font-size: 18px;}.detail {color: #999;margin-top: 20px;display: block;position: relative;}.detail::before {position: absolute;content: '';right: 200px;top: 3px;width: 12px;height: 12px;background: url('./../../images/arrow.png') no-repeat;background-size: 100% 100%;}
</style>
本来很早就写好了,发的比较晚,当自己学习了
好了,未来争取输出更多干货视文章……
📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!
📚愿我们奔赴在各自的热爱里!我们未来见……