总有一个功能,你会用的到!
接上篇文章:vue项目干货
源码地址
15.关于echarts图表及随区域大小变化resize
创建lineChart组件,折线图表
代码如下:
<template>
<div :id="srcData.id" class="warnCount"></div>
</template>
<script>
import echarts from 'echarts';
import resize from '../resize' //用于可视区域改变时resize
export default {
name: "chart",
mixins: [resize],
data() {
return {
chartColumn: null,
scale: 1,
}
},
props: {
srcData: Object, //数据
isGetData: Boolean //获取好数据 可以开始绘制标记
},
watch: {
isGetData(val) {
this.drawChart();
}
},
methods: {
drawChart() {
let me=this;
setTimeout(() => {
let me = this;
this.chartColumn.clear();
this.chartColumn.setOption({
tooltip: {
trigger: 'axis',
confine: true
},
yAxis: {
name: '得分',
type: 'value',
axisLine: {
lineStyle: {
color: '#72aafa'
},
},
splitLine: {
show:false,
lineStyle: {
color: '#154d5a',
width: 0.5
}
},
},
xAxis :{
type: 'time',
splitLine: {
show: false,
lineStyle: {
color: '#72aafa',
}
},
axisLine: {
lineStyle: {
color: '#72aafa'
}
},
},
grid:{
top:'15%',
right:'10%',
left:'10%',
bottom:'15%'
},
series:this.srcData.sData
})
}, 0);
}
},
created() {
var me = this;
},
updated() {
},
mounted() {
let charDom = document.getElementById(this.srcData.id), me = this;
charDom.style.height = this.srcData.height + "px";
this.scale = window.innerWidth / 1920;
this.chartColumn = echarts.init(charDom);
this.chartColumn.on('click', function (params) {
me.$emit('click', params);
})
},
beforeDestroy() {
if (this.chartColumn) {
this.chartColumn.clear()
}
},
destroy() {
if (this.chartColumn) {
this.chartColumn.dispose()
this.chartColumn = null;
}
},
components: {}
}
</script>
<style scoped lang="scss">
.warnCount {
width: 100%;
height: 350px;
}
</style>
接下来开始使用该组件:
传值:
warnCountTrendData: {
id: 'warnCountTrend',
height: 350,
sData:[
{
name:'竞逐对',
symbol:'circle',
symbolSize:6,
type:'line',
lineStyle:{
width:1
},
data:[
{value:["2020-01-01 00:00:00",0]},
{value:["2020-01-02 00:00:00",0]},
{value:["2020-01-04 01:01:01",200]},
{value:["2020-01-07 01:01:01",200]}
]
},
{
name:'竞逐对1',
symbol:'circle',
symbolSize:6,
type:'line',
lineStyle:{
width:1
},
data:[
{value:["2020-01-02 00:00:00",0]},
{value:["2020-01-06 04:01:00",100]},
{value:["2020-01-07 01:01:01",200]}
]
}
]
}
当窗口改变时window.onresize可以被监听到,但当导航栏收起时监听不到,此项目的解决方案是安装:element-resize-detector
resize.js文件:
import {debounce} from '../common/util';
import elementResizeDetectorMaker from 'element-resize-detector'
export default {
data() {
return {
$_sidebarElm: null
}
},
mounted() {
let me=this;
this.__resizeHandler = debounce(() => {
if (this.chartColumn) {
this.chartColumn.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler);
const erd = elementResizeDetectorMaker()
erd.listenTo(document.getElementsByClassName("contentBox"),(element)=>{
me.$nextTick(()=>{
me.resize()
})
})
},
beforeDestroy() {
window.removeEventListener('resize', this.__resizeHandler);
},
methods: {
resize() {
this.__resizeHandler()
}
}
}
debounce为函数防抖方法:
export const debounce = (func, wait, immediate) => {
let timeout, args, context, timestamp, result
const later = function () {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function (...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
实现效果:
16.抽屉
通过drawer控制抽屉展示隐藏
<el-button @click="showDrawer" type="primary" class='showBtn' :style='sty'>
<i class='iconfont iconshezhi' v-if='!drawer'></i>
<i class='iconfont iconguanbi' v-else></i>
</el-button>
<el-drawer :visible.sync="drawer" direction="rtl" style='position:absolute' @close='onClose'>
<span class='drawTitle'>设置</span>
<div style='margin:0 auto;width:100%;'>
<el-form ref="form" label-width="80px">
<el-form-item label="选择主题">
<el-select v-model="value" placeholder="请选择" @change='changeColor'>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</el-drawer>
再来控制控制按钮的样式:
.showBtn {
position:absolute;
top:50%;
transform :translateY(-50%);
z-index:100000;
transition: right .3s;
padding:10px!important;
i {
font-size:20px;
}
}
.drawTitle {
position: absolute;
top: 4%;
left: 5%;
font-weight: 700;
color: #666;
font-size: 17px;
}
方法逻辑:
showDrawer:function(){
let me=this;
me.drawer = !me.drawer;
me.value=sessionStorage.getItem('theme');
me.sty.right=me.drawer?'30%':'0' //按钮位置
},
onClose:function(){
let me=this;
me.sty.right='0'
}
实现效果:
17.换肤功能
增加如下两个文件(需安装sass)
mixin.scss
@mixin get-theme-value($type, $value, $css-key, $css-value) {
@each $themename , $theme in $themes {
[data-theme = '#{$themename}'] & {
$_type: map-get($theme, $type);
#{$css-key}: #{$css-value} map-get($_type , $value );
}
}
}
@mixin get-color-value($type, $value) {
@each $themename , $theme in $themes {
[data-theme = '#{$themename}'] & {
$_type: map-get($theme, $type);
#{$type}-color: map-get($_type , $value );
}
}
}
@mixin background($color){
@include get-theme-value('background', $color, 'background', '');
}
@mixin background-color($color){
@include get-color-value('background', $color);
}
@mixin font-color($color) {
@include get-theme-value('font', $color, 'color', '');
}
@mixin border-color($color) {
@include get-color-value('border', $color);
}
@mixin border($color, $css-key:'border', $css-value:'1px solid') {
@include get-theme-value('border', $color, $css-key , $css-value)
}
@mixin box-shadow($color, $css-value) {
@include get-theme-value('boxShadow', $color, 'box-shadow', $css-value)
}
@mixin common-link-font($size: 1.2) {
font-size: #{$size}rem; font-weight: 600;
&:hover,
&.selected{
@include font-color('color4');
}
@include font-color('color1');
}
@mixin common-font($size: 1.2, $font-weight: 400) {
font-size: #{$size}rem; font-weight: $font-weight;
@include font-color('color1');
}
@mixin flex($justify: flex-start, $align-items: center, $dir: row, $wrap: nowrap, $align-content: stretch) {
display: flex;
flex-flow: $dir $wrap;
justify-content: $justify;
align-items: $align-items;
align-content: $align-content;
}
theme.css 定义两套主题
@import './mixin.scss';
// default theme
$default-theme : (
font: (
color1: #16284c,
),
border: (
color1: #16284c,
),
background: (
color1: #16284c,
),
boxShadow: (
color1: rgba(0,0,0,.3)
)
);
//红色主题
$red-theme : (
font: (
color1: red
),
border: (
color1: red
),
background: (
color1: red
),
boxShadow: (
color1: rgba(0,0,0,.3)
)
);
$themes: (
default-theme: $default-theme,
red-theme: $red-theme
);
App.vue
<template>
<div id="app">
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
</div>
</template>
<script>
export default {
name: 'app',
data(){
return {
getNowThemeInfo:'' //初始主题
}
},
mounted() {
let me=this;
me.getNowThemeInfo=sessionStorage.getItem('theme');
me.setBodyTheme();
},
methods: {
setBodyTheme() {
document.body.dataset.theme = this.getNowThemeInfo;
}
},
components: {}
}
</script>
<style lang="scss">
body {
margin: 0px;
padding: 0px;
/*background: url(assets/bg1.jpg) center !important;
background-size: cover;*/
// background: #1F2D3D;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
font-size: 14px;
-webkit-font-smoothing: antialiased;
}
#app {
position: absolute;
top: 0px;
bottom: 0px;
width: 100%;
}
.el-submenu [class^=fa] {
vertical-align: baseline;
margin-right: 10px;
}
.el-menu-item [class^=fa] {
vertical-align: baseline;
margin-right: 10px;
}
.toolbar {
background: #f2f2f2;
padding: 10px;
//border:1px solid #dfe6ec;
margin: 10px 0px;
.el-form-item {
margin-bottom: 10px;
}
}
.fade-enter-active,
.fade-leave-active {
transition: all .2s ease;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
</style>
当某个元素的颜色信息需要随主题改变时,需要这样定义颜色信息
你会发现浏览器中样式使这样写的
基本换肤功能就实现了,下面介绍下如何切换(此项目将主题信息存储在session中)
main.js中增加如下方法,监听session
Vue.prototype.resetSetItem = function (key, newVal) {
if (key =='theme') {
// 创建一个StorageEvent事件
var newStorageEvent = document.createEvent('StorageEvent');
const storage = {
setItem: function (k, val) {
sessionStorage.setItem(k, val);
// 初始化创建的事件
newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null);
// 派发对象
window.dispatchEvent(newStorageEvent)
}
}
return storage.setItem(key, newVal);
}
}
在app.vue中监听变化
window.addEventListener('setItem', ()=> {
var val = sessionStorage.getItem('theme');
console.log(val);
this.getNowThemeInfo=sessionStorage.getItem('theme');
this.setBodyTheme();
})
在改变主题信息时记得存session里theme
录屏工具打不开了...效果先看项目吧
将不断更新完善,期待您的批评指正!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。