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地理小工具系列

http://datav.aliyun.com/tools/


 


 

 

2、點擊下載文件


 

 

也可以用geopandas打開。

3、點開https://mapshaper.org/

選擇文件並輸出


 

 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>

異步插槽:開發思路更多的是為了公共複用