vue3+axios使用echarts的地图
vue3+axios使用echarts的地图
概述:
在echarts的官网是直接提供的js代码和网上,如何在vue3中跑起来(各种跨域,各种报错让我想die)
附加:之前一直跑不起来的很大原因是完全不清楚生命周期,破案了
友情链接:
(75条消息) vue+Echarts动态数据已经赋值,但是无法渲染页面的问题_高小胖爱胡小宝的博客-CSDN博客
引用本地json
echarts5.0取消了内置的map(地图不合法....)
有两类方法:
a.下载china.json等文件并放置在public文件夹
创建ChinaMap2.vue
在script部分:
import * as echarts from "echarts"; import usaJson from "/public/USA.json";//此处必须要用绝对路径(网上百度未理解)
在vue2中本地的json文件存放在static文件夹下
在vue3中本身不带static文件夹,我们约定俗成把本地json放在public文件夹下(或者在public下再新建static文件夹)
我们先对官网的示例进行一些改造从而跑起来...
我虽然用的是vue3,但觉得现阶段vue2的data methods的写法非常清晰舒服,目前还没有感受到vue3的setup之好处
//echarts的地图要点:引入地图json文件后要注册 并且写正确的名字,必须是“CHINA” "USA" //echarts.registerMap("USA", usaJson); export default { name: "eTest", data() { return { myChart: "", }; }, methods: { initChart() { var chartDom = document.getElementById("main"); this.myChart = echarts.init(chartDom); var option; this.myChart.showLoading(); console.log(usaJson); //usaJson早就被引入 成功注册地图 echarts.registerMap("USA", usaJson); this.myChart.hideLoading(); //像这种纯静态的option也可以写到一个src/views/mapOption.js再去引入减少代码量 //例如ChinaMap3 option = { title: { text: "USA Population Estimates (2012)", subtext: "Data from www.census.gov", sublink: "http://www.census.gov/popest/data/datasets.html", left: "right", }, tooltip: { trigger: "item", showDelay: 0, transitionDuration: 0.2, }, visualMap: { left: "right", min: 500000, max: 38000000, inRange: { color: [ "#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf", "#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026", ], }, text: ["High", "Low"], calculable: true, }, toolbox: { show: true, //orient: 'vertical', left: "left", top: "top", feature: { dataView: { readOnly: false }, restore: {}, saveAsImage: {}, }, }, series: [ { name: "USA PopEstimates", type: "map", roam: true, map: "USA", emphasis: { label: { show: true, }, }, data: [ { name: "Alabama", value: 4822023 }, { name: "Alaska", value: 731449 }, { name: "Arizona", value: 6553255 }, { name: "Arkansas", value: 2949131 }, { name: "California", value: 38041430 }, { name: "Colorado", value: 5187582 }, { name: "Connecticut", value: 3590347 }, { name: "Delaware", value: 917092 }, { name: "District of Columbia", value: 632323 }, { name: "Florida", value: 19317568 }, { name: "Georgia", value: 9919945 }, { name: "Hawaii", value: 1392313 }, { name: "Idaho", value: 1595728 }, { name: "Illinois", value: 12875255 }, { name: "Indiana", value: 6537334 }, { name: "Iowa", value: 3074186 }, { name: "Kansas", value: 2885905 }, { name: "Kentucky", value: 4380415 }, { name: "Louisiana", value: 4601893 }, { name: "Maine", value: 1329192 }, { name: "Maryland", value: 5884563 }, { name: "Massachusetts", value: 6646144 }, { name: "Michigan", value: 9883360 }, { name: "Minnesota", value: 5379139 }, { name: "Mississippi", value: 2984926 }, { name: "Missouri", value: 6021988 }, { name: "Montana", value: 1005141 }, { name: "Nebraska", value: 1855525 }, { name: "Nevada", value: 2758931 }, { name: "New Hampshire", value: 1320718 }, { name: "New Jersey", value: 8864590 }, { name: "New Mexico", value: 2085538 }, { name: "New York", value: 19570261 }, { name: "North Carolina", value: 9752073 }, { name: "North Dakota", value: 699628 }, { name: "Ohio", value: 11544225 }, { name: "Oklahoma", value: 3814820 }, { name: "Oregon", value: 3899353 }, { name: "Pennsylvania", value: 12763536 }, { name: "Rhode Island", value: 1050292 }, { name: "South Carolina", value: 4723723 }, { name: "South Dakota", value: 833354 }, { name: "Tennessee", value: 6456243 }, { name: "Texas", value: 26059203 }, { name: "Utah", value: 2855287 }, { name: "Vermont", value: 626011 }, { name: "Virginia", value: 8185867 }, { name: "Washington", value: 6897012 }, { name: "West Virginia", value: 1855413 }, { name: "Wisconsin", value: 5726398 }, { name: "Wyoming", value: 576412 }, { name: "Puerto Rico", value: 3667084 }, ], }, ], }; this.myChart.setOption(option); }, }, mounted() { this.initChart(); }, };
b.下载map的包放在node moudle下
import chinaJson from "echarts/map/js/china.js"
引用网络json+引用后端数据
当我们使用axios向网络,像后端引用数据时,开始一个个匪夷所思的错误
这其中一部分是跨域请求造成的问题:
如果是后端:
Access-Control-Allow-Origin
但如果我们请求网络资源,并不能改变后端呢??
问题A:前端解决跨域问题(配置proxy的代理)
配置完代理后重新启动!!!重刷新不管用!!!
什么是跨域问题:
在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号(如存在)相同,则允许相互访问。
比如 vue项目的端口是8081
自己电脑开启了一个8080的端口,请求/getData就会放回json数据。
正确的做法是在配置文件中添加跨域:
vue2直接在config/index.js中配置
vue3需要在根目录下创建一个vue.config.js的配置文件
//vue.config.js module.exports = { outputDir: 'dist', //build输出目录 assetsDir: 'assets', //静态资源目录(js, css, img) lintOnSave: false, //是否开启eslint devServer: { open: true, //是否自动弹出浏览器页面 host: "localhost", port: '8080', https: false, proxy: { '/api': { target: 'https://echarts.apache.org', //API服务器的地址 changeOrigin: true, pathRewrite: { '^/api': '' }, }, }, } }
然后在axios请求时这么写(此时的api会被替换成上面配置的target)
initChart() { axios({ method:"get", url:"/api/examples/data/asset/geo/USA.json" }).then((res)=>{ this.usaJson=res.data; this.initChart2(); }) },
问题B:axios的异步请求
axios请求数据所造成的系列问题处理方法:
axios是异步的,其中的then是回调,也就是说会继续执行后面的代码,在不考率这一点的时候,我们在回调中进行log打印觉得已经得到了数据,但其实后面的代码在执行时对着空数据做事。这个错不明显且让人疑惑
在看上去成功读到数据,网页却没有显示时,考虑axios的异步请求是否成功,考虑自己对于res.data的属性写对了没,之前dataList写成datalist,哪里都不报错,vscode也没提示,找了半天
一种方法:将我们的主要逻辑全部放在回调中(.then)
第二种方法:在函数名前加async,在axios的调用前加await
methods: { async getData(){ //会阻塞在此处等待 var res=await axios.get("http://localhost:8081/test5") this.myjson=res.data.dataList; console.log(this.myjson); } },
附加点:axios的请求和封装
(还没有搞懂请求响应拦截什么的)
完整过一遍axios,再也不怕写请求 - 掘金 (juejin.cn)
如果没有给axios配置baseURL,在每次写都是http://localhost:8080/....
axios的基本知识
一种是
axios.post('/post',data).then((res)=>{ console.log(res) })
另一种是
axios({ method:'post', url:'/post', data:data }).then(...)
当我们需要传入参数时: http://localhost:8080/data.json?id=12,应该如何去获取呢?
axios.get('/data.json',{ params:{ id:12 } }).then((res)=>{ console.log(res) })
axios的封装(参考tansci)
现在utils里封装axios.js 配置了axios的基本信息,响应拦截
//export default API export default axios
在api中的systemapi:一次性写好所有的会用到请求的函数(这里每一个参数都是params,继续看知道为什么)
在views中
成功代码:
地图来自网络请求,数据来自mock接口模拟
<template> <div class="echartss"> <div id="main" style="width: 1000px; height: 400px"></div> </div> </template> <script> import * as echarts from "echarts"; import axios from "axios"; //import usaJson from "/public/USA.json" //import option from "./mapOption.js"; export default { name: "eTest", data() { return { myChart: "", usaJson:[], datax: [], max:"", min:"", }; }, methods: { initdata() { axios({ method: "get", url: "http://localhost:8081/test5", //mock接口 }).then((res) => { //网上找来的最大最小值迅速get console.log(res.data.dataList) this.datax=res.data.dataList; this.max=Math.max.apply(Math,this.datax.map(function(o){ return o.value; })) this.min=Math.min.apply(Math,this.datax.map(function(o){ return o.value; })) this.initChart(); }); }, initChart() { //var ROOT_PATH = 'https://echarts.apache.org/examples'; axios({ method:"get", url:"/api/examples/data/asset/geo/USA.json" }).then((res)=>{ //都写在回调函数里,呜呜呜,之前莫名奇妙了100回 this.usaJson=res.data; this.initChart2(); }) }, initChart2(){ var chartDom = document.getElementById("main"); //this.myChart = echarts.init(chartDom); console.log(this.usaJson); echarts.registerMap("USA", this.usaJson); //console.log(echarts.getMap()); console.log(echarts.version); this.myChart = echarts.init(chartDom); var option = { title: { text: "USA Population Estimates (2012)", subtext: "Data from www.census.gov", sublink: "http://www.census.gov/popest/data/datasets.html", left: "right", }, tooltip: { trigger: "item", showDelay: 0, transitionDuration: 0.2, }, visualMap: { left: "right", min:this.min, max:this.max, inRange: { color: [ "#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf", "#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026", ], }, text: ["High", "Low"], calculable: true, }, toolbox: { show: true, //orient: 'vertical', left: "left", top: "top", feature: { dataView: { readOnly: false }, restore: {}, saveAsImage: {}, }, }, series: [ { name: "USA PopEstimates", type: "map", roam: true, map: "USA", emphasis: { label: { show: true, }, }, data: this.datax, }, ], }; this.myChart.setOption(option); } }, mounted() { this.initdata(); }, }; </script> <style> </style>
加一个简单的elementplus玩玩:
先把官网的一个代码复制过来,发现不行,报错难以理解
仔细一看:
我用的是js,这里怎么是ts。把lang=ts删除,成功
:data 响应式 后到前可变
infos:
然后在methods产生变化
总代码:
<template> <h1>这里是Demo!</h1> <el-row> <el-button>Default</el-button> <el-button type="primary">Primary</el-button> <el-button type="success">Success</el-button> <el-button type="info">Info</el-button> <el-button type="warning">Warning</el-button> <el-button type="danger">Danger</el-button> <el-button @click="showinfo">更新infos</el-button> </el-row> <p>{{ info }}</p> <p>{{ infos }}</p> <el-table :data="infos" border style="width: 100%"> <el-table-column prop="name" label="地区名称" width="180" /> <el-table-column prop="value" label="销售总额" /> </el-table> <div class="echartss"> <div id="main" style="width: 1000px; height: 400px"></div> </div> </template> <script> import * as echarts from "echarts"; import axios from "axios"; import chinaJson from "echarts/map/js/china.js"; export default { name: "demo", data() { return { infos: [{ name: "waiting", value: "undefined" }], info: "hello joker", myChart: "", datax: [], max:"", min:"", }; }, methods: { initdata() { axios({ method: "get", url: "http://localhost:8081/test4", }).then((res) => { console.log(res.data.dataList) this.datax=res.data.dataList; this.max=Math.max.apply(Math,this.datax.map(function(o){ return o.value; })) this.min=Math.min.apply(Math,this.datax.map(function(o){ return o.value; })) this.initChart(); }); }, initChart() { //var ROOT_PATH = 'https://echarts.apache.org/examples'; var chartDom = document.getElementById("main"); //this.myChart = echarts.init(chartDom); echarts.registerMap("China", chinaJson); //console.log(echarts.getMap()); console.log(echarts.version); this.myChart = echarts.init(chartDom); var option = { title: { text: "USA Population Estimates (2012)", subtext: "Data from www.census.gov", sublink: "http://www.census.gov/popest/data/datasets.html", left: "right", }, tooltip: { trigger: "item", showDelay: 0, transitionDuration: 0.2, }, visualMap: { left: "right", min:this.min, max:this.max, inRange: { color: [ "#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf", "#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026", ], }, text: ["High", "Low"], calculable: true, }, toolbox: { show: true, //orient: 'vertical', left: "left", top: "top", feature: { dataView: { readOnly: false }, restore: {}, saveAsImage: {}, }, }, series: [ { name: "China PopEstimates", type: "map", roam: true, map: "china", emphasis: { label: { show: true, }, }, data: this.datax, }, ], }; this.myChart.setOption(option); }, showinfo() { axios .get("http://localhost:8081/test4") .then((response) => { this.infos = response.data.dataList; }) .catch((error) => { console.log(error); }); }, }, mounted() { this.initdata(); this.showinfo(); }, }; </script> <style> </style>