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数据。

1665905813236

正确的做法是在配置文件中添加跨域:

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,继续看知道为什么)

1665903680195

在views中

1665903755835

1665903790245

成功代码:

地图来自网络请求,数据来自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玩玩:

先把官网的一个代码复制过来,发现不行,报错难以理解

仔细一看:1665905307395

我用的是js,这里怎么是ts。把lang=ts删除,成功

1665905423552

:data 响应式 后到前可变

infos:1665905653204

然后在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>

 

posted @ 2023-01-03 15:53  爵岚  阅读(239)  评论(0编辑  收藏  举报