数据大屏vue3+ts+axios+MockJS+dataV+echarts

打印 上一主题 下一主题

主题 815|帖子 815|积分 2445

一、官网/文档


  • vue3:https://cn.vuejs.org/api/
  • TypeScript:https://www.tslang.cn/docs/handbook/basic-types.html
  • axios:http://www.axios-js.com/zh-cn/docs/
  • MockJS:http://mockjs.com/
  • dataV:http://datav.jiaminghi.com/guide/
  • echarts:https://echarts.apache.org/handbook/zh/basics/download
  • 百度地图文档:https://lbsyun.baidu.com/

二、报错

有些是我确实碰到的,有些是我为了验证某些特性是不是真的如他所说的那样报错所记载的
1. VueCompilerError: <template v-for> key should be placed on the <template> tag.

1.1 报错内容如图:


1.2 原因

vue3模板语法在template标签上利用v-for的同时内里假如要利用key关键字,那么为了使template有意义key关键字须在template上而非内层标签上

1.3 修正


  • 根据报错找到位置

  • 将原来在rect标签上的key关键字转移到template上

2. TypeScript 对象类型的属性访问报错 / 给对象动态添加属性报错

2.1 编辑器报错如图


2.2 原因

底子数据类型object上没有属性name。
类型推断认为obj应为any
2.3 修正

有四种方法

  • 类型推论:在TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型。

  • 利用any

  • 利用接口interface

  • 直接tsconfig.json文件中添加 "suppressImplicitAnyIndexErrors":true,来屏蔽隐式索引检查
3. Error: Property 属性名 does not exist on type 接口名

3.1 报错内容如图


3.2 原因

这个是我研究 TypeScript 中 interface 可选属性时 看到 文档说会这么报错,然后就试了一下。
意外之喜是他还会帮你指出精确的名称
不外这种环境编辑器(VScode)一开始就会给你报错

3.3 办理

改成精确的属性名就好。
4. Cannot assign to 属性名 because it is a read-only property.

4.1 报错如图



4.2 原因

这内里是两种环境,


  • 第一种是想知道只读属性会报什么错,
  • 第二种是 只读属性跟可选属性团结的环境下,不赋初始值然后再去手动赋值会不会报错,嗯,报了
4.3 办理

只读属性 一定是只给初始值 ,后面别作妖改
三、一些注意点

1. 实时显示时间

一秒一秒实时显示,思路大致就是setInterval计时器实现
显示格式是YYYY-MM-DD 周x hh:mm:ss

  • 首先是时间
  • 处理
  1. export function timeProcessor(date:string|Date):string{
  2.    const dateObj:Date=new Date(date)
  3.    const year:number=dateObj.getFullYear()
  4.    const month:number|string=unshiftZero(dateObj.getMonth()+1)
  5.    const dateStr:number|string=unshiftZero(dateObj.getDate())
  6.    const day:any=function():string{
  7.       const dayNumber=dateObj.getDay()
  8.       const dayStrList=['周日','周一','周二','周三','周四','周五','周六']
  9.       return dayStrList[dayNumber]
  10.    }()
  11.    const hour:number|string=unshiftZero(dateObj.getHours())
  12.    const minute:number|string=unshiftZero(dateObj.getMinutes())
  13.    const second:number|string=unshiftZero(dateObj.getSeconds())
  14.    return `${year}-${month}-${dateStr}  ${day}  ${hour}:${minute}:${second}`
  15. }
  16. export function unshiftZero(num:number):string|number{
  17.    return num<10?`0${num}`:num
  18. }
复制代码

  • 引入然后渲染
  1. import {timeProcessor} from "@/utils/xxx";
  2. const nowDate:string = timeProcessor(new Date())
复制代码
html部分就是简单的双花括号包裹编译
  1. <div class="time">{{ nowData }}</div>
复制代码

  • 计时器循环渲染
  1. const timer = setInterval(() => {
  2.   nowData = timeProcessor(new Date())
  3. }, 1000)
  4. onBeforeUnmount(() => {
  5.   clearInterval(timer)
  6. })
复制代码
原则上如许就可以了,但是现实上效果却是

出现这种环境的原因是缺少ref包裹,那么ref是什么呢?他是vue3提供的一个响应式操纵对象。没有ref包裹的值不具有响应性,下面的值再怎么改变上面也只会显示一开始得到的。
所以必要改为响应式被ref包裹
  1. import { ref, reactive, onBeforeUnmount } from 'vue'
  2. import type { Ref } from 'vue'
  3. let nowData:Ref<string> = ref(timeProcessor(new Date()))
  4. const timer = setInterval(() => {
  5.   nowData.value = timeProcessor(new Date())
  6. }, 1000)
  7. onBeforeUnmount(() => {
  8.   clearInterval(timer)
  9. })
复制代码

2. interface 额外属性 检查

想了好久还是放这内里
2.1 TypeScript中额外属性报错

首先 ,额外属性是什么东西?就是你给了 一个接口他没有的东西。
  1. interface studentObject {
  2.     name: string;
  3.     age?: number
  4. }
  5. //这里 即便 不传入 age 也不会报错
  6. function logStudent(studentConfig: studentObject): string {
  7.     const student = { name: 'zhangsan', city: 'shanghai' };
  8.     if (studentConfig.name) {
  9.         student.name = studentConfig.name;
  10.     }
  11.     return `当前入学学生名为${student.name}`
  12. }
  13. const wusi = logStudent({ name: 'wusi', classNumber: 5 })
复制代码
这段代码内里 wusi 变量 传值 classNumber 就是 额外属性 ,
这么传值会报错,首先是编辑器报错

然后是编译报错


在TypeScript中,对象字面量会被特殊对待而且会颠末 额外属性检查,当将它们赋值给变量或作为参数传递的时间。
假如一个对象字面量存在任何“目标类型”不包罗的属性时,你会得到一个错误。

2.2 避开额外属性检查

有三种方法
2.2.1 类型断言

{ } as 接口名
  1. interface studentObject {
  2.     name: string;
  3.     age?: number
  4. }
  5. //这里 即便 不传入 age 也不会报错
  6. function logStudent(studentConfig: studentObject): string {
  7.     const student = { name: 'zhangsan', city: 'shanghai' };
  8.     if (studentConfig.name) {
  9.         student.name = studentConfig.name;
  10.     }
  11.     return `当前入学学生名为${student.name}`
  12. }
  13. const wusi = logStudent({ name: 'wusi', classNumber: 5 } as studentObject)
复制代码
2.2.2 添加一个字符串索引签名

要确定这个对象大概具有某些做为特殊用途利用的额外属性
写法 [propName: string]: any;
  1. interface studentObject {
  2.     name: string;
  3.     age?: number;
  4.     [propName: string]: any;
  5. }
  6. //这里 即便 不传入 age 也不会报错
  7. function logStudent(studentConfig: studentObject): string {
  8.     const student = { name: 'zhangsan', city: 'shanghai' };
  9.     if (studentConfig.name) {
  10.         student.name = studentConfig.name;
  11.     }
  12.     return `当前入学学生名为${student.name}`
  13. }
  14. const wusi = logStudent({ name: 'wusi', classNumber: 5 })
复制代码
2.2.3 传值给第三方变量

就是先把值存在一个单独变量中
  1. interface studentObject {
  2.     name: string;
  3.     age?: number;
  4. }
  5. //这里 即便 不传入 age 也不会报错
  6. function logStudent(studentConfig: studentObject): string {
  7.     const student = { name: 'zhangsan', city: 'shanghai' };
  8.     if (studentConfig.name) {
  9.         student.name = studentConfig.name;
  10.     }
  11.     return `当前入学学生名为${student.name}`
  12. }
  13. const wusiObj={ name: 'wusi', classNumber: 5 }
  14. const wusi = logStudent(wusiObj)
复制代码
四、涉及技术

1、vue3部分

1.1 ref()

1.1.1 定义

   担当一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。
  1.1.2 类型

  1. function ref<T>(value: T): Ref<UnwrapRef<T>>
  2. interface Ref<T> {
  3.   value: T
  4. }
复制代码
1.1.3 详细信息



  • ref 对象是可更改的,也就是说你可以为 .value 赋予新的值。它也是响应式的,即所有对 .value 的操纵都将被追踪,而且写操纵会触发与之相干的副作用。
  • 假如将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深条理响应式的对象。这也意味着假如对象中包罗了嵌套的 ref,它们将被深层地解包。
  • 若要避免这种深条理的转换,请利用 shallowRef() 来替代。
1.1.4 为 ref() 标注类型

TypeScript写法时,必要标注变量类型,但是被ref()所包裹的值这种该是什么类型呢?
vue3本身提供TypeScript支持,只必要将Ref类型引入 然后标注即可


  • 先引入ref 及 Ref 类型
  1.    import { ref } from 'vue'
  2.    import type { Ref } from 'vue'
复制代码


  • 变量利用变量:Ref<基本类型> = ref(值)
  1. import { ref } from 'vue'
  2. import type { Ref } from 'vue'
  3. const year: Ref<string | number> = ref('2020')
  4. year.value = 2020 // 成功!
复制代码
1.1.5 示例

  1. const count = ref(0)
  2. console.log(count.value) // 0
  3. count.value = 1
  4. console.log(count.value) // 1
复制代码
1.1.6 团结本项目的一些个人看法

本项目中重点用到 ref 或者说 是我警醒 必要利用ref 是在 时间展示部分,一开始只是单纯声明变量,待效果没有出来时反应过来他没有响应式,在编辑器看来他只是一个普通变量。
这也是之前一直利用vue2所留下的个人风俗,之前vue2不必要特意去关注这部分,框架会帮你搞定,看起来是vue2比vue3写法更简但在底层实现时vue2必要逐个甄别,vue3不必要,这也是vue3比vue2轻便的一部分原因。
1.2 reactive()

1.2.1 定义

返回一个对象的响应式署理。
1.2.2 类型

  1. function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
复制代码
1.2.3 详细信息



  • 响应式转换是“深层”的:它会影响到所有嵌套的属性。
    一个响应式对象也将深层地解包任何 ref 属性,同时保持响应性。
  • 想避免深层响应式转换,只想保留对这个对象顶条理访问的响应性,请利用 shallowReactive() 作替代。
  • 返回的对象以及其中嵌套的对象都会通过 ES Proxy 包裹,因此不等于源对象,发起只利用响应式署理,避免利用原始对象。
1.2.4 标注类型

reactive() 也会隐式地从它的参数中推导类型:
  1. import { reactive } from 'vue'
  2. // 推导得到的类型:{ title: string }
  3. const book = reactive({ title: 'Vue 3 指引' })
复制代码
要显式地标注一个 reactive 变量的类型,我们可以利用接口:
  1. import { reactive } from 'vue'
  2. interface Book {
  3.   title: string
  4.   year?: number
  5. }
  6. const book: Book = reactive({ title: 'Vue 3 指引' })
复制代码
1.2.5 示例

创建一个响应式对象:
  1. const obj = reactive({ count: 0 })
  2. obj.count++
复制代码
ref 的解包:
  1. const count = ref(1)
  2. const obj = reactive({ count })
  3. // ref 会被解包
  4. console.log(obj.count === count.value) // true
  5. // 会更新 `obj.count`
  6. count.value++
  7. console.log(count.value) // 2
  8. console.log(obj.count) // 2
  9. // 也会更新 `count` ref
  10. obj.count++
  11. console.log(obj.count) // 3
  12. console.log(count.value) // 3
复制代码
注意当访问到某个响应式数组或 Map 如许的原生聚集类型中的 ref 元素时,不会执行 ref 的解包:
  1. const books = reactive([ref('Vue 3 Guide')])
  2. // 这里需要 .value
  3. console.log(books[0].value)
  4. const map = reactive(new Map([['count', ref(0)]]))
  5. // 这里需要 .value
  6. console.log(map.get('count').value)
复制代码
将一个 ref 赋值给一个 reactive 属性时,该 ref 会被自动解包:
  1. const count = ref(1)
  2. const obj = reactive({})
  3. obj.count = count
  4. console.log(obj.count) // 1
  5. console.log(obj.count === count.value) // true
复制代码
1.2.6 tips



  • 访问到某个响应式数组或 Map 如许的原生聚集类型中的 ref 元素时,不会执行 ref 的解包。
2、TypeScript部分

2.1 Any

2.1.1 定义

typescript中的一种底子类型,表示值可以是任何类型(never除外)
2.1.1.1 利用环境

以下环境可以利用 any类型来标志变量:


  • 不清晰该变量类型
  • 变量值大概来自于动态的内容,比如来自用户输入或第三方代码库。
  • 不希望类型检查器对该值进行检查,而是直接让它们通过编译阶段的检查。
2.1.1.2 示例

  1. let notSure: any = 4;
  2. notSure = "maybe a string instead";
  3. notSure = false; // okay, definitely a boolean
复制代码
对现有代码进行改写的时间,any类型非常有效,它答应你在编译时可选择地包罗或移除类型检查。
听起来这作用貌似 Object 也有,就像它在别的语言中那样。
但是 Object类型的变量只是答应你给它赋恣意值 -
但是却不可以大概在它上面调用恣意的方法,即便它真的有这些方法:
  1. let notSure: any = 4;
  2. notSure.ifItExists(); // okay, ifItExists might exist at runtime
  3. notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
  4. let prettySure: Object = 4;
  5. prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
复制代码
当只知道一部分数据的类型时,any类型也是有效的。 比如,你有一个数组,它包罗了不同的类型的数据:
  1. let list: any[] = [1, true, "free"];
  2. list[1] = 100;
复制代码
2.1.2 关于 typescript底子类型的一些东西

   typescript中底子类型分别有
  

  • 底子类型
    boolean 布尔值、 number 数字、 String 字符串、 array 数组、Null、Undefined
  • 其他不算太常见
  

  • Tuple元祖:各元素可不同数据类型的数组(多个类型时必须严酷按照类型排序赋值,越界元素用团结类型替代)
  • enum枚举:对JavaScript标准数据类型的增补。(可以为一组数值赋予友好的名字;可以由枚举的值得到它的名字
  • any:值可以是任何类型(never打咩)
  • Void:没有任何类型。此类型变量 值 仅为 undefined、null
  • Never :永不存在值的类型。它存在于任何类型子集中,但他本身没有子集类型         (1) 总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; (就是我们往控制台投掷异常的函数)
    (2) 当变量被永不为真的类型掩护所约束时,它也大概是 never类型。
    (3) never类型是任何类型的子类型,也可以赋值给任何类型;
    然而,没有类型是never的子类型或可以赋值给never类型
    (除了never本身之外)。 纵然 any也不可以赋值给never。
    (就是说所有类型都是他爹,但他本身没有儿子,他本身接纳的无丝分裂)
  

  • Object:表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。
  2.2 InterFace

TypeScript官方文档链接
2.2.1先容



  • TypeScript的焦点原则之一是对值所具有的结构进行类型检查
  • 它偶然被称做“鸭式辨型法”或“结构性子类型化”。
  • 在TypeScript里,接口的作用是为类型定名和为代码或第三方代码定义契约。
2.2.2 属性

2.2.2.1 可选属性

就是说 接口中并不是所有属性都是 必须,当有些属性只有在某些环境下必要时,那么它就黑白必须属性即可选属性。
设置可选属性只必要在属性后添加?即可
下面这个例子就明确表示出 age 是可选属性
  1. interface studentObject{
  2.   name:string;
  3.   age?:number
  4. }
  5. //这里 即便 不传入 age 也不会报错
  6. function logStudent(studentConfig:studentObject):string{
  7.   let student={name:'zhangsan',city:'shanghai'};
  8.   if(studentConfig.name){
  9.     student.name=studentConfig.name;
  10.   }
  11.   return `当前入学学生名为${student.name}`
  12. }
  13. let wusi=logStudent({name:'wusi'})
复制代码
2.2.2.2 只读属性

关键字 readonly 定义只读属性
  1. interface point{
  2.   readonly x:number;
  3.   readonly y:number
  4. }
  5. const redPoint:point={x:123.89,y:128.90}
  6. redPoint.y=900.89;
复制代码
会报错 Cannot assign to ‘y’ because it is a read-only property.
   TypeScript具有ReadonlyArray<T>类型,它与Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:
  1. let a: number[] = [1, 2, 3, 4];
  2. let ro: ReadonlyArray<number> = a;
  3. ro[0] = 12; // error!
  4. ro.push(5); // error!
  5. ro.length = 100; // error!
  6. a = ro; // error!
复制代码
效果如图

别的这组代码编辑器也会报错:




上面代码的最后一行,可以看到就算把整个ReadonlyArray赋值到一个普通数组也是不可以的。 但是你可以用类型断言重写:
  1. a = ro as number[];
复制代码
readonly VS const


  • 作为属性利用就用readonly;
  • 作为变量利用就用const
2.2.3 可索引类型

可索引类型具有一个 索引签名,它形貌了对象索引的类型,还有相应的索引返回值类型。
2.2.3.1 索引签名初始

  1. interface StringArray {
  2.   [index: number]: string;
  3. }
  4. let myArray: StringArray;
  5. myArray = ["Bob", "Fred"];
  6. let myStr: string = myArray[0];// => "Bob"
复制代码
这段代码定义了StringArray接口,它具有索引签名。
这个索引签名表示了当用 number去索引StringArray时会得到string类型的返回值。

有没有想起来什么熟悉的东西?比如 Array[index] ,String[index]
2.2.3.2 索引签名类型


  • TypeScript支持两种索引签名:字符串和数字。
  • 可以同时利用两种类型的索引,但是数字索引的返回值必须是 字符串索引返回值类型 的子类型。       这是由于利用 number来索引时,JavaScript会将它转换成string然后再去索引对象。
    也就是说用 100(一个number)去索引等同于利用"100"(一个string)去索引,因此两者必要保持一致。

  1. class Animal {
  2.     name: string;
  3. }
  4. class Dog extends Animal {
  5.     breed: string;
  6. }
  7. // 错误:使用数值型的字符串索引,
  8. //有时会得到完全不同的Animal!
  9. interface NotOkay {
  10.     [x: number]: Animal;
  11.     [x: string]: Dog;
  12. }
复制代码
编译报错

编辑器报错

字符串索引签名可以大概很好的形貌dictionary模式,而且它们也会确保所有属性与其返回值类型相匹配。
由于字符串索引声明了 obj.property和obj["property"]两种形式都可以。
下面的例子里, name的类型与字符串索引类型不匹配,所以类型检查器给出一个错误提示:
  1. interface NumberDictionary {
  2.   [index: string]: number;
  3.   length: number;    // 可以,length是number类型
  4.   name: string       // 错误,`name`的类型与索引类型返回值的类型不匹配
  5. }
复制代码

最后,你可以将索引签名设置为只读,如许就防止了给索引赋值:
  1. interface ReadonlyStringArray {
  2.     readonly [index: number]: string;
  3. }
  4. let myArray: ReadonlyStringArray = ["Alice", "Bob"];
  5. myArray[2] = "Mallory"; // error!
复制代码

你不能设置myArray[2],由于索引签名是只读的。
2.2.4 tips


  • 任何利用 module关键字来声明一个内部模块的地方都应该利用namespace关键字来替换。 避免相似的名称迷惑。
  • TypeScript会对interface做额外属性检查,就是传入不存在的属性时会报错。想避开有以下方法:

    • 利用类型断言 {} as 接口名
    • 添加一个字符串索引签名,前提是你可以大概确定这个对象大概具有某些做为特殊用途利用的额外属性
    • 传值颠末第三变量。 先用一个变量存储值,然后再定义对应接口值

3、npm

3.1 patch-package

报错一 内里我们办理方式触及到了改源码,但是项目云端时新人该如何,在拉取代码后也修改源码?可以是可以,那用户呢?
在这里我利用了patch-package
3.1.1 安装

  1. npm install patch-package
复制代码
跟其他的一样风俗用什么用什么,必要注意的是不能用cnpm
3.1.2 利用


  • 先在项目的pageage.json文件的scripts部分添加代码"postinstall": "patch-package"',如许我们修改后的源码就会在npm install的时间自动为依靠包打上
  • 修改源码
  • 执行命令 npx patch-package 修改的依靠名称比如报错一的那个那么我将执行npx patch-package @jiaminghi/data-view。
3.1.3 注意

1、第一次利用patch-package会在项目根目录生成patches文件夹,内里有修改过的文件diff记载。

2、当这个包版本更新后,执行命令:git apply --ignore-whitespace patches/@jiaminghi+data-view+2.10.0.patch即可。其中@jiaminghi+data-view+2.10.0.patch是它生成的文件名。

4、百度地图

中间的地图用的是百度地图
我这里是web端所以选的是javascriptAPI


<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=秘钥"></script>

4.1 账号及密钥

4.1.1 账号注册


  • 进入百度地图开放平台官网,点击右上角【登录】按钮,进入百度账号登录页面

  • 如您已经拥有百度账号,请通过扫码/用户名验证的方式直接登录;如您还未拥有百度账号请您点击【注册】完成账号注册

  • 通过百度账号注册 成为 百度地图开放平台开辟者,选择开辟者类型(个人/企业),完成开辟者认证即可

4.1.2 AK秘钥申请

JavaScript API只支持浏览端的AK进行接入与访问,请开辟者在申请AK时注意选择精确的AK类型。

  • 进入百度地图开放平台官网控制台,点击【应用管理】-【我的应用】

  • 点击【创建应用】进入AK申请页面,填写应用名称,务必选择AK类型为“浏览器端”,JS API只支持浏览器端AK进行哀求与访问

  • 为了防止AK被盗用,请您务必配置refer白名单,只有该白名单中的网站才气乐成发起调用。如下方示例所示,配置了*.mysite.com*为域名白名单,即代表域名中包罗.mysite.com的网站=才可以利用该AK访问JS API的服务

    本身当地设置搞着玩 直接 输入 * 也OK
4.2 利用

4.2.1 单页面

以helloworld demo举例

代码如下:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.         <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  6.         <style type="text/css">
  7.         body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
  8.         </style>
  9.         <script type="text/javascript" src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=您的密钥"></script>
  10.         <title>地图展示</title>
  11. </head>
  12. <body>
  13.         <div id="allmap"></div>
  14. </body>
  15. </html>
  16. <script type="text/javascript">
  17.     // GL版命名空间为BMapGL
  18.     // 按住鼠标右键,修改倾斜角和角度
  19.         var map = new BMapGL.Map("allmap");    // 创建Map实例
  20.         map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 11);  // 初始化地图,设置中心点坐标和地图级别
  21.         map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
  22. </script>
复制代码

重要部分:
  1. <script type="text/javascript" src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=您的密钥"></script>
  2. <script type="text/javascript">
  3.     // GL版命名空间为BMapGL
  4.     // 按住鼠标右键,修改倾斜角和角度
  5.         var map = new BMapGL.Map("allmap");    // 创建Map实例
  6.         map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 11);  // 初始化地图,设置中心点坐标和地图级别
  7.         map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
  8. </script>
复制代码
4.2.2 与echarts 团结


  • 项目安装echarts 引入 百度地图


  • 引入 echarts 与 echarts 下的 bmap
  1. import * as echarts from 'echarts';
  2. // 请确保在引入百度地图扩展之前已经引入百度地图 JS API 脚本并成功加载
  3. // https://api.map.baidu.com/api?v=3.0&ak=你申请的AK
  4. import 'echarts/extension/bmap/bmap';
复制代码

  • 写 echart 大致框架
  1. import * as echarts from 'echarts';
  2. // 请确保在引入百度地图扩展之前已经引入百度地图 JS API 脚本并成功加载
  3. // https://api.map.baidu.com/api?v=3.0&ak=你申请的AK
  4. import 'echarts/extension/bmap/bmap';
  5. import { onMounted } from 'vue';import {data,geoCoordMap,styleJson} from "./index"function chartFun(){  const chartDom = document.getElementById('center-index');  const myChart = echarts.init(chartDom, 'dark');  let option;  const convertData = function (data: string | any[]) {        const res = [];        for (let i = 0; i < data.length; i++) {            const geoCoord = geoCoordMap[data[i].name];            if (geoCoord) {                res.push({                    name: data[i].name,                    value: geoCoord.concat(data[i].value)                });            }        }        return res;   };      option = {        backgroundColor: 'transparent',        title: {            text:'天下重要都会库存-百度地图',            left: 'center',            textStyle: {                color: '#fff'            }        },        tooltip: {            trigger: 'item'        },        bmap: {},        series: [            {                name: '库存',                type: 'scatter',                coordinateSystem: 'bmap',                data: convertData(data),//数据处理                encode: {                    value: 2                },                symbolSize: function (val: number[]) {                    return val[2] / 10;                },                label: {                    formatter: '{b}',                    position: 'right',                    show:false                },                itemStyle: {                    color: '#ddb926'                },                emphasis: {                    label: {                        show: true                    }                }            },            {                name: 'Top 5',                type: 'effectScatter',                coordinateSystem: 'bmap',                data: convertData(                    data                        .sort(function (a:any, b:any) {                            return b.value - a.value;                        })                        .slice(0, 6)                ),                encode: {                    value: 2                },                symbolSize: function (val: number[]) {                    return val[2] / 10;                },                showEffectOn: 'emphasis',                rippleEffect: {                    brushType: 'stroke'                },                hoverAnimation: true,                label: {                    formatter: '{b}',                    position: 'right',                    show: true                },                itemStyle: {                    color: '#f4e925',                    shadowBlur: 10,                    shadowColor: '#333'                },                zlevel: 1            },        ]    };    option && myChart.setOption(option);}onMounted(() => {    chartFun()})
复制代码

  • 其中重要是bmap对象 是百度地图相干 的
  1. bmap: {
  2.    center: [103.114129, 50.550339],
  3.    zoom: 5,
  4.    roam: true,
  5.    mapStyle: {
  6.      styleJson
  7.    }
  8. },
复制代码
其中 styleJson 是这个引入的

那个index文件源码如下:
  1. interface DataItem {
  2.     name: string;
  3.     value: number;
  4.   }
  5. export const data:DataItem[]=[
  6.     { name: '海门', value: 9 },
  7.     { name: '鄂尔多斯', value: 12 },
  8.     { name: '招远', value: 12 },
  9.     { name: '舟山', value: 12 },
  10.     { name: '齐齐哈尔', value: 14 },
  11.     { name: '盐城', value: 15 },
  12.     { name: '赤峰', value: 16 },
  13.     { name: '青岛', value: 18 },
  14.     { name: '乳山', value: 18 },
  15.     { name: '金昌', value: 19 },
  16.     { name: '泉州', value: 21 },
  17.     { name: '莱西', value: 21 },
  18.     { name: '日照', value: 21 },
  19.     { name: '胶南', value: 22 },
  20.     { name: '南通', value: 23 },
  21.     { name: '拉萨', value: 24 },
  22.     { name: '云浮', value: 24 },
  23.     { name: '梅州', value: 25 },
  24.     { name: '文登', value: 25 },
  25.     { name: '上海', value: 25 },
  26.     { name: '攀枝花', value: 25 },
  27.     { name: '威海', value: 25 },
  28.     { name: '承德', value: 25 },
  29.     { name: '厦门', value: 26 },
  30.     { name: '汕尾', value: 26 },
  31.     { name: '潮州', value: 26 },
  32.     { name: '丹东', value: 27 },
  33.     { name: '太仓', value: 27 },
  34.     { name: '曲靖', value: 27 },
  35.     { name: '烟台', value: 28 },
  36.     { name: '福州', value: 29 },
  37.     { name: '瓦房店', value: 30 },
  38.     { name: '即墨', value: 30 },
  39.     { name: '抚顺', value: 31 },
  40.     { name: '玉溪', value: 31 },
  41.     { name: '张家口', value: 31 },
  42.     { name: '阳泉', value: 31 },
  43.     { name: '莱州', value: 32 },
  44.     { name: '湖州', value: 32 },
  45.     { name: '汕头', value: 32 },
  46.     { name: '昆山', value: 33 },
  47.     { name: '宁波', value: 33 },
  48.     { name: '湛江', value: 33 },
  49.     { name: '揭阳', value: 34 },
  50.     { name: '荣成', value: 34 },
  51.     { name: '连云港', value: 35 },
  52.     { name: '葫芦岛', value: 35 },
  53.     { name: '常熟', value: 36 },
  54.     { name: '东莞', value: 36 },
  55.     { name: '河源', value: 36 },
  56.     { name: '淮安', value: 36 },
  57.     { name: '泰州', value: 36 },
  58.     { name: '南宁', value: 37 },
  59.     { name: '营口', value: 37 },
  60.     { name: '惠州', value: 37 },
  61.     { name: '江阴', value: 37 },
  62.     { name: '蓬莱', value: 37 },
  63.     { name: '韶关', value: 38 },
  64.     { name: '嘉峪关', value: 38 },
  65.     { name: '广州', value: 38 },
  66.     { name: '延安', value: 38 },
  67.     { name: '太原', value: 200 },
  68.     { name: '清远', value: 39 },
  69.     { name: '中山', value: 39 },
  70.     { name: '昆明', value: 39 },
  71.     { name: '寿光', value: 40 },
  72.     { name: '盘锦', value: 40 },
  73.     { name: '长治', value: 41 },
  74.     { name: '深圳', value: 41 },
  75.     { name: '珠海', value: 42 },
  76.     { name: '宿迁', value: 43 },
  77.     { name: '咸阳', value: 43 },
  78.     { name: '铜川', value: 44 },
  79.     { name: '平度', value: 44 },
  80.     { name: '佛山', value: 44 },
  81.     { name: '海口', value: 44 },
  82.     { name: '江门', value: 45 },
  83.     { name: '章丘', value: 45 },
  84.     { name: '肇庆', value: 46 },
  85.     { name: '大连', value: 47 },
  86.     { name: '临汾', value: 47 },
  87.     { name: '吴江', value: 47 },
  88.     { name: '石嘴山', value: 49 },
  89.     { name: '沈阳', value: 50 },
  90.     { name: '苏州', value: 50 },
  91.     { name: '茂名', value: 50 },
  92.     { name: '嘉兴', value: 51 },
  93.     { name: '长春', value: 51 },
  94.     { name: '胶州', value: 52 },
  95.     { name: '银川', value: 52 },
  96.     { name: '张家港', value: 52 },
  97.     { name: '三门峡', value: 53 },
  98.     { name: '锦州', value: 54 },
  99.     { name: '南昌', value: 54 },
  100.     { name: '柳州', value: 54 },
  101.     { name: '三亚', value: 54 },
  102.     { name: '自贡', value: 56 },
  103.     { name: '吉林', value: 56 },
  104.     { name: '阳江', value: 57 },
  105.     { name: '泸州', value: 57 },
  106.     { name: '西宁', value: 57 },
  107.     { name: '宜宾', value: 58 },
  108.     { name: '呼和浩特', value: 58 },
  109.     { name: '成都', value: 58 },
  110.     { name: '大同', value: 58 },
  111.     { name: '镇江', value: 59 },
  112.     { name: '桂林', value: 59 },
  113.     { name: '张家界', value: 59 },
  114.     { name: '宜兴', value: 59 },
  115.     { name: '北海', value: 60 },
  116.     { name: '西安', value: 61 },
  117.     { name: '金坛', value: 62 },
  118.     { name: '东营', value: 62 },
  119.     { name: '牡丹江', value: 63 },
  120.     { name: '遵义', value: 63 },
  121.     { name: '绍兴', value: 63 },
  122.     { name: '扬州', value: 64 },
  123.     { name: '常州', value: 64 },
  124.     { name: '潍坊', value: 65 },
  125.     { name: '重庆', value: 66 },
  126.     { name: '台州', value: 67 },
  127.     { name: '南京', value: 67 },
  128.     { name: '滨州', value: 70 },
  129.     { name: '贵阳', value: 71 },
  130.     { name: '无锡', value: 71 },
  131.     { name: '本溪', value: 71 },
  132.     { name: '克拉玛依', value: 72 },
  133.     { name: '渭南', value: 72 },
  134.     { name: '马鞍山', value: 72 },
  135.     { name: '宝鸡', value: 72 },
  136.     { name: '焦作', value: 75 },
  137.     { name: '句容', value: 75 },
  138.     { name: '北京', value: 79 },
  139.     { name: '徐州', value: 79 },
  140.     { name: '衡水', value: 80 },
  141.     { name: '包头', value: 80 },
  142.     { name: '绵阳', value: 80 },
  143.     { name: '乌鲁木齐', value: 84 },
  144.     { name: '枣庄', value: 84 },
  145.     { name: '杭州', value: 84 },
  146.     { name: '淄博', value: 85 },
  147.     { name: '鞍山', value: 86 },
  148.     { name: '溧阳', value: 86 },
  149.     { name: '库尔勒', value: 86 },
  150.     { name: '安阳', value: 90 },
  151.     { name: '开封', value: 90 },
  152.     { name: '济南', value: 92 },
  153.     { name: '德阳', value: 93 },
  154.     { name: '温州', value: 95 },
  155.     { name: '九江', value: 96 },
  156.     { name: '邯郸', value: 98 },
  157.     { name: '临安', value: 99 },
  158.     { name: '兰州', value: 99 },
  159.     { name: '沧州', value: 100 },
  160.     { name: '临沂', value: 103 },
  161.     { name: '南充', value: 104 },
  162.     { name: '天津', value: 105 },
  163.     { name: '富阳', value: 106 },
  164.     { name: '泰安', value: 112 },
  165.     { name: '诸暨', value: 112 },
  166.     { name: '郑州', value: 113 },
  167.     { name: '哈尔滨', value: 114 },
  168.     { name: '聊城', value: 116 },
  169.     { name: '芜湖', value: 117 },
  170.     { name: '唐山', value: 119 },
  171.     { name: '平顶山', value: 119 },
  172.     { name: '邢台', value: 119 },
  173.     { name: '德州', value: 120 },
  174.     { name: '济宁', value: 120 },
  175.     { name: '荆州', value: 127 },
  176.     { name: '宜昌', value: 130 },
  177.     { name: '义乌', value: 132 },
  178.     { name: '丽水', value: 133 },
  179.     { name: '洛阳', value: 134 },
  180.     { name: '秦皇岛', value: 136 },
  181.     { name: '株洲', value: 143 },
  182.     { name: '石家庄', value: 147 },
  183.     { name: '莱芜', value: 148 },
  184.     { name: '常德', value: 152 },
  185.     { name: '保定', value: 153 },
  186.     { name: '湘潭', value: 154 },
  187.     { name: '金华', value: 157 },
  188.     { name: '岳阳', value: 169 },
  189.     { name: '长沙', value: 175 },
  190.     { name: '衢州', value: 177 },
  191.     { name: '廊坊', value: 193 },
  192.     { name: '菏泽', value: 194 },
  193.     { name: '合肥', value: 229 },
  194.     { name: '武汉', value: 273 },
  195.     { name: '大庆', value: 279 }
  196. ];
  197. export const geoCoordMap:Record<string, number[]>= {
  198.     海门: [121.15, 31.89],
  199.     鄂尔多斯: [109.781327, 39.608266],
  200.     招远: [120.38, 37.35],
  201.     舟山: [122.207216, 29.985295],
  202.     齐齐哈尔: [123.97, 47.33],
  203.     盐城: [120.13, 33.38],
  204.     赤峰: [118.87, 42.28],
  205.     青岛: [120.33, 36.07],
  206.     乳山: [121.52, 36.89],
  207.     金昌: [102.188043, 38.520089],
  208.     泉州: [118.58, 24.93],
  209.     莱西: [120.53, 36.86],
  210.     日照: [119.46, 35.42],
  211.     胶南: [119.97, 35.88],
  212.     南通: [121.05, 32.08],
  213.     拉萨: [91.11, 29.97],
  214.     云浮: [112.02, 22.93],
  215.     梅州: [116.1, 24.55],
  216.     文登: [122.05, 37.2],
  217.     上海: [121.48, 31.22],
  218.     攀枝花: [101.718637, 26.582347],
  219.     威海: [122.1, 37.5],
  220.     承德: [117.93, 40.97],
  221.     厦门: [118.1, 24.46],
  222.     汕尾: [115.375279, 22.786211],
  223.     潮州: [116.63, 23.68],
  224.     丹东: [124.37, 40.13],
  225.     太仓: [121.1, 31.45],
  226.     曲靖: [103.79, 25.51],
  227.     烟台: [121.39, 37.52],
  228.     福州: [119.3, 26.08],
  229.     瓦房店: [121.979603, 39.627114],
  230.     即墨: [120.45, 36.38],
  231.     抚顺: [123.97, 41.97],
  232.     玉溪: [102.52, 24.35],
  233.     张家口: [114.87, 40.82],
  234.     阳泉: [113.57, 37.85],
  235.     莱州: [119.942327, 37.177017],
  236.     湖州: [120.1, 30.86],
  237.     汕头: [116.69, 23.39],
  238.     昆山: [120.95, 31.39],
  239.     宁波: [121.56, 29.86],
  240.     湛江: [110.359377, 21.270708],
  241.     揭阳: [116.35, 23.55],
  242.     荣成: [122.41, 37.16],
  243.     连云港: [119.16, 34.59],
  244.     葫芦岛: [120.836932, 40.711052],
  245.     常熟: [120.74, 31.64],
  246.     东莞: [113.75, 23.04],
  247.     河源: [114.68, 23.73],
  248.     淮安: [119.15, 33.5],
  249.     泰州: [119.9, 32.49],
  250.     南宁: [108.33, 22.84],
  251.     营口: [122.18, 40.65],
  252.     惠州: [114.4, 23.09],
  253.     江阴: [120.26, 31.91],
  254.     蓬莱: [120.75, 37.8],
  255.     韶关: [113.62, 24.84],
  256.     嘉峪关: [98.289152, 39.77313],
  257.     广州: [113.23, 23.16],
  258.     延安: [109.47, 36.6],
  259.     太原: [112.53, 37.87],
  260.     清远: [113.01, 23.7],
  261.     中山: [113.38, 22.52],
  262.     昆明: [102.73, 25.04],
  263.     寿光: [118.73, 36.86],
  264.     盘锦: [122.070714, 41.119997],
  265.     长治: [113.08, 36.18],
  266.     深圳: [114.07, 22.62],
  267.     珠海: [113.52, 22.3],
  268.     宿迁: [118.3, 33.96],
  269.     咸阳: [108.72, 34.36],
  270.     铜川: [109.11, 35.09],
  271.     平度: [119.97, 36.77],
  272.     佛山: [113.11, 23.05],
  273.     海口: [110.35, 20.02],
  274.     江门: [113.06, 22.61],
  275.     章丘: [117.53, 36.72],
  276.     肇庆: [112.44, 23.05],
  277.     大连: [121.62, 38.92],
  278.     临汾: [111.5, 36.08],
  279.     吴江: [120.63, 31.16],
  280.     石嘴山: [106.39, 39.04],
  281.     沈阳: [123.38, 41.8],
  282.     苏州: [120.62, 31.32],
  283.     茂名: [110.88, 21.68],
  284.     嘉兴: [120.76, 30.77],
  285.     长春: [125.35, 43.88],
  286.     胶州: [120.03336, 36.264622],
  287.     银川: [106.27, 38.47],
  288.     张家港: [120.555821, 31.875428],
  289.     三门峡: [111.19, 34.76],
  290.     锦州: [121.15, 41.13],
  291.     南昌: [115.89, 28.68],
  292.     柳州: [109.4, 24.33],
  293.     三亚: [109.511909, 18.252847],
  294.     自贡: [104.778442, 29.33903],
  295.     吉林: [126.57, 43.87],
  296.     阳江: [111.95, 21.85],
  297.     泸州: [105.39, 28.91],
  298.     西宁: [101.74, 36.56],
  299.     宜宾: [104.56, 29.77],
  300.     呼和浩特: [111.65, 40.82],
  301.     成都: [104.06, 30.67],
  302.     大同: [113.3, 40.12],
  303.     镇江: [119.44, 32.2],
  304.     桂林: [110.28, 25.29],
  305.     张家界: [110.479191, 29.117096],
  306.     宜兴: [119.82, 31.36],
  307.     北海: [109.12, 21.49],
  308.     西安: [108.95, 34.27],
  309.     金坛: [119.56, 31.74],
  310.     东营: [118.49, 37.46],
  311.     牡丹江: [129.58, 44.6],
  312.     遵义: [106.9, 27.7],
  313.     绍兴: [120.58, 30.01],
  314.     扬州: [119.42, 32.39],
  315.     常州: [119.95, 31.79],
  316.     潍坊: [119.1, 36.62],
  317.     重庆: [106.54, 29.59],
  318.     台州: [121.420757, 28.656386],
  319.     南京: [118.78, 32.04],
  320.     滨州: [118.03, 37.36],
  321.     贵阳: [106.71, 26.57],
  322.     无锡: [120.29, 31.59],
  323.     本溪: [123.73, 41.3],
  324.     克拉玛依: [84.77, 45.59],
  325.     渭南: [109.5, 34.52],
  326.     马鞍山: [118.48, 31.56],
  327.     宝鸡: [107.15, 34.38],
  328.     焦作: [113.21, 35.24],
  329.     句容: [119.16, 31.95],
  330.     北京: [116.46, 39.92],
  331.     徐州: [117.2, 34.26],
  332.     衡水: [115.72, 37.72],
  333.     包头: [110, 40.58],
  334.     绵阳: [104.73, 31.48],
  335.     乌鲁木齐: [87.68, 43.77],
  336.     枣庄: [117.57, 34.86],
  337.     杭州: [120.19, 30.26],
  338.     淄博: [118.05, 36.78],
  339.     鞍山: [122.85, 41.12],
  340.     溧阳: [119.48, 31.43],
  341.     库尔勒: [86.06, 41.68],
  342.     安阳: [114.35, 36.1],
  343.     开封: [114.35, 34.79],
  344.     济南: [117, 36.65],
  345.     德阳: [104.37, 31.13],
  346.     温州: [120.65, 28.01],
  347.     九江: [115.97, 29.71],
  348.     邯郸: [114.47, 36.6],
  349.     临安: [119.72, 30.23],
  350.     兰州: [103.73, 36.03],
  351.     沧州: [116.83, 38.33],
  352.     临沂: [118.35, 35.05],
  353.     南充: [106.110698, 30.837793],
  354.     天津: [117.2, 39.13],
  355.     富阳: [119.95, 30.07],
  356.     泰安: [117.13, 36.18],
  357.     诸暨: [120.23, 29.71],
  358.     郑州: [113.65, 34.76],
  359.     哈尔滨: [126.63, 45.75],
  360.     聊城: [115.97, 36.45],
  361.     芜湖: [118.38, 31.33],
  362.     唐山: [118.02, 39.63],
  363.     平顶山: [113.29, 33.75],
  364.     邢台: [114.48, 37.05],
  365.     德州: [116.29, 37.45],
  366.     济宁: [116.59, 35.38],
  367.     荆州: [112.239741, 30.335165],
  368.     宜昌: [111.3, 30.7],
  369.     义乌: [120.06, 29.32],
  370.     丽水: [119.92, 28.45],
  371.     洛阳: [112.44, 34.7],
  372.     秦皇岛: [119.57, 39.95],
  373.     株洲: [113.16, 27.83],
  374.     石家庄: [114.48, 38.03],
  375.     莱芜: [117.67, 36.19],
  376.     常德: [111.69, 29.05],
  377.     保定: [115.48, 38.85],
  378.     湘潭: [112.91, 27.87],
  379.     金华: [119.64, 29.12],
  380.     岳阳: [113.09, 29.37],
  381.     长沙: [113, 28.21],
  382.     衢州: [118.88, 28.97],
  383.     廊坊: [116.7, 39.53],
  384.     菏泽: [115.480656, 35.23375],
  385.     合肥: [117.27, 31.86],
  386.     武汉: [114.31, 30.52],
  387.     大庆: [125.03, 46.58]
  388. };
  389. export const styleJson:object[]=[
  390.     {
  391.         featureType: 'water',
  392.         elementType: 'all',
  393.         stylers: {
  394.             color: '#044161'
  395.         }
  396.     },
  397.     {
  398.         featureType: 'land',
  399.         elementType: 'all',
  400.         stylers: {
  401.             color: '#0ff'
  402.         }
  403.     },
  404.     {
  405.         featureType: 'boundary',
  406.         elementType: 'geometry',
  407.         stylers: {
  408.             color: '#0ff'
  409.         }
  410.     },
  411.     {
  412.         featureType: 'railway',
  413.         elementType: 'all',
  414.         stylers: {
  415.             visibility: 'off'
  416.         }
  417.     },
  418.     {
  419.         featureType: 'highway',
  420.         elementType: 'geometry',
  421.         stylers: {
  422.             color: '#004981'
  423.         }
  424.     },
  425.     {
  426.         featureType: 'highway',
  427.         elementType: 'geometry.fill',
  428.         stylers: {
  429.             color: '#005b96',
  430.             lightness: 1
  431.         }
  432.     },
  433.     {
  434.         featureType: 'highway',
  435.         elementType: 'labels',
  436.         stylers: {
  437.             visibility: 'off'
  438.         }
  439.     },
  440.     {
  441.         featureType: 'arterial',
  442.         elementType: 'geometry',
  443.         stylers: {
  444.             color: '#004981'
  445.         }
  446.     },
  447.     {
  448.         featureType: 'arterial',
  449.         elementType: 'geometry.fill',
  450.         stylers: {
  451.             color: '#00508b'
  452.         }
  453.     },
  454.     {
  455.         featureType: 'poi',
  456.         elementType: 'all',
  457.         stylers: {
  458.             visibility: 'off'
  459.         }
  460.     },
  461.     {
  462.         featureType: 'green',
  463.         elementType: 'all',
  464.         stylers: {
  465.             color: '#056197',
  466.             visibility: 'off'
  467.         }
  468.     },
  469.     {
  470.         featureType: 'subway',
  471.         elementType: 'all',
  472.         stylers: {
  473.             visibility: 'off'
  474.         }
  475.     },
  476.     {
  477.         featureType: 'manmade',
  478.         elementType: 'all',
  479.         stylers: {
  480.             visibility: 'off'
  481.         }
  482.     },
  483.     {
  484.         featureType: 'local',
  485.         elementType: 'all',
  486.         stylers: {
  487.             visibility: 'off'
  488.         }
  489.     },
  490.     {
  491.         featureType: 'arterial',
  492.         elementType: 'labels',
  493.         stylers: {
  494.             visibility: 'off'
  495.         }
  496.     },
  497.     {
  498.         featureType: 'boundary',
  499.         elementType: 'geometry.fill',
  500.         stylers: {
  501.             color: '#029fd4'
  502.         }
  503.     },
  504.     {
  505.         featureType: 'building',
  506.         elementType: 'all',
  507.         stylers: {
  508.             color: '#1a5787'
  509.         }
  510.     },
  511.     {
  512.         featureType: 'label',
  513.         elementType: 'all',
  514.         stylers: {
  515.             visibility: 'off'
  516.         }
  517.     }
  518. ]
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大号在练葵花宝典

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表