Vue实战篇可视化+Echarts5.0

 

 node/使用命令: https://nodejs.org/zh-cn/

npm install -g @vue/cli

npm install ts-node -g npm init -y npm install @types/node -D npm install express -S npm install @types/express -D npm install axios -S

 实时更新|新冠肺炎疫情地图 (sina.cn)

 下载源码:novid19搜索

https://search.gitee.com/?skin=rec&type=repository&q=novid19

下载完成,web和node 安装依赖

npm install 

项目启动

npm run dev

node/index.ts代码

// @ts-ignore 错误忽略
import express, {Express, Request, Response, Router} from "express"; // {类型}
// axios
import axios from "axios";


// 接口函数: 前端交互
const app:Express = express()

// 路由去分模块,避免所有路由都写在入口文件中
const router:Router = express.Router()

// 中间件注册,路由注册
app.use('/api',router)
// 路由请求:req接收前端,resp响应返给前端
router.get('/list', async (require:Request,response:Response)=>{
    const result = await axios.post('https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=statisGradeCityDetail,diseaseh5Shelf')
    response.json({ // 响应返给前端
        data: result.data
    })
})

// 开启服务: 端口3333,接收回调
app.listen(3333,()=>{
    console.log('success server http://localhost:3333')
})

在package.json中添加:npm run dev运行

 

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "ts-node index.ts"
  },

试用apipost工具测试

http://localhost:3333/api/list

看是否获取到数据

 

第三章 初始化前端

npm init vue@latest

安装less

npm install less less-loader -D

安装Element-Plus

# NPM
$ npm install element-plus --save

# Yarn
$ yarn add element-plus

# pnpm
$ pnpm install element-plus 

Volar 支持#

如果您使用 Volar,请在 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型。

// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": ["element-plus/global"]
  }
}

按需导入

npm install -D unplugin-vue-components unplugin-auto-import

然后把下列代码插入到你的 Vite 或 Webpack 的配置文件中

Vite
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

 

安装axios

npm install axios

App.vue

<template>
<!--    引入背景bg-->
<!--    <div :style="{ background: `url(${bg})` }" class="box">-->
    <div class="box">
        <div class="box-left"></div>
        <div class="box-center"></div>
        <div class="box-right"></div>
    </div>
</template>


<script setup lang="ts">
// 引入背景
import bg from './assets/xinguan.jpg'
// 引入
import {useCounterStore} from "@/stores";

const store = useCounterStore()
// 有跨域问题:需要node/index.ts开启跨域
store.getList()

</script>

<style lang="less">
*{//清除样式
  padding: 0;
  margin: 0;
}
html,body,#app{
  height: 100%;
  height: 100vh;
  overflow: hidden; // 超出部分隐藏
  background-image: url("./assets/xinguan.jpg"); // 背景
  background-size: 100% 100%; // 背景大小
}
.box{
  height: 100%;
  display: flex; // 弹性布局
  overflow: hidden;
  &-left{
    width: 400px;
  }
  &-center{
    flex: 1;
  }
  &-right{
    width: 400px;
  }
}


</style>

store/index.ts

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
//  引入
import {getApiList} from "@/server";

/*export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }
  return { count, doubleCount, increment }
})*/

export const useCounterStore = defineStore({
  id: 'counter',
  state:() => ({
    list: {

    }
  }),
  actions: {
    async getList () { // 同步
      const result = await getApiList()

      console.log(result); // 跨域问题,App.vue中引入
    }
  }
})

node/index.ts

// @ts-ignore
import express, {Express, Request, Response, Router} from "express"; // {类型}
// axios
import axios from "axios";

// 接口函数: 前端交互
const app:Express = express()

// 解决vite-demo中跨域问题
app.use('*',(req,res,next) =>{// 允许跨域
    res.header('Access-Control-Allow-Origin','*'); // '*‘可以指定IP
    next();
})

// 路由去分模块,避免所有路由都写在入口文件中
const router:Router = express.Router()

// 中间件注册,路由注册
app.use('/api',router)
// 路由请求:req接收前端,resp响应返给前端
router.get('/list', async (req:Request,res:Response)=>{
    const result = await axios.post('https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=statisGradeCityDetail,diseaseh5Shelf')
    res.json({ // 响应返给前端
        ...result.data.data
    })
})

// 开启服务: 端口3333,接收回调
app.listen(3333,()=>{
    console.log('success server http://localhost:3333')
})

server/index.ts

// 引入axios
import axios from "axios";

// 创建实例
const server = axios.create({
    baseURL:"http://localhost:3333"  // 每次请求:后台接口
})

// 导出Api
export const getApiList = () => server.get('/api/list').then(res => res.data)

 第四章 Map 和 ECharts可视化

  

 

  

安装Echarts

npm install echarts -S

引入时:将所有Api生成一个对象,启用别名

// 引入钩子:获取Dom
import {onMounted} from "vue";
// 引入echarts可视化:将所有Api成一个对象 需要别名
import * as echarts from 'echarts'

onMount钩子中:#china对应的 <div id="china"></div>

 

onMounted(() =>{
    echarts.init(document.querySelector('#china') as HTMLElement)
})

1. 在绘图前我们需要为 ECharts 准备一个定义了高宽的 DOM 容器

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <div id="main" style="width: 600px;height:400px;">
</template>

2.初始化

// 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById('main'));

3.指定图表的配置项和数据,Vue3.2不同点

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>ECharts</title>
    <!-- 引入刚刚下载的 ECharts 文件 -->
    <script src="echarts.js"></script>
  </head>
  <body>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      var myChart = echarts.init(document.getElementById('main'));

      // 指定图表的配置项和数据
      var option = {
        title: {
          text: 'ECharts 入门示例'
        },
        tooltip: {},
        legend: {
          data: ['销量']
        },
        xAxis: {
          data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
          {
            name: '销量',
            type: 'bar',
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      };

      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    </script>
  </body>
</html>

Vue3中:局部引入echart,注意不同点

第一种方法:

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width: 600px;height:400px;"></div>
</template>

<script setup lang="ts">
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'

const chart =ref(); // 创建DOM引用

// 使用生命钩子
onMounted(() => {
    init(); // vue3.2没有this
})

// 第一种方法:初始化方法
function init (){
    // 基于准备好的dom,初始化echarts实例
    // var myChart = echarts.init(document.getElementById('main'));
    // Vue3中: 需要全局引入
    var myChart = echarts.init(chart.value)


    // 指定图表的配置项和数据
    var option = {
        title: { // 标题
            text: 'ECharts 入门示例'
        },
        tooltip: {},  // 提示
        legend: {  // 图例
            data: ['销量']
        },
        xAxis: { // x轴
            data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {}, // y轴
        series: [ // data数据
            {
                name: '销量',
                type: 'bar', // 图样类型
                data: [5, 20, 36, 10, 10, 20] // 图标数据
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
}
</script>

<style scoped>

</style>

第二种方法

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width: 600px;height:400px;"></div>
</template>

<!--echarts中报红,取消lang='ts'--> <script setup > import {onMounted, reactive, ref} from "vue"; // 局部引入echarts核心模块 import * as echarts from 'echarts' const chart =ref(); // 创建DOM引用 // 第二种方法:初始化方法 const option = reactive({ // 指定图表的配置项和数据 title: { // 标题 text: 'ECharts 入门示例' }, tooltip: {}, // 提示 legend: { // 图例 data: ['销量'] }, xAxis: { // x轴 data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, // y轴 series: [ // data数据 { name: '销量', type: 'bar', // 图样类型 data: [5, 20, 36, 10, 10, 20] // 图标数据 } ] }) // 使用生命钩子 onMounted(() => { // 基于准备好的dom,初始化echarts实例 // var myChart = echarts.init(document.getElementById('main')); // Vue3中: 需要引入 var myChart = echarts.init(chart.value) // init(); // vue3.2没有this // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); }) </script> <style scoped> </style>

echarts使用配置手册

 

 

 常用代码:

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width: 600px;height:400px;"></div>
</template>

<script setup >
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'

const chart =ref(); // 创建DOM引用

// 第二种方法:初始化方法
const option = reactive({
    // 指定图表的配置项和数据
    title: { // 标题
        // left: 'center', // 居中
        text: 'ECharts 入门示例',
        left: 'center',
        textStyle: {
            color: '#f60',
            fontSize: 20,
        }
    },
    color: '#f00', // 系列柱的颜色
    tooltip: {},  // 提示
    legend: {  // 图例
        data: ['销量'],
        top: '5%',
        left: 'right',
        textStyle: { // 文字样式
            color: '#f68',
        }
    },
    xAxis: { // x轴
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
        axisLine: { // 设置轴
            lineStyle: { // 样式
                color:'#000' // 颜色
            }
        },

        axisLabel:{
            interval: 0,
            formatter: value => value.split('').join('\n') //报红:取消lang='ts'
        }
    },
    yAxis: { // y轴
        axisLine: { // 设置轴
            lineStyle: { // 样式
                color:'#000' // 颜色
            }
        },
        axisLabel:{
            // formatter: '{value} 件'
            formatter: function(value,index){ // 报红:取消lang='ts'
                return value %2 == 0 ? value + '' : value  // 可写各种逻辑判断: 奇偶数
            }
        }
    },
    series: [ // data数据
        {
            name: '销量',
            type: 'bar', // 图样类型
            data: [5, 20, 36, 10, 10, 20], // 图标数据
            label: {
                show: true,
                position: 'top'
            },
        }
    ]
})

// 使用生命钩子
onMounted(() => {
    // 基于准备好的dom,初始化echarts实例
    // var myChart = echarts.init(document.getElementById('main'));
    // Vue3中: 需要引入
    var myChart = echarts.init(chart.value)

    // init(); // vue3.2没有this
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
})

</script>

<style scoped>

</style>

自适应响应式:

1、单一图表

 

 

 在noMounted生命钩子中

 

 

 2、多图表组件使用

index/index.vue 中引入:单图表组件echarts.vue\echarts1.vue\echarts2.vue 

<template>
    <div>
        <!--可以复用-->
        <charts></charts>
        <charts1></charts1>
        <charts2></charts2>

    </div>
</template>

<script setup >
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'
// 引入单一图表:可以复用
import Charts from './Charts.vue'
import Charts1 from './Charts1.vue'
import Charts2 from './Charts2.vue'

const chart = ref(); // 创建DOM引用

</script>

<style scoped>

</style>

新建index/chart.vue,单图表组件

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width: 100%;height:400px;"></div>
</template>

<script setup >
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'

const chart =ref(); // 创建DOM引用

// 第二种方法:初始化方法
const option = reactive({
    // 指定图表的配置项和数据
    title: { // 标题
        // left: 'center', // 居中
        text: 'ECharts 入门示例',
        left: 'center',
        textStyle: {
            color: '#f60',
            fontSize: 20,
        }
    },
    color: '#f00', // 系列柱的颜色
    tooltip: {},  // 提示
    legend: {  // 图例
        data: ['销量'],
        top: '5%',
        left: 'right',
        textStyle: { // 文字样式
            color: '#f68',
        }
    },
    xAxis: { // x轴
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
        axisLine: { // 设置轴
            lineStyle: { // 样式
                color:'#000' // 颜色
            }
        },

        axisLabel:{
            interval: 0,
            formatter: value => value.split('').join('\n') //报红:取消lang='ts'
        }
    },
    yAxis: { // y轴
        axisLine: { // 设置轴
            lineStyle: { // 样式
                color:'#000' // 颜色
            }
        },
        axisLabel:{
            // formatter: '{value} 件'
            formatter: function(value,index){ // 报红:取消lang='ts'
                return value %2 == 0 ? value + '' : value  // 可写各种逻辑判断: 奇偶数
            }
        }
    },
    series: [ // data数据
        {
            name: '销量',
            type: 'bar', // 图样类型
            data: [5, 20, 36, 10, 10, 20], // 图标数据
            label: {
                show: true,
                position: 'top'
            },
        }
    ]
})

// 使用生命钩子
onMounted(() => {
    // 基于准备好的dom,初始化echarts实例
    // var myChart = echarts.init(document.getElementById('main'));
    // Vue3中: 需要引入
    var myChart = echarts.init(chart.value)

    // init(); // vue3.2没有this
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);

    // 单图表响应式: 跟随浏览器大小改变
    window.addEventListener('resize',()=>{
        myChart.resize()
    })

})

</script>

<style scoped>

</style>

新建index/chart1.vue,单图表组件:曲线图

 

 新建index/chart2.vue,单图表组件:饼形图

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width: 100%;height:400px;"></div>
</template>

<script setup >
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'

const chart =ref(); // 创建DOM引用

// 第二种方法:初始化方法
const option = reactive({
    tooltip: {
        trigger: 'item'
    },
    legend: {
        top: '5%',
        left: 'center'
    },
    series: [
        {
            name: 'Access From',
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            itemStyle: {
                borderRadius: 10,
                borderColor: '#fff',
                borderWidth: 2
            },
            label: {
                show: false,
                position: 'center'
            },
            emphasis: {
                label: {
                    show: true,
                    fontSize: 40,
                    fontWeight: 'bold'
                }
            },
            labelLine: {
                show: false
            },
            data: [
                { value: 1048, name: 'Search Engine' },
                { value: 735, name: 'Direct' },
                { value: 580, name: 'Email' },
                { value: 484, name: 'Union Ads' },
                { value: 300, name: 'Video Ads' }
            ]
        }
    ]
})

// 使用生命钩子
onMounted(() => {
    // 基于准备好的dom,初始化echarts实例
    // var myChart = echarts.init(document.getElementById('main'));
    // Vue3中: 需要引入
    var myChart = echarts.init(chart.value)

    // init(); // vue3.2没有this
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);

    // 单图表响应式: 跟随浏览器大小改变
    window.addEventListener('resize',()=>{
        myChart.resize()
    })

})

</script>

<style scoped>

</style>

V3.2中具体传参方式:deineProps和defineEmits

 

 

  

 

 

 

 数据传参:

index/index.vue父组件:父传子

<template>
    <div>
        <!--可以复用-->
        <!--自定义传参:父传子-->
        <charts :chartType="'bar'" :chartData="[150,200,345,1030,102,202]"></charts>
        <charts :chartType="'line'" :chartData="[50,100,240,530,152,252]"></charts>
        <charts1></charts1>
        <charts2></charts2>

    </div>
</template>

charts.vue子组件: 接收

1、接收父传参:指定类型

// const props = defineProps({ // 宏接收:父传参
// 解构优化
const {chartType,chartData}= defineProps({ // 宏接收:父传参
    chartType:{
        type: String
    },
    chartData: {
        type: Array
    }
})

2、修改属性series:[ ]中的:图样和图表

series: [ // data数据
        {
            name: '销量',
            // type: 'bar', // 图样类型
            // type: props.chartType, // 父传参:自定义
            type:chartType, // 结构优化
            // data: [5, 20, 36, 10, 10, 20], // 图表数据
            // data: props.chartData,
            data: chartData,
            label: {
                show: true,
                position: 'top'
            },
        }
    ]

完成代码:

main.ts

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from "@/router/index";
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(ElementPlus)

app.mount('#app')

router/index.vue路由配置

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    /*{
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/AboutView.vue')
    },*/
    {
      path: '/navMenu',
      name: 'navMenu',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/navMenu.vue')
    },
    {
      path: '/index',
      name: 'index',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/index/index.vue')
    },
    {
      path: '/order',
      name: 'order',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/order/index.vue')
    },
    {
      path: '/other',
      name: 'other',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/other/index.vue')
    }
  ]
})

export default router

App.vue

<template>
    <div id="module" class="common-layout">
        <el-container>
            <NavMenu></NavMenu>
            <el-container>
                <el-header>Header</el-header>
                <el-main>
                    <!--路由匹配-->
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </div>
</template>

<script setup lang="ts">
// 引入navMenu组件
import NavMenu from './views/navMenu.vue'



</script>

<style lang="less">


</style>

navMenu.vue

<template>
    <el-aside width="200px" class="aside">
        <el-menu
            default-active="2"
            class="el-menu-vertical-demo" router>
            <el-menu-item :index="v.url" v-for="v in items" :key="v.url">
                <el-icon><setting /></el-icon>
                <span>{{ v.name }}</span>
            </el-menu-item>
        </el-menu>
    </el-aside>
</template>

<script setup lang="ts">
import {reactive} from "vue";

const items = reactive([
    {name:'首页',url:'/index'},
    {name:'订单页',url:'/order'},
    {name:'其他页',url:'/other'},
])

</script>

<style scoped>

</style>

index/charts

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width: 100%;height:400px;"></div>
</template>

<script setup >
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'

// const props = defineProps({ // 宏接收:父传参
// 结构优化
const {chartType,chartData}= defineProps({ // 宏接收:父传参
    chartType:{
        type: String
    },
    chartData: {
        type: Array
    }
})

const chart =ref(); // 创建DOM引用

// 第二种方法:初始化方法
const option = reactive({
    // 指定图表的配置项和数据
    title: { // 标题
        // left: 'center', // 居中
        text: 'ECharts 入门示例',
        left: 'center',
        textStyle: {
            color: '#f60',
            fontSize: 20,
        }
    },
    color: '#f00', // 系列柱的颜色
    tooltip: {},  // 提示
    legend: {  // 图例
        data: ['销量'],
        top: '5%',
        left: 'right',
        textStyle: { // 文字样式
            color: '#f68',
        }
    },
    xAxis: { // x轴
        data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'],
        axisLine: { // 设置轴
            lineStyle: { // 样式
                color:'#000' // 颜色
            }
        },

        axisLabel:{
            interval: 0,
            formatter: value => value.split('').join('\n') //报红:取消lang='ts'
        }
    },
    yAxis: { // y轴
        axisLine: { // 设置轴
            lineStyle: { // 样式
                color:'#000' // 颜色
            }
        },
        axisLabel:{
            // formatter: '{value} 件'
            formatter: function(value,index){ // 报红:取消lang='ts'
                return value %2 == 0 ? value + '' : value  // 可写各种逻辑判断: 奇偶数
            }
        }
    },
    series: [ // data数据
        {
            name: '销量',
            // type: 'bar', // 图样类型
            // type: props.chartType, // 父传参:自定义
            type:chartType, // 解构优化
            // data: [5, 20, 36, 10, 10, 20], // 图标数据
            // data: props.chartData,
            data: chartData,
            label: {
                show: true,
                position: 'top'
            },
        }
    ]
})

// 使用生命钩子
onMounted(() => {
    // 基于准备好的dom,初始化echarts实例
    // var myChart = echarts.init(document.getElementById('main'));
    // Vue3中: 需要引入
    var myChart = echarts.init(chart.value)

    // init(); // vue3.2没有this
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);

    // 单图表响应式: 跟随浏览器大小改变
    window.addEventListener('resize',()=>{
        myChart.resize()
    })

})

</script>

<style scoped>

</style>

 优化布局

 

 index/index

<template>
    <div class="df">
        <!--布局:46分-->
        <!--<div style="flex: 0 1 40%" class="content">-->
        <div style="flex:0 1 40%">
            <div>
                <!--可以复用-->
                <!--自定义传参:父传子-->
                <charts :chartType="'bar'" :chartData="[150,200,345,1030,102,202]"></charts>
            </div>
            <div>
                <charts :chartType="'line'" :chartData="[50,100,240,530,152,252]"></charts>
            </div>
            <div>
                <charts :chartType="'line'" :chartData="[50,100,240,530,152,252]"></charts>
            </div>
        </div>

        <div style="flex: 0 1 60%">
            <div>
                <charts2></charts2>
            </div>
        </div>
    </div>
</template>

<script setup >
// import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
// import * as echarts from 'echarts'
// 引入单一图表:可以复用
import Charts from './Charts.vue'
// import Charts1 from './Charts1.vue'
import Charts2 from './Charts2.vue'



</script>

<style scoped lang="less">
.df {
    display: flex; // 弹性布局
}

</style>

 地图图例篇

引入Echarts,还需引入地图问题文件:数据源

1、如何获取数据源:查看echarts地图中完整代码Path路径

 

 

 https://echarts.apache.org/examples/data/asset/geo/HK.json

如何获取中国地图的shp文件(含省级)

1、下载地图json文件

网址:DataV.GeoAtlas地理小工具系列

 

 

 

 

2、点击下载文件

 

 

也可以用geopandas打开。

3、点开

选择文件并输出

 

 export

 

  

 这个边界时包含九段线的,还是很赞的。下一期试试疫情可视化。

 

2、获取到数据后,引入和注册

// 局部引入echarts核心模块
import * as echarts from 'echarts'
// 还需引入地图文件
import chinaMap from '../../assets/china1.json'

onMounted中:注册

// 注册可用的地图
    echarts.registerMap('china',chinaMap);

option中写入相关属性

const option = reactive({// 指定图表的配置项和数据
    series: [{ // 地图不需XY轴
        type: 'map', // 图表类型
        map: 'china', // 地图类型
    }]
})

以上步骤要牢记!

丰富地图属性

 

 

 常用option属性设置:要改变样式类别:label

const option = reactive({// 指定图表的配置项和数据
    series: [{ // 地图不需XY轴
        type: 'map', // 图表类型
        map: 'china', // 地图类型
        label: { // 标签:地图中的标签、文字
            show: true, // 开启地图中的标签、文字等,(必须开启)
            color: '#fff',
            fontSize:11,
        },
        itemStyle:{ // 修改地图区域标签样式
            areaColor: '#219edb', // 区域颜色
            borderColor: '#fff', // 区域边框价格
        },
        emphasis: { // 地图高亮状态的多边形和标签样式
            label:{
                color: '#000',
                fontSize: 12,
            },
            itemStyle: {
                areaColor: '#f60',
                borderColor: '#329edb'
            }

        }
    }]
})

 视觉效果

 

 注意排列:与series属性同级

visualMap: {
        min: 800,
        max: 50000,
        text: ['High', 'Low'],
        realtime: false,
        calculable: true,
        inRange: {
            color: ['lightskyblue', 'yellow', 'orangered']
        },
        textStyle: {
            color:'#000'
        }
    },

 完整代码

<template>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <!--vue3中 id=‘’ 变更 ref=-->
    <div ref="chart" style="width:650px;height:650px;"></div>
</template>

<script setup >
import {onMounted, reactive, ref} from "vue";
// 局部引入echarts核心模块
import * as echarts from 'echarts'
// 还需引入地图文件
import chinaMap from '../../assets/china1.json'

const chart =ref(); // 创建DOM引用

// 第二种方法:初始化方法
const option = reactive({// 指定图表的配置项和数据
    series: [{ // 地图不需XY轴
        type: 'map', // 图表类型
        map: 'china', // 地图类型
        data: [ // 展示数据
            {name:'河南省',value:32300},
            {name: '山东省',value: 21203},
            {name: '四川省',value: 41203},
            {name: '青海省',value: 31203},

        ],
        label: { // 标签:地图中的标签、文字
            show: true, // 开启地图中的标签、文字等,(必须开启)
            color: '#fff',
            fontSize:11,
        },
        itemStyle:{ // 修改地图区域标签样式
            areaColor: '#219edb', // 区域颜色
            borderColor: '#fff', // 区域边框价格
        },
        emphasis: { // 地图高亮状态的多边形和标签样式
            label:{
                color: '#000',
                fontSize: 12,
            },
            itemStyle: {
                areaColor: '#f60',
                borderColor: '#329edb'
            }
        },
    }],
    visualMap: {
        min: 800,
        max: 50000,
        text: ['High', 'Low'],
        realtime: false,
        calculable: true,
        inRange: {
            color: ['lightskyblue', 'yellow', 'orangered']
        },
        textStyle: {
            color:'#000'
        }
    },
})

// 使用生命钩子
onMounted(() => {
    // 基于准备好的dom,初始化echarts实例
    // var myChart = echarts.init(document.getElementById('main'));
    // Vue3中: 需要引入
    var myChart = echarts.init(chart.value)

    // 注册可用的地图
    echarts.registerMap('china',chinaMap);

    // init(); // vue3.2没有this
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);

    // 单图表响应式: 跟随浏览器大小改变
    window.addEventListener('resize',()=>{
        myChart.resize()
    })


})

</script>

<style scoped>

</style>

 

 

动态数据的使用

 

1、引入axios

npm i axios -S

2、建http文件夹,创建api.js和request.js请求2个文件: http/api.js\http/request.js

开发思路: 避免私有处理造成的难维护,如:访问地址、端口变化、请求头等。老鸟考虑:如何共有化,避免多造轮子

request.js进行二次封装

 

// 引入axios
import axios, {Axios} from "axios";

// 访问地址
const service =axios.create({
    baseURL:'http://127.0.0.1:3333'
})

// 请求拦截器
service.interceptors.request.use(config=>config)

// 响应拦截器
service.interceptors.response.use(res=>{
    // 错误码的判断
    return res;
},error => {
    return Promise.reject(error)
})

// 导出接口
export default service

 

 

   Vue3.2注意写法: 100%出现问题

// 局部引入echarts核心模块
import * as echarts from 'echarts'
// 还需引入地图文件
import chinaMap from '../../assets/china1.json'
// 引入动态数据axios,二次封装
import axios from "../../http/request";

// const mapData = await fetch(`/api/post/1`).then(r => r.json())
// 根据接口文档:实际参数获取数据,异步组件await
const mapData = await axios.get('student_location').then(res => res.data.result)

const chart =ref(); // 创建DOM引用

// 第二种方法:初始化方法
const option = reactive({// 指定图表的配置项和数据
    series: [{ // 地图不需XY轴
        type: 'map', // 图表类型
        map: 'china', // 地图类型
        data: mapData, // 使用动态Api接口文档数据
        /*[ // 展示数据
            {name:'河南省',value:32300},
            {name: '山东省',value: 21203},
            {name: '四川省',value: 41203},
            {name: '青海省',value: 31203},
        ],*/

问题:由于aync异步组件,页面无法显示

// 根据接口文档:实际参数获取数据
const mapData = await axios.get('student_location').then(res => res.data.result)

父组件index/index.vue,要使用Vue3.2异步插槽方式

 

  

<div style="flex: 0 1 60%">
            <div >
                <!--异步组件-->
                <Suspense>
                    <!--跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符#。
                    例如 v-slot:header 可以被重写为 #header-->
                    <template #default>
                        <charts2></charts2>
                    </template>
                </Suspense>
            </div>
        </div>

异步插槽:开发思路更多的是为了公共复用

 

posted @ 2023-01-01 12:19  爵岚  阅读(552)  评论(0编辑  收藏  举报