vue2 + echarts + 地图项目学习笔记
vue2 + echarts + 地图项目学习笔记
一、echarts引入
echarts的安装
控制台输入
cnpm install echarts@4.9.0
因为版本问题,可以使用4.9.0的版本
保证里面的"dependencies"引入了echarts
packge.json
"dependencies": { "core-js": "^3.6.5", "echarts": "^5.2.1", "element-ui": "^2.15.6", "vue": "^2.6.11", "vue-router": "^3.2.0" }, 复制代码
到main.js中引入
import Echarts from 'echarts' Vue.prototype.$echarts = Echarts 复制代码
二、components组件使用
components
文件下新建TopView
,SalesView
,BottomView
,MapView
举个例子,在里面的文件新建index.vue
components/BottomView/index.vue
<template> <div>bottom view</div> </template> <script> export default { } </script> <style> </style> 复制代码
引入BottomView
views/Home.vue
<template> <div> <bottom-view /> </div> </template> <script> // @ is an alias to /src import BottomView from '../components/BottomView' export default { name: 'Home', components: { BottomView } } 复制代码
三、element组件使用
如果在components/TopView/index.vue中使用鼠标悬浮效果
<!-- TopView --> <template> <div> <el-card shadow="hover"> 鼠标悬浮时显示 </el-card> </div> </template> 复制代码
在plugins文件中按需引入
plugins/element.js
import Vue from 'vue' import { Card } from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(Card) 复制代码
四、复习父向子传参props
父组件:
<template> <common-card title="累计销售额"//传入的关键字 value="¥ 32,039,165" /> </template> <script> import CommonCard from '../components/CommonCard' // 引入子组件 export default { components: { CommonCard // 注册子组件 } } </script> <style> </style> 复制代码
子组件:
<!-- CommonCard --> <template> <div> <div>{{title}}</div> <div>{{value}}</div> </div> </template> <script> export default { // 设置title传入的值为字符型 props: { title: String, value: String } } </script> <style scoped> </style> 复制代码
五、父组件传入标签可以用slot
父组件:
<template> <common-card> // 需要template 加上v-slot:name <template v-slot:footer> <span>昨日销售量</span> <span>¥30,000,000</span> </template> </common-card> </template> 复制代码
子组件:
<!-- CommonCard --> <template> <div> // 写入slot标签,加上名字 <slot name="footer"></slot> </div> </template> 复制代码
六、vue-echarts组件入了门
为什么需要vue-echarts组件呢?
答:为了更好的优化复杂的自定义组件
七、v-echart组件
使用一些简单的场景中使用,更快更简单
适用:快速生成样式,不需要做过多修改
难点:修改时需要了解很多默认属性
下载:npm i v-charts echarts -S
申明v-charts
// main.js import './plugins/vcharts' 复制代码
按需导入
// src\plugins\vcharts.js // vchart.js import Vue from 'vue' // 引入折线图 import VEline from 'v-charts/lib/line.common' // 注册折线图,这样注册是因为VEline是一个组件 Vue.component('ve-line', VEline) 复制代码
salesView页面使用
<!-- salesView --> <template> <!-- 使用线形图组件 --> <ve-line :data="data" /> </template> <script> export default { //这条语句必须写,不然会报错 /* eslint-disable */ data () { return { data: { columns: ['日期', '销售额'], rows: [ { '日期': '1月1日', '销售额': 123 }, { '日期': '1月2日', '销售额': 1223 }, { '日期': '1月3日', '销售额': 2123 }, { '日期': '1月4日', '销售额': 4123 }, { '日期': '1月5日', '销售额': 3123 }, { '日期': '1月6日', '销售额': 7123 } ] } } } } </script> <style scoped> .echarts { width: 100%; height: 100%; } </style> 复制代码
八、设置element样式
el-menu水平垂直
<el-menu mode="horizontal"></el-menu> 复制代码
设置选中状态
(1)方法一 <el-menu mode="horizontal" :default-active="'1'" > // :default-active="'1'"设置选中的是‘1’ <el-menu-item index="1">销售额</el-menu-item> // index="1"为选需要选中的队列,但是个传递出去是个字符串1 // 需要上面默认选中也设置成一个格式 <el-menu-item index="2">访问量</el-menu-item> </el-menu> 复制代码
(2)方法二 // 在方法里面设置 <script> export default { data () { return { activeIndex: '1' } } } </script> //然后去调用 <el-menu mode="horizontal" :default-active="activeIndex" > <el-menu-item index="1">销售额</el-menu-item> <el-menu-item index="2">访问量</el-menu-item> </el-menu> 复制代码
设置监听salect
<el-menu mode="horizontal" :default-active="activeIndex" @select="onMenuSalect"> <el-menu-item index="1">销售额</el-menu-item> <el-menu-item index="2">访问量</el-menu-item> </el-menu> // 监听事件为onMenu <script> export default { data () { return { activeIndex: '1' } }, methods: { // 监听menu的点击事件 onMenuSalect (index) { this.activeIndex = index console.log(this.activeIndex) } } } </script> 复制代码
日期表组件:<el-date-picker />
设置可以选择一段时间的效果
<el-date-picker type="daterange" /> 复制代码
设置中间的文字现在是条杠
-
<el-date-picker type="daterange" v-model="date" range-separator="至" start-placeholde="开始日期" end-placeholde="结束日期" /> 复制代码
:class="+item.no <= 3 ? 'top-no' : '' "
意思:是class的item.no
为数字;小于3加上top-no
,默认为空
+item.no
转化为数字
九、引入百度地图
路由文件里面引入
// src\router\index.js import BMap from '../views/BMap.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/bmap', name: 'BMap', component: BMap } ] 复制代码
引用百度地图API文件
// public\index.html <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=您的密钥"></script> 复制代码
解决报错(也可以不处理,一样可以展示地图)
A parser-blocking, cross site (i.e. different eTLD+1) script, https://api.map.baidu.com/getscript?v=2.0&ak=VzzaOTQaSGHBfLipyg2KRIQxN29SxvRU&services=&t=20210918100012, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message. See https://www.chromestatus.com/feature/5718547946799104 for more details. 复制代码
只要把引入的 api
改成 getscript
// public\index.html <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=2.0&ak=您的密钥"></script> 复制代码
写入到页面
<!-- src\views\BMap.vue --> <!-- 地图页面 --> <template> <v-chart :option="options" /> </template> <script> // 引入百度地图 import 'echarts/extension/bmap/bmap' export default { data () { return { options: {} } }, mounted () { this.options = { bmap: { key: 'VzzaOTQaSGHBfLipyg2KRIQxN29SxvRU', // 前为经度,后面为纬度 center: [104.114129, 37.550339], zoom: 5, // 不允许地图进行缩放 roam: false // mapStyle: {} } } } } </script> <style> </style> 复制代码
十、给百度地图设置样式
需要在mounted加一个注释,表示不更改单引号显示
// src\views\BMap.vue export default { mounted () { /* eslint-disable */ } } 复制代码
在
styleJson
中页写样式
// src\views\BMap.vue mounted () { /* eslint-disable */ this.options = { bmap: { key: 'VzzaOTQaSGHBfLipyg2KRIQxN29SxvRU', // 前为经度,后面为纬度 center: [104.114129, 37.550339], zoom: 5, // 不允许地图进行缩放 roam: false, mapStyle: { // 设置地图样式 styleJson: [{ 'featureType': 'water', 'elementType': 'all', 'stylers': { 'color': '#d1d1d1' } }, { 'featureType': 'land', 'elementType': 'all', 'stylers': { 'color': '#f3f3f3' } }, { 'featureType': 'railway', 'elementType': 'all', 'stylers': { 'color': 'off' } }, { 'featureType': 'highway', 'elementType': 'all', 'stylers': { 'color': '#fdfdfd' } }, { 'featureType': 'highway', 'elementType': 'labels', 'stylers': { 'color': 'off' } }, { 'featureType': 'arterial', 'elementType': 'geometry.fill', 'stylers': { 'color': '#fefefe' } }, { 'featureType': 'poi', 'elementType': 'all', 'stylers': { 'color': 'off' } }, { 'featureType': 'green', 'elementType': 'all', 'stylers': { 'color': 'off' } }, { 'featureType': 'subwayy', 'elementType': 'all', 'stylers': { 'color': 'off' } }, { 'featureType': 'manmade', 'elementType': 'all', 'stylers': { 'color': '#d1d1d1' } }, { 'featureType': 'local', 'elementType': 'all', 'stylers': { 'color': '#d1d1d1' } }, { 'featureType': 'arterial', 'elementType': 'labels', 'stylers': { 'color': 'off' } }, { 'featureType': 'boundary', 'elementType': 'all', 'stylers': { 'color': '#fefefe' } }, { 'featureType': 'building', 'elementType': 'all', 'stylers': { 'color': '#d1d1d1' } }, { 'featureType': 'babel', 'elementType': 'babels.text.fill', 'stylers': { 'color': '#999' } }, { "featureType": "city", "elementType": "labels.text.fill", "stylers": { "color": "#454d50" } }] } } } 复制代码
十一、用echart绘制地图上的点
在series中定制样式
mounted () { /* eslint-disable */ this.options = { // hover点提示信息 tooltip: {}, // 定制小圆点 series: [{ name: '销售额', // 类型为散点图 type: 'scatter', // 协调系统来自百度地图api coordinateSystem: 'bmap', // 数据来源 data: testPoin, // 表示hover提示信息为第三项里面的值 encode: { value:2 }, // 修改每个点的颜色 itemStyle: { color: 'purple', }, // 设置点的大小 symbolSize: function (val) { // value的第三个值为大小,然后缩小十倍 return val[2] / 10 }, // 在小圆点中间显示数值 label: { show: false, // 设置显示左边 position: 'right', formatter: function (v) { // 设置左边显示城市 - 数值 return `${v.data.name} - ${v.data.value[2]}` } }, emphasis: { // 设置为hover点的时候才显示label label: { show: true } } }] } } 复制代码
需要用到数据源
<script> // 引入百度地图 import 'echarts/extension/bmap/bmap' // 这里是要用在展示小圆点的信息,value第一、二为是地址,第三位是销售额的值 const testPoin = [{ name: '海门', value: [121.15, 31.89, 80] }, { name: '南京', value: [118.78, 32.04, 100] }] <script /> 复制代码
添加前几名为水波纹圆点
只要建立第二个data,我这里名字为testPoint2 然后在series里面建立第二列,type类型改为“effectScatter” series: [ { // 普通类型的小圆点样式就是上面的样子,我不写了 }, { // 强调显示,显示小圆点水波纹效果 name: 'Top 2', type: 'effectScatter', coordinateSystem: 'bmap', data: testPoint2, // 其他样式和上面的一样,下面给一些小圆点的水波纹设置为水波线样 // 鼠标移动上去的动画样式 hoverAnimation: true, rippleEffect: { // 小圆点上的波纹变成空心的线 brushType: 'stroke' }, itemStyle: { // 设置小圆点为紫色 color: 'purple', // 设置小圆点有阴影,大小 shadowBlur: 10, // 阴影的颜色 shadowColor: '#333' } } } 复制代码
十二、用v-echart绘制地图
建立页面
src\router\index.js import BMap2 from '../views/BMap2.vue' const routes = [ { path: '/', name: 'Home', component: Home }, // 写入bmap2 { path: '/bmap2', name: 'BMap2', component: BMap2 } ] 复制代码
按需引入
// src\plugins\vcharts.js import Vue from 'vue' import VCharts from 'v-charts' import 'v-charts/lib/style.css' Vue.use(VCharts) 复制代码
使用v-chart地图
// src\views\BMap2.vue <!-- v-chart实现百度地图 --> <template> <ve-map :data="chartData"></ve-map> </template> <script> export default { data () { return { chartData: { // 点元素 columns: ['位置', '税收'], // 若干个对象 rows: [ { // eslint-disable-next-line quote-props '位置': '上海', // eslint-disable-next-line quote-props '税收': 123 }, { // eslint-disable-next-line quote-props '位置': '北京', // eslint-disable-next-line quote-props '税收': 456 } ] } } } } </script> <style> </style> 复制代码
解决图片不显示:option替换为:options
下面是替换的页面
解决没有v-charts/lib/style.css文件
【报错,我执行替换了,之后在改】BMapScatter里面放的是bmap.vue,不是bmap2.vue
十三、echart中实现水球图
运行了npm install echarts-liquidfill
水球图文档的地址:github.com/ecomfe/echa…
在路由中注册这个页面
// src\router\index.js import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' import Liquidfill from '../views/Liquidfill.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/liquidfill', name: 'Liquidfill', component: Liquidfill } ] const router = new VueRouter({ routes }) export default router 复制代码
使用echart中的liquidfill水球图
// src\views\Liquidfill.vue <!-- liquidFill --> <template> <div id="container" /> </template> <script> // 引入 import 'echarts-liquidfill' export default { mounted () { // 展示多个数据要按从大到小的顺序 const data = [0.68, 0.5, 0.4, 0.3] const chart = this.$echarts.init(document.getElementById('container')) chart.setOption({ series: [{ type: 'liquidFill', data, color: ['red', 'blue', 'yellow'], // 设置透明度 itemStyle: { opacity: 0.6 }, emphasis: { opacity: 0.9 } }] }) } } </script> <style lang="scss" scoped> #container { width: 100%; height: 100%; } </style> 复制代码
十四、v-echart中使用水球图
新建一个
LiquidFill
文件
// src\components\LiquidFill\index.vue <!-- 水球图 --> <template> <ve-liquidfil :data="chartData" height="100%" /> </template> <script> export default { data () { return { chartData: { // 传入precent columns: ['title', 'precent'], // 定制precent rows: [{ title: rate, precent: 0.68 }] } } } } </script> <style> </style> 复制代码
去bmap文件中引入,并展示
// src\components\MapView\index.vue <template> <div class="chart-wrapper"> <liquid-fill></liquid-fill> </div> </template> // 注册 <script> import BMapScatter from '../BMapScatter' import LiquidFill from '../LiquidFill' export default { components: { BMapScatter, LiquidFill } } </script> 复制代码
报错了,水球图canvas没有,所以图不显示
npm i v-charts echarts@4.9.0 -S
解决
设置水球图样式
// src\components\LiquidFill\index.vue // 利用settings绑定chartSettings事件 <template> <ve-liquidfill :data="chartData" height="100%" :settings="chartSettings" /> </template> <script> function getColor (value) { // 设置value值大于0并小于0.5为绿色;大于0.5为黄色,大于0.8为红色,默认为灰色 return value > 0 && value <= 0.5 ? 'rgba(97,216,0,.7)' : value > 0.5 && value <= 0.8 ? 'rgba(204,178,26,.7)' : value > 0.8 ? 'rgba(241,47,28,.7)' : '#c7c7cb ' } export default { data () { return { chartData: { // 传入precent columns: ['title', 'precent'], // 定制precent rows: [{ title: 'rate', precent: 0.36 }] }, chartSettings: {} } }, mounted () { this.chartSettings = { seriesMap: { rate: { radius: '80%', label: { formatter: (v) => { // 使用math.floor去data.value值取整 return `${Math.floor(v.data.value * 100)}%` }, // 对数字的样式进行修改 textStyle: { fontSize: 36, color: '#999', fontWeight: 'normal' }, // 改变文字的位置,为x轴,y轴 position: ['50%', '50%'], // 水波和文字重叠的位置的颜色 insideColor: '#fff' }, // 修改外边框 outline: { itemStyle: { borderColor: '#aaa4a', borderWidth: 1, color: 'none', shadowColor: '#fff' }, // 去除默认边距 borderDistance: 0 }, // 水球图球里面的背景颜色 backgroundStyle: { color: '#fff' }, // 去除水球图背景里面默认的阴影 itemStyle: { shadowBlur: 0, shadowColor: '#fff' }, // 改动默认的波纹振幅 amplitude: 8, // 设置波纹的颜色,设置为动态的绑定 color: [getColor(this.chartData.rows[0].precent)] } } } } } </script> 复制代码
十五、v-echart中使用词云图
下载词云图包
cnpm i -S echarts-wordcloud
mapView文件中注册并使用
// src\components\MapView\index.vue <template> <div class="chart-wrapper"> <word-cloud /> </div> </template> <script> // import WordCloud from '../../views/WordCloud' // 使用ve-wordcloud的云词条 import WordCloud from '../WordCloud' export default { components: { WordCloud } } </script> 复制代码
1 定义云词条样式
// src\components\WordCloud\index.vue <!-- wordCloud --> <template> <ve-wordcloud :data="chartData" height="100%" :settings="chartSettings" /> </template> <script> export default { data () { return { chartData: { columns: ['name', 'value'], rows: [{ name: '慕课网', // 大小随机 value: 100 * Math.random() }, { name: '慕课网1', value: 100 * Math.random() }, { name: '慕课网2', value: 100 * Math.random() }, { name: '慕课网3', value: 100 * Math.random() }, { name: '慕课网4', value: 100 * Math.random() }, { name: '慕课网5', value: 100 * Math.random() }, { name: '慕课网6', value: 100 * Math.random() }, { name: '慕课网7', value: 100 * Math.random() }, { name: '慕课网8', value: 100 * Math.random() }] }, chartSettings: { // 定义默认的颜色 color: ['rgba(97,216,0,.7)', 'rgba(204,178,26,.7)', 'rgba(245,166,35,.7)', 'rgba(156,13,113,.7)'] } } } } </script> <style lang="scss" scoped> </style> 复制代码
2 定义ve-wordcloud的云词条(第二种使用词云图的库,比较复杂,最后使用上面一种)
// src\views\WordCloud.vue <!-- word-cloud --> <template> <div id="container" /> </template> <script> import 'echarts-wordcloud' export default { mounted () { const data = [{ name: '慕课网', value: 100 }, { name: '数据可视化', value: 50 }, { name: '$am', value: 25 }, { name: '慕课网1', value: 150 }, { name: '数据可视化1', value: 70 }, { name: '$am1', value: 55 }] const chart = this.$echarts.init(document.getElementById('container')) chart.setOption({ series: [{ type: 'wordCloud', data, // 设置最终呈现的效果 shape: 'circle', // 文字随机配色 // Global text style textStyle: { normal: { fontFamily: 'sans-serif', fontWeight: 'bold', // Color can be a callback function or a color string color: function () { // Random color var r = Math.floor(Math.random() * 160) var g = Math.floor(Math.random() * 160) var b = Math.floor(Math.random() * 160) return 'rgb(' + r + ',' + g + ',' + b + ')' } }, emphasis: { shadowBlur: 10, shadowColor: '#333' } } }] }) } } </script> <style lang="scss" scoped> #container { width: 100%; height: 100%; } </style> 复制代码
十六、v-echart中使用词云图
http请求公共方法分装
使用axios来分装: cnpm i axios -S
// src\utils\request.js import axios from 'axios' const service = axios.create({ baseURL: 'http://www.baidu.com', timeout: 5000 }) export default service 复制代码
写一个API方法应用这个
request
// src\api\index.js import request from '../utils/request' export function test () { return request({ url: '/test', method: 'get' }) } 复制代码
在home页面做请求
// src\views\Home.vue <template> <div class="home"> <top-view /> <sales-view /> <bottom-view /> <map-view /> </div> </template> <script> // @ is an alias to /src import TopView from '../components/TopView' import SalesView from '../components/SalesView' import BottomView from '../components/BottomView' import MapView from '../components/MapView' import { test } from '../api' export default { name: 'Home', components: { TopView, SalesView, BottomView, MapView }, mounted () { test() } } </script> <style> .home { width: 100%; /* height: 100%; */ padding: 20px; background: #eee; box-sizing: border-box; } </style> 复制代码
解决跨域
// 复制代码
4.2 额外知识点( get
和 post
传参不同)
// get 传参使用params import request from '../utils/request' export function test () { return request({ url: '/test', method: 'get', // 请求结果后面带参数 params: { a: 1 } }) } 复制代码
// post 传参使用data import request from '../utils/request' export function test () { return request({ url: '/test', method: 'post', // 请求结果后面带参数 data: { a: 1 }, params: { b: 1 } }) } 复制代码
3 额外知识点(定义响应拦截器)
//src\utils\request.js import axios from 'axios' const service = axios.create({ baseURL: 'http://www.baidu.com', timeout: 5000 }) // 响应拦截器 service.interceptors.response.use( response => { }, error => { return Promise.reject(error) } ) export default service 复制代码
// src\views\Home.vue // 抓取 export default { name: 'Home', components: { TopView, SalesView, BottomView, MapView }, // 抓取错误并弹出 mounted () { test().catch(err => alert(err.message)) } } 复制代码
十七、防盗网接口接入(重点)
接入慕课网的防盗网通用域名
// src\utils\request.js import axios from 'axios' const service = axios.create({ baseURL: 'http://apis.imooc.com', timeout: 5000 }) // 响应拦截器 service.interceptors.response.use( response => { }, error => { return Promise.reject(error) } ) export default service 复制代码
// src\api\index.js import request from '../utils/request' export function wordcloud () { return request({ url: '/screen/wordcloud', method: 'post', // 请求结果后面带参数,icode失效了 params: { icode: '903170538' } }) } 复制代码
// src\views\Home.vue <template> <div class="home"> <top-view /> <sales-view /> <bottom-view /> <map-view /> </div> </template> <script> // @ is an alias to /src import TopView from '../components/TopView' import SalesView from '../components/SalesView' import BottomView from '../components/BottomView' import MapView from '../components/MapView' import { wordcloud } from '../api' export default { name: 'Home', components: { TopView, SalesView, BottomView, MapView }, // 抓取错误并弹出 mounted () { wordcloud() } } </script> <style> .home { width: 100%; /* height: 100%; */ padding: 20px; background: #eee; box-sizing: border-box; } </style>
作者:子玖
链接:https://juejin.cn/post/7015784621203783711