Vue2大屏项目的简要总结(vue、JavaScript、echarts、组件封装)

Vue2大屏项目的简要总结

1、屏幕自适应 — v-scale-screen
简介

实现的主要核心手段就是使用css属性transform实现缩放效果,会进行等比例计算达到等比缩放效果

使用
// 1、安装依赖
npm install v-scale-screen -save
# or
yarn add v-scale-screen

// 2、main.js中引入
import VScaleScreen from 'v-scale-screen'
Vue.use(VScaleScreen)

// 3、使用

	

简要说明
  1. 通过该方法实现屏幕自适应无需考虑使用rem等单位,直接px布局即可。
实现效果
  1. 正常打开情况下

    在这里插入图片描述

  2. 调整浏览器大小后显示情况

    在这里插入图片描述

2、数字翻牌器 – vue-count-to
简介

是一个组件插件,像组件一样注册就可使用

使用
// 1、安装
npm install vue-count-to

// 2、引入
import CountTo from 'vue-count-to'

// 3、注册
components: {
  CountTo
},

// 4、使用
// 变化前数据startVal:Number
// 变化后数据endVal:Number
// 变化时间间隔duration:ms

项目中使用

封装数字翻牌部分,将数据以对象的形式传递过去

// 数据(假设父组件传递过来的数据是下面这个)
testData: {
	startVal: 0,
	endVal: 32,
}

// 至于duration的话看个人情况吧,直接再翻牌组件中写死也行
补充说明

其实dataV也有数字翻牌器功能,但这种方法和dataV的数字翻牌器更加易于理解并且更加直观,大家可以研究研究

3、Echarts图表的使用
简介

大屏中echarts图表展示几乎是不可避免的,以图表的形式展示数据给人的感官更加直观舒服,能够清除的反映数据的变化。下面是Vue项目中echarts图表的使用

使用
// 1、下包
 npm install echarts --save
 
// 2、全局引入
import * as echarts from "echarts"; // 引入echarts
Vue.prototype.$echarts = echarts;

// 3、组件中使用 HuLiDengJi.vue
// 模板

  


// 逻辑部分
async mounted() {
  this.huLiEcharts = this.$echarts.init(this.$refs.huLiRef);
  this.drawLine();
},

data() {
    return {
      huLiEcharts: "",
 	  options: {}, // echarts图表的数据,可在线上调试后复制即可,但里面的数据部分需要父组件传递,因为是会变化的
    };
  },

// 方法
methods: {
	drawLine() {
      	this.huLiEcharts.setOption(this.option);
    }
},

// 侦听器 -- 数据变化重新渲染
watch: {
    huLiData: {
    	deep: true,
      	// immediate: true,
      	handler() {
        	this.drawLine();
      	},
    },
},
4、echarts图表自动轮播tooltip
简介

最终效果是实现鼠标在不移入echarts图的情况下,能够让他以一定时间间隔自动顺序选中内容进行展示,当鼠标移入后会停止自动轮播,鼠标移除后又回复轮播

代码
1、先将自动轮播方法封装成一个单独的js文件
/**
 * echarts tooltip轮播
 * @param chart ECharts实例
 * @param chartOption echarts的配置信息
 * @param options object 选项
 * {
 *  interval    轮播时间间隔,单位毫秒,默认为2000
 *  loopSeries  boolean类型,默认为false。
 *              true表示循环所有series的tooltip,false则显示指定seriesIndex的tooltip
 *  seriesIndex 默认为0,指定某个系列(option中的series索引)循环显示tooltip,
 *              当loopSeries为true时,从seriesIndex系列开始执行。
 *  updateData  自定义更新数据的函数,默认为null;
 *              用于类似于分页的效果,比如总数据有20条,chart一次只显示5条,全部数据可以分4次显示。
 * }
 * @returns {{clearLoop: clearLoop}|undefined}
 */
export function loopShowTooltip(chart, chartOption, options) {
  let defaultOptions = {
    interval: 2000,
    loopSeries: false,
    seriesIndex: 0,
    updateData: null,
  };

  if (!chart || !chartOption) {
    return;
  }

  let dataIndex = 0; // 数据索引,初始化为-1,是为了判断是否是第一次执行
  let seriesIndex = 0; // 系列索引
  let timeTicket = 0;
  let seriesLen = chartOption.series.length; // 系列个数
  let dataLen = 0; // 某个系列数据个数
  let chartType; // 系列类型
  let first = true;
  let lastShowSeriesIndex = 0;
  let lastShowDataIndex = 0;

  if (seriesLen === 0) {
    return;
  }

  // 待处理列表
  // 不循环series时seriesIndex指定显示tooltip的系列,不指定默认为0,指定多个则默认为第一个
  // 循环series时seriesIndex指定循环的series,不指定则从0开始循环所有series,指定单个则相当于不循环,指定多个
  // 要不要添加开始series索引和开始的data索引?

  if (options) {
    options.interval = options.interval || defaultOptions.interval;
    options.loopSeries = options.loopSeries || defaultOptions.loopSeries;
    options.seriesIndex = options.seriesIndex || defaultOptions.seriesIndex;
    options.updateData = options.updateData || defaultOptions.updateData;
  } else {
    options = defaultOptions;
  }

  // 如果设置的seriesIndex无效,则默认为0
  if (options.seriesIndex = seriesLen) {
    seriesIndex = 0;
  } else {
    seriesIndex = options.seriesIndex;
  }

  /**
   * 清除定时器
   */
  function clearLoop() {
    if (timeTicket) {
      clearInterval(timeTicket);
      timeTicket = 0;
    }

    chart.off("mousemove", stopAutoShow);
    zRender.off("mousemove", zRenderMouseMove);
    zRender.off("globalout", zRenderGlobalOut);
  }

  /**
   * 取消高亮
   */
  function cancelHighlight() {
    /**
     * 如果dataIndex为0表示上次系列完成显示,如果是循环系列,且系列索引为0则上次是seriesLen-1,否则为seriesIndex-1;
     * 如果不是循环系列,则就是当前系列;
     * 如果dataIndex>0则就是当前系列。
     */
    let tempSeriesIndex =
      dataIndex === 0
        ? options.loopSeries
          ? seriesIndex === 0
            ? seriesLen - 1
            : seriesIndex - 1
          : seriesIndex
        : seriesIndex;
    let tempType = chartOption.series[tempSeriesIndex].type;

    if (tempType === "pie" || tempType === "radar" || tempType === "map") {
      chart.dispatchAction({
        type: "downplay",
        seriesIndex: lastShowSeriesIndex,
        dataIndex: lastShowDataIndex,
      }); // wait 系列序号为0且循环系列,则要判断上次的系列类型是否是pie、radar
    }
  }

  /**
   * 自动轮播tooltip
   */
  function autoShowTip() {
    let invalidSeries = 0;
    let invalidData = 0;
    function showTip() {
      // chart不在页面中时,销毁定时器
      let dom = chart.getDom();
      if (document !== dom && !document.documentElement.contains(dom)) {
        clearLoop();
        return;
      }

      // 判断是否更新数据
      if (
        dataIndex === 0 &&
        !first &&
        typeof options.updateData === "function"
      ) {
        options.updateData();
        chart.setOption(chartOption);
      }

      let series = chartOption.series;
      let currSeries = series[seriesIndex];
      if (
        !series ||
        series.length === 0 ||
        !currSeries ||
        !currSeries.type ||
        !currSeries.data ||
        !currSeries.data.length
      ) {
        return;
      }

      chartType = currSeries.type; // 系列类型
      dataLen = currSeries.data.length; // 某个系列的数据个数

      let tipParams = {
        seriesIndex: seriesIndex,
      };
      switch (chartType) {
        case "pie":
          // 处理饼图中数据为0或系列名为空的不显示tooltip
          if (
            !currSeries.data[dataIndex].name ||
            currSeries.data[dataIndex].name === "空" ||
            !currSeries.data[dataIndex].value
          ) {
            invalidData += 1;
            dataIndex = (dataIndex + 1) % dataLen;
            if (options.loopSeries && dataIndex === 0) {
              // 数据索引归0表示当前系列数据已经循环完
              // 无效数据个数个总数据个数相等,则该系列无效
              if (invalidData === dataLen) {
                invalidSeries += 1;
              }

              // 新系列,重置无效数据个数
              invalidData = 0;

              // 系列循环递增1
              seriesIndex = (seriesIndex + 1) % seriesLen;
              // 系列数循环至起始值时重置无效系列数
              if (seriesIndex === options.seriesIndex) {
                if (seriesLen !== invalidSeries) {
                  // 下一次系列轮回,重置无效系列数
                  invalidSeries = 0;
                  showTip();
                } else {
                  // 下一次系列轮回,重置无效系列数
                  invalidSeries = 0;
                  clearLoop();
                }
              } else {
                showTip();
              }
            } else if (!options.loopSeries && dataIndex === 0) {
              if (dataLen !== invalidData) {
                invalidData = 0;
                showTip();
              } else {
                invalidData = 0;
                clearLoop();
              }
            } else {
              showTip();
            }

            return;
          }
        // eslint-disable-next-line no-fallthrough
        case "map":
        case "chord":
          tipParams.name = currSeries.data[dataIndex].name;
          break;
        case "radar": // 雷达图
          tipParams.seriesIndex = seriesIndex;
          // tipParams.dataIndex = dataIndex;
          break;
        case "lines": // 线图地图上的lines忽略
          dataIndex = 0;
          seriesIndex = (seriesIndex + 1) % seriesLen;
          invalidSeries++; // 记录无效系列数,如果无效系列数和系列总数相等则取消循环显示
          if (seriesLen !== invalidSeries) {
            showTip();
          } else {
            clearLoop();
          }
          return;
        default:
          tipParams.dataIndex = dataIndex;
          break;
      }

      if (chartType === "pie" || chartType === "radar" || chartType === "map") {
        if (!first) {
          cancelHighlight();
        }

        // 高亮当前图形
        chart.dispatchAction({
          type: "highlight",
          seriesIndex: seriesIndex,
          dataIndex: dataIndex,
        });
      }

      // 显示 tooltip
      tipParams.type = "showTip";
      chart.dispatchAction(tipParams);

      lastShowSeriesIndex = seriesIndex;
      lastShowDataIndex = dataIndex;

      dataIndex = (dataIndex + 1) % dataLen;
      if (options.loopSeries && dataIndex === 0) {
        // 数据索引归0表示当前系列数据已经循环完
        invalidData = 0;
        seriesIndex = (seriesIndex + 1) % seriesLen;
        if (seriesIndex === options.seriesIndex) {
          invalidSeries = 0;
        }
      }

      first = false;
    }

    showTip();
    timeTicket = setInterval(showTip, options.interval);
  }

  // 关闭轮播
  function stopAutoShow() {
    if (timeTicket) {
      clearInterval(timeTicket);
      timeTicket = 0;

      if (chartType === "pie" || chartType === "radar" || chartType === "map") {
        cancelHighlight();
      }
    }
  }

  let zRender = chart.getZr();

  function zRenderMouseMove(param) {
    if (param.event) {
      // 阻止canvas上的鼠标移动事件冒泡
      // param.event.cancelBubble = true;
    }
    stopAutoShow();
  }

  // 离开echarts图时恢复自动轮播
  function zRenderGlobalOut() {
    // console.log("移出了")
    // console.log(timeTicket)
    if (!timeTicket) {
      autoShowTip();
    }
  }

  // 鼠标在echarts图上时停止轮播
  chart.on("mousemove", stopAutoShow);
  zRender.on("mousemove", zRenderMouseMove);
  zRender.on("globalout", zRenderGlobalOut);

  autoShowTip();

  return {
    clearLoop: clearLoop,
  };
}
2、在需要使用改方法的文件中引入
import { loopShowTooltip } from "../../../tooltip-auto-show-vue.js";
export default {
  data() {
    return {
      tootipTimer:""
    };
  },
}
3、引用刚才封装的js方法
myChart.setOption(option);
this.tootipTimer && this.tootipTimer.clearLoop(); // this.tootipTimer 在data里定义
this.tootipTimer = 0;
// 调用轮播的方法
this.tootipTimer = loopShowTooltip(myChart, option, {
	interval: 2000, // 轮播间隔时间
	loopSeries: true, // 是否开启轮播循环
    // loopSeries: boolean类型,默认为false。true表示循环所有series的tooltip;false则显示指定seriesIndex的tooltip。
    // seriesIndex: 默认为0,指定某个系列(option中的series索引)循环显示tooltip,当loopSeries为true时,从seriesIndex系列开始执行。
});
效果
初始效果

请添加图片描述

会自动的顺序选中显示

请添加图片描述

参考文献

vue项目中的echarts图表,实现自动轮播tooltip_echarts 自动轮播tooltip

5、echarts图标禁用legend默认的点击行为实现
简介

我遇到的场景是基于上面的一个场景,默认情况下点击图标的legend时会隐藏对应区域,但如果存在自动轮播的时候,就会产生一个空缺,也就是你让点击的legend内容隐藏了,但轮播的时候还会对隐藏区域进行轮播,造成轮播到隐藏部分时会出现显示的一个空缺,如果我们去禁用掉隐藏区域这个功能后,那么也就不会出现这一问题了

代码
myChart.on('legendselectchanged', function (params) {
	myChart.setOption({
		legend:{selected:{[params.name]: true}}
	})
	 console.log('点击了', params.name);
	// do something
});
参考文献

Echarts 自定义、覆盖legend点击事件、禁用legend默认的点击行为的实现_legend禁止点击

6、表格自动滚动
简介

大屏中很可能遇到图标自动滚动效果,这个可以使用dataV的一个组件进行实现

代码
// 模板使用


// 数据部分
export default {
  header: ['列1', '列2', '列3'], // 表头
  data: [
    ['行1列1', '行1列2', '行1列3'],
    ['行2列1', '行2列2', '行2列3'],
    ['行3列1', '行3列2', '行3列3'],
    ['行4列1', '行4列2', '行4列3'],
    ['行5列1', '行5列2', '行5列3'],
    ['行6列1', '行6列2', '行6列3'],
    ['行7列1', '行7列2', '行7列3'],
    ['行8列1', '行8列2', '行8列3'],
    ['行9列1', '行9列2', '行9列3'],
    ['行10列1', '行10列2', '行10列3']
  ]
}
注意事项
  1. 数据改变时用修改整个config对象的形式进行修改,因为它组件内部没用设置deep进行深度侦听,因此只修改configdata是监测不到的,刷新不了
  2. 轮播表还有很多配置可参考,具体可以看一下dataV官网
参考文献

轮播表 | DataV (jiaminghi.com)

7、公告类的部分实现自动滚动
简介

需要一个类似公告消息滚动的实现,移动端一般有对应的vant或者uView可以使用,pc的话element-ui暂时没有,但也是有方法可以实现的

代码
新建一个组件使用就行
  
    
      

{{ sendVal }}

export default { name: 'ScrollMessageTwo', props: { sendVal: { type: String, default: '暂无' } }, data() { return { value: 0, timer: '', //计时器 pwidth: 0, //公告文本的宽度 windowWidth: 0 // 设备屏幕的宽度 } }, mounted() { this.windowWidth = document.querySelector('#box').clientWidth let element = this.$refs.cmdlist this.pwidth = document.defaultView .getComputedStyle(element, '') .width.split('px') this.timer = setInterval(this.clickCommend, 20) }, watch: { value(newValue) { let allWidth = parseInt(this.windowWidth) + parseInt(this.pwidth[0]) if (newValue <= -allWidth) { this.$refs.cmdlist.style.marginLeft = this.windowWidth + 'px' this.value = 0 } } }, methods: { clickCommend() { let _this = this this.$nextTick(() => { this.value -= 1 this.$refs.cmdlist.style.marginLeft = _this.windowWidth + this.value + 'px' }) }, menter() { clearInterval(this.timer) }, mleave() { this.timer = setInterval(this.clickCommend, 20) } }, beforeDestroy() { clearInterval(this.timer) } } #box { display: flex; align-items: center; overflow: hidden; } .marquee-box { display: inline-block; overflow: auto; } #pWidth { display: inline-block; word-break: keep-all; white-space: nowrap; overflow: hidden; }
参考文献

vue实现横屏滚动公告效果_vue.js_脚本之家 (jb51.net)

说明

原参考文章是获取整个屏幕的宽度,也就是屏幕宽度的一个消息滚动,但我遇到的场景只是一小块内容区域滚动,因此对它windowWidth的值进行了修改,大家也可以按自己的情况进行修改

8、区域内容自动滚动实现
简介

类似于表格自动滚动,但这不是一个表格却也要进行滚动

当内容超过高度时,开启自动滚动

默认向下滚动,触底后在向上

点击内容区域后还会停止滚动,此时你可以通过鼠标滚轮进行滚动

代码实现
  
    
      滚动内容1
滚动内容2
滚动内容3
滚动内容4
滚动内容5
滚动内容6
滚动内容7
滚动内容8
滚动内容9
滚动内容10
滚动内容11
滚动内容12
滚动内容13
滚动内容14
滚动内容15
滚动内容16
滚动内容17
滚动内容18
export default { data() { return { scrollTimer: null, // 滚动定时器 pauseTimer: null, // 暂停定时器 scrollId: 'scrollId', // 滚动容器id scrollDirection: 'down' // 滚动方向 up向上 down向下 } }, destroyed() { // 清理定时器 clearTimeout(this.pauseTimer) this.pauseTimer = null clearInterval(this.scrollTimer) this.scrollTimer = null // 清理点击监听 window.document.removeEventListener('click', this.pauseScroll) }, mounted() { this.dataCompleteFun() }, methods: { // 数据加载完成方法 dataCompleteFun() { // 开启滚动 this.autoScroll() }, autoScroll() { const scrollHeight = document.getElementById(this.scrollId).scrollHeight const clientHeight = document.getElementById(this.scrollId).clientHeight const scroll = scrollHeight - clientHeight // 滚动长度为0 if (scroll === 0) { return } // 触发滚动方法 this.scrollFun() // 去除点击监听 window.document.removeEventListener('click', this.pauseScroll) // 重设点击监听 window.document.addEventListener('click', this.pauseScroll, false) }, pauseScroll() { // 定时器不为空 if (this.scrollTimer) { // 清除定时器 clearInterval(this.scrollTimer) this.scrollTimer = null // 一秒钟后重新开始定时器 this.pauseTimer = setTimeout(() => { this.scrollFun() }, 2000) } }, scrollFun() { // 如果定时器存在 if (this.scrollTimer) { // 则先清除 clearInterval(this.scrollTimer) this.scrollTimer = null } this.scrollTimer = setInterval(() => { const scrollHeight = document.getElementById(this.scrollId).scrollHeight const clientHeight = document.getElementById(this.scrollId).clientHeight const scroll = scrollHeight - clientHeight // 获取当前滚动条距离顶部高度 const scrollTop = document.getElementById(this.scrollId).scrollTop // 向下滚动 if (this.scrollDirection === 'down') { const temp = scrollTop + 1 document.getElementById(this.scrollId).scrollTop = temp // 滚动 // 距离顶部高度 大于等于 滚动长度 if (scroll <= temp) { // 滚动到底部 停止定时器 clearInterval(this.scrollTimer) this.scrollTimer = null // 改变方向 this.scrollDirection = 'up' // 一秒后重开定时器 setTimeout(() => { this.scrollFun() }, 1000) } // 向上滚动 } else if (this.scrollDirection === 'up') { const temp = scrollTop - 0.5 document.getElementById(this.scrollId).scrollTop = temp // 滚动 // 距离顶部高度 小于等于 0 if (temp <= 0) { // 滚动到底部 停止定时器 clearInterval(this.scrollTimer) this.scrollTimer = null // 改变方向 this.scrollDirection = 'down' // 一秒后重开定时器 setTimeout(() => { this.scrollFun() }, 1000) } } }, 150) } } }
参考文献

vue实现自动滚动效果(上下往复) – 前端 – 华仔部落 (zjh336.cn)

更新

后期对排版进行了调整

在这里插入图片描述

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/28348eaa03.html