IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue-element-admin分析 -> 正文阅读

[JavaScript知识库]vue-element-admin分析

观摩一下开源项目vue-element-admin的源码,来看看花裤衩大神是如何优雅的写代码,如何封装业务组件的,顺便如果能在自己的项目中应用想必也是极好的

首先拉取代码然后在本地运行

下载依赖的时候遇到报错

解决

echarts

代码运行后第一眼就看见我前些天研究的图表,刚好项目是用的echarts,趁着还有些印象,先来研究一下Vue-element-admin是如何在项目中使用echarts的

?看了几个图表后就得折线图比较符合我的思路就以折线图为例

src/views/dashboard/admin/components/LineChart.vue

先把代码复制下来逐行分析

<template>
  <div
    :class="className"
    :style="{height:height,width:width}"
  />
</template>

<script>
//导入echarts 好像不是按需导入
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize' //应该是封装的resize函数等下再看

export default {
  mixins: [resize],//通过混合使用
  props: {
    //图表样式
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '350px'
    },
    //不知道啥用 false 和true好像没区别
    autoResize: {
      type: Boolean,
      default: true
    },
    //接收图表数据
    chartData: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      chart: null
    }
  },
  //监听数据变化 如果发生改变就重新渲染图表
  watch: {
    chartData: {
      deep: true,
      handler (val) {
        this.setOptions(val)
      }
    }
  },
  //创建图表
  mounted () {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  // 销毁图表实例
  beforeDestroy () {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    // 初始化图表实例
    initChart () {
      //vm.$el获取Vue实例关联的DOM元素;
      this.chart = echarts.init(this.$el, 'macarons')
      this.setOptions(this.chartData)
    },
    // 接收图表数据进行渲染
    setOptions ({ expectedData, actualData } = {}) {
      this.chart.setOption({
        xAxis: {
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
          boundaryGap: false,
          axisTick: {
            show: false
          }
        },
        grid: {
          left: 10,
          right: 10,
          bottom: 20,
          top: 30,
          containLabel: true
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          },
          padding: [5, 10]
        },
        yAxis: {
          axisTick: {
            show: false
          }
        },
        legend: {
          data: ['expected', 'actual']
        },
        series: [{
          name: 'expected', itemStyle: {
            normal: {
              color: '#FF005A',
              lineStyle: {
                color: '#FF005A',
                width: 2
              }
            }
          },
          smooth: true,
          type: 'line',
          data: expectedData,
          animationDuration: 2800,
          animationEasing: 'cubicInOut'
        },
        {
          name: 'actual',
          smooth: true,
          type: 'line',
          itemStyle: {
            normal: {
              color: '#3888fa',
              lineStyle: {
                color: '#3888fa',
                width: 2
              },
              areaStyle: {
                color: '#f3f8ff'
              }
            }
          },
          data: actualData,
          animationDuration: 2800,
          animationEasing: 'quadraticOut'
        }]
      })
    }
  }
}
</script>

一路看下来没什么问题,只有?autoResize不知道是干什么的,看结构应该是在index.vue传入图表数据

index.vue

没有传入宽高,用的默认值


    <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
      <line-chart :chart-data="lineChartData" />
    </el-row>

再看看resize.js,我水平不够还没有使用过mixins,正好借这个机会看看怎么使用

import { debounce } from '@/utils'//引入防抖函数等会来看

export default {
  data () {
    return {
      $_sidebarElm: null,//字面意思是侧边栏,没太搞懂什么作用
      $_resizeHandler: null
    }
  },
  mounted () {
    //定义resize事件 echart如果存在就会调用resize 让图表自适应显示
    this.$_resizeHandler = debounce(() => {
      if (this.chart) {
        this.chart.resize()
      }
    }, 100)

    // 窗口大小变化时就会resize保证图表显示正常
    this.$_initResizeEvent()

    //等会再研究
    this.$_initSidebarResizeEvent()
  },
  //销毁上面两个函数
  beforeDestroy () {
    this.$_destroyResizeEvent()
    this.$_destroySidebarResizeEvent()
  },
  //从其他组件切换到当前组件的时候,调用resize事件
  activated () {
    this.$_initResizeEvent()
    this.$_initSidebarResizeEvent()
  },
  //切换到其他组件销毁上面两个方法
  deactivated () {
    this.$_destroyResizeEvent()
    this.$_destroySidebarResizeEvent()
  },
  methods: {
    $_initResizeEvent () {
      window.addEventListener('resize', this.$_resizeHandler)
    },
    $_destroyResizeEvent () {
      window.removeEventListener('resize', this.$_resizeHandler)
    },
    $_sidebarResizeHandler (e) {
      if (e.propertyName === 'width') {//e.propertyName忘了是啥玩意,大概率是改变的属性啥的 等会查查
        this.$_resizeHandler()
      }
    },
    $_initSidebarResizeEvent () {
      this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
      //动画transition结束后调用this.$_sidebarResizeHandler
      this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
    },
    $_destroySidebarResizeEvent () {
      this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
    }
  }
}

图表相关的都能看懂,就是sidebar相关的有点懵,e.propertyName也忘了,查了一下mdn好像有了点思路

? 我猜测应该是侧边栏宽带发生变化时调用resize方法让图表正常显示

我这里操作了一下侧边栏可以变大变小,当宽带小到一定的时候侧边栏会消失

相关代码

    $_sidebarResizeHandler (e) {
      if (e.propertyName === 'width') {
        this.$_resizeHandler()
      }

        $_initSidebarResizeEvent () {
      this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
      //动画transition结束后调用this.$_sidebarResizeHandler
      this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
    },

最后我在

src/style/sidebar.css中证实了想法

这样一来上面的代码就不难理解了?

通过e.propertyName指示完成动画的css属性名称,然后监听侧边栏的变化,如果是宽带发生改变,就对图表进行resize 保证正常显示

图表部分差不多就这些,用mixin 来处理 resize 代码确实是十分优雅,学到了

直接借鉴到自己的组件中

防抖函数

再分析一下防抖函数

好像和昨天刚看的underscore中防抖函数差不多的思想,有空我写一篇文章仔细分析一下

传入一个参数immediate,代表是否想要立即执行,如果传递了immediate,则立即执行一次函数,然后设置一个定时器,时间截止后将定时器设置为null,下次进入函数时先判断定时器是否为null,然后决定是否再次执行。

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function 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) {
    // 如果定时器不存在并且传递了immediate,立即执行
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

未完待续

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:05:12  更:2022-09-13 11:08:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:42:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码