一、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 class="home">
<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 class="top-view"> <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 class="common-card">
<div class="title">{{title}}</div>
<div class="value">{{value}}</div>
</div>
</template>
<script>
export default {
// 设置title传入的值为字符型
props: {
title: String,
value: String
}
}
</script>
<style lang="scss" 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 class="common-card"> // 写入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 lang="scss" 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文件
6. 【报错,我执行替换了,之后在改】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>