第一步
根据UI图,确定大屏布局,完成百分比布局,如果有需要可以对其进行拆分,以下是我对通用大屏进行的拆分方式,便于模块化小单元管理。
第二步
封装通用echarts组件
// chart.vue
<template>
<div :id="id" :class="className" :style="{height:height,width:width}" />
</template>
<script>
import * as echarts from 'echarts'
import resize from './mixins/resize'
import tdTheme from './mixins/theme.json' // 引入默认主题
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
},
eventClick: {
type: Function,
default: () => {}
}
},
data() {
return {
chart: null
}
},
mounted() {
echarts.registerTheme('tdTheme', tdTheme) // 覆盖默认主题(自定义预设主题)
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart(chartOption) {
this.chart = echarts.init(this.$el, 'tdTheme')
this.chart = echarts.init(document.getElementById(this.id))
if (chartOption) {
this.chart.setOption(chartOption)
if (this.eventClick) {
this.chart.on('click', this.eventClick)
}
}
}
}
}
</script>
// 页面大小发生改变时,重绘图表
// resize.js
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null
}
},
mounted() {
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.__resizeHandler)
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.__resizeHandler()
}
}
}
}
第三步
页面开发完成后,引入插件,使页面放大缩小的同时可以自适应,这里用到lib-flexible和postcss- pxtorem
- postcss-pxtorem:自动把px转成rem
- lib-flexible:页面自适应插件
npm install lib-flexible --save-dev
npm install postcss-pxtorem@5.1.1 --save-dev
特别注意!
修改 node_modules/lib-flexible/flexible.js 中的大屏自适应函数,直接替换函数即可
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr < 540) {
width = 540 * dpr;
}else if(width / dpr > 1920){
width = 1920 * dpr
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
屏幕最大最小宽:540/1920(按设计稿)
vue.config.js 配置
module.exports = {
css: {
sourceMap: false,
loaderOptions: {
css: {
// options here will be passed to css-loader
},
postcss: {
// options here will be passed to postcss-loader
},
},
},
}
在 vue.config.js 同级新建 postcss.config.js
module.exports = {
plugins: {
autoprefixer: {},
'postcss-pxtorem': {
rootValue: 192, // 结果为:设计稿元素尺寸/10
propList: ['*'], // 是一个存储哪些将被转换的属性列表,这里设置为['*']全部,假设需要仅对边框进行设置,可以写['*', '!border*']
unitPrecision: 5, // 保留rem小数点多少位
// selectorBlackList: ['.radius'], //则是一个对css选择器进行过滤的数组,比如你设置为['fs'],那例如fs-xl类名,里面有关px的样式将不被转换,这里也支持正则写法。
replace: true, // replace (Boolean) Replaces rules containing rems instead of adding fallbacks.
mediaQuery: false, // 媒体查询( @media screen 之类的)中不生效
minPixelValue: 12, // px小于12的不会被转换
exclude: e => { // 指定文件跳过px转rem
if (/src(\\|\/)views(\\|\/)siteScreen/.test(e)) {
return false
}
return true
}
}
}
}
优化
长时间在页面停留,需要定时刷新某些图表数据,或每天哪个时间刷新,每月一刷新...因此需要一个以下函数⬇️
// 轮询函数,每天定时发请求
/*
* @params {String}fn 时间结束时要调用的函数名
*/
polling(fn) {
const nowTemp = this.$dayjs().valueOf() // 获取当前时间戳
const nextTemp = new Date(this.$dayjs().add(1, 'hour').format('YYYY-MM-DD HH:mm:ss').substr(0, 14) + '00:00').getTime()// 获取下个小时时间戳
const tomorrowTemp = new Date(this.$dayjs().add(1, 'days').format().substr(0, 10) + ' 00:00:00').getTime() // 获取今天24:00的时间戳
const residueTemp = nextTemp - nowTemp // 距离下个时间点还有多久
this.pollingST = setTimeout(() => {
clearTimeout(this.pollingST)
this[fn]() // 重新请求函数
}, residueTemp)
}
// 记得清除定时器
beforeDestroy() {
clearTimeout(this.pollingST)
}
// 定义变量
data() {
return {
pollingST: null,
}
}
// 鼠标移入移出刷新
@mouseover="mouseOver" @mouseleave="mouseLeave"
mouseOver() {
clearTimeout(this.pollingST)
this.pollingST = null
},
mouseLeave() {
this.setMonthChange()
},
专门服务大屏的组件库:datav