vue2 echarts饼状图,柱状图,折线图,简单封装以及使用

news2025/1/20 19:22:36

vue2 echarts饼状图,柱状图,折线图,简单封装以及使用

1. 直接上代码(复制可直接用,请根据自己的文件修改引用地址,图表只是简单封装,可根据自身功能,进行进一步配置。

2. 安装echarts npm install echarts --save

3. 安装 npm install element-resize-detector --save注:该配置在博客最底部 用于 echarts 宽高计算等)

4. 柱状图简单封装

  1. 先上菜单目录
    2. ](https://img-blog.csdnimg.cn/direct/cb6c1c62e1514158bb2c0e0574f0f5c3.png)

  2. 新建 barChart.vue


 // barChart.vue
 
 <template>
  <div :style="{ height: height, width: width }" />
</template>

<script>
import * as echarts from "echarts";
import resize from "@/echarts/mixins/resize";
export default {
  mixins: [resize],
  props: {
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "280px",
    },
    chartData: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      chart: null,
    };
  },
  watch: {
    // 监听表数据变化,重新初始化图表
    chartData: {
      deep: true,
      handler(val) {
        if (this.chart) {
          this.$nextTick(() => {
            this.initChart();
          });
        }
      },
    },
  },
  mounted() {
    // 初始化图表
    this.initChart();
  },
  beforeDestroy() {
    // 页面销毁时 销毁图表
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el);
      this.setOptions(this.chartData);
    },
    // 图表配置项
    setOptions(chartData) {
      const { data = [], color = [], yLabel = "" } = chartData;
      const names = data.map((item) => item.name);
      const values = data.map((item) => {
        if (color.length) {
          return {
            value: item.value,
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: color[0][1] },
                { offset: 1, color: color[0][2] },
              ]),
            },
          };
        } else {
          return {
            value: item.value,
            itemStyle: {
              // 此处设置柱状图的渐变
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: "rgba(19, 179, 228, 0.2)" },
                { offset: 1, color: "rgba(19, 179, 228, 1)" },
              ]),
            },
          };
        }
      });
      const valuesDefaultItem = data.map((item) => {
        if (color.length) {
          // 此处判断 是否使用传入的颜色
          return {
            value: 0,
            itemStyle: {
              color: color[0][3],
            },
            emphasis: {
              itemStyle: {
                color: color[0][3],
              },
            },
          };
        } else {
          return {
            value: 0,
            itemStyle: {  // 柱状图顶部颜色
              color: 'rgb(19, 179, 228)',
            },
            emphasis: {
              itemStyle: {
                color: '#333',  // 柱状图顶部hover时的颜色
              },
            },
          };
        }
      });
      const valuesMax = data.map((item) => item.value / 5);
      const options = {
        grid: {
          top: 50,
          left: 20,
          right: 20,
          bottom: 0,
          containLabel: true,
        },
        tooltip: {
          trigger: "axis",
          formatter: `{b}<br />{c}${yLabel}`,
          axisPointer: {
            // 坐标轴指示器,坐标轴触发有效
            type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
            shadowStyle: {
              color: "#e7baba61", // 鼠标移入时的背景色
            },
          },
          borderColor: "rgb(19, 179, 228)", // 鼠标移入时 悬浮框border样式
          backgroundColor: "rgba(6,167,205,.9)",  // 鼠标移入时 悬浮框背景样式
          padding: 10, // 鼠标移入时 悬浮框padding
          textStyle: { // 鼠标移入时 悬浮框内容样式
            fontSize: 14,
            fontWeight: 400,
            color: "yellow",
          },
        },
        xAxis: {
          data: names,
          nameLocation: "center",
          axisLabel: {
            rotate: 0,
            interval: 0,
            align: "center",
            // X轴  字体样式
            textStyle: {
              color: "#333333",
              fontSize: 12,
              fontWeight: 500,
            },
           
            // 此处设置 X轴  多出3个字符就进行换行(可自定义设置)
  
            // formatter: function (params) {
            //   let newParamsName = ""; // 拼接后的新字符串
            //   let paramsNameNumber = params.length; // 实际标签数
            //   let provideNumber = 3; // 每行显示的字数
            //   let rowNumber = Math.ceil(paramsNameNumber / provideNumber); // 如需换回,算出要显示的行数

            //   if (paramsNameNumber > provideNumber) {
            //     /** 循环每一行,p表示行 */

            //     for (let i = 0; i < rowNumber; i++) {
            //       let tempStr = ""; // 每次截取的字符串
            //       let start = i * provideNumber; // 截取位置开始
            //       let end = start + provideNumber; // 截取位置结束

            //       // 最后一行的需要单独处理

            //       if (i == rowNumber - 1) {
            //         tempStr = params.substring(start, paramsNameNumber);
            //       } else {
            //         tempStr = params.substring(start, end) + "\n";
            //       }
            //       newParamsName += tempStr;
            //     }
            //   } else {
            //     newParamsName = params;
            //   }
            //   return newParamsName;
            // },
          },
          axisTick: {
            show: false,
          },
          axisLine: {
            show: false,
          },
          z: 10,
        },
       dataZoom: [
          {
            type: "inside",
            start: 20, //数据窗口范围的起始百分比。范围是:0 ~ 100。表示 0% ~ 100%。
            end: 100,
            xAxisIndex: 0, //设置控制xAxis
            // yAxisIndex: 0, //设置控制yAxis
            zoomOnMouseWheel: true, //设置鼠标滚轮不能触发缩放。
          },
        ],
        yAxis: {
          name: yLabel, // Y周单位
          nameTextStyle: { // 单位样式
            color: "#333",
            align: "center",
          },
          // y轴刻度样式
          axisLabel: {
            textStyle: {
              color: "#333333",
              fontSize: 12,
              fontWeight: 400,
            },
          },
          // y轴刻度横线样式
          splitLine: {
            lineStyle: {
              color: "#dddddd",
            },
          },
          // 是否显示y轴
          axisLine: {
            show: true,
          },
        },
        series: [
          {
            type: "bar",
            barMaxWidth: 36,
            label: {
              show: true,
              position: "top",
              distance: 4,
              color: "#fff",
              fontSize: 13,
              fontWeight: 400,
              formatter: `{c}`,
            },
            data: values,
            stack: "one",
          },
          // 设置柱状图顶部的样式
          {
            type: "bar",
            barMaxWidth: 60,
            stack: "one",
            barMinHeight: 3,
            barMaxHeight: 3,
            cursor: "default",
            data: valuesDefaultItem,
          },
          {
            type: "bar", //占位
            barMaxWidth: 36, // 设置柱状图宽度
            stack: "one",
            barMinHeight: 3,
            barMaxHeight: 3,
            cursor: "default",
            emphasis: {
              itemStyle: {
                color: "transparent",
              },
            },
            itemStyle: {
              color: "transparent",
            },
            data: valuesMax,
          },
        ],
      };
      console.log(options);
      this.chart.setOption(options);
    },
  },
};
</script>

在这里插入图片描述

5. 柱状图组件使用

<template>
  <div class="about">
    <div class="box-card">
      <div style="width:100%;height:100%">
        <barChart :chartData="chartData" height="100%"></barChart>
      </div>
    </div>
  </div>
</template>
<script>
import barChart from "./components/barChart.vue"; // 柱状图
export default {
  components: {
    barChart,
  },
  data() {
    return {
      chartData: {
        yLabel: "次",
        color: [],
        data: [],
      },
    };
  },
  mounted(){
    // 调用接口
    this.getFaceData()
  },
  methods: {
    getFaceData() {
      // 此处应该调用接口
      // 暂时使用假数据
      this.chartData.data = [
        {
          name: "admin11",
          value: 505,
        },
        {
          name: "lss11",
          value: 600,
        },
        {
          name: "zbw",
          value: 800,
        },
        {
          name: "陌生人",
          value: 902,
        },
      ];
    },
  },
};
</script>
<style lang="scss">
.box-card {
  width: 800px;
  height: 400px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin: 20px;
}
</style>

6. 饼状图简单封装

  1. 新建 pieChart.vue

//pieChart.vue

<template>
  <div :style="{ height: height, width: width }" />
</template>
<script>
import * as echarts from "echarts";
import resize from "@/echarts/mixins/resize";
export default {
  mixins: [resize],
  props: {
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "280px",
    },
    chartData: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      chart: null,
    };
  },
  watch: {
    // 监听表数据变化,重新初始化图表
    chartData: {
      deep: true,
      handler(val) {
        if (this.chart) {
          this.$nextTick(() => {
            this.initChart();
          });
        }
      },
    },
  },
  mounted() {
    // 初始化图表
    this.initChart();
  },
  beforeDestroy() {
    // 页面销毁时 销毁图表
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el);
      this.setOptions(this.chartData);
    },
    // 图表配置项
    setOptions(chartData) {
      // 图表数据
      const data = chartData.data;
      // 计算图标中心的数据总值
      let sum = data.reduce((pre, cur, index, arr) => {
        return pre + cur.value;
      }, 0);
      // 图表中心显示的名称
      let name = chartData.name;
      const options = {
        // 自定义设置图表颜色
        color: [
          "rgb(53, 136, 229)",
          "rgb(13, 235, 251)",
          "rgb(227, 59, 90)",
          "rgb(255, 147, 38)",
          "rgb(176, 210, 231)",
          "rgb(62, 255, 194)",
          "rgb(138, 92, 247)",
          "rgb(25, 120, 162)",
          "rgb(67, 207, 124)",
          "rgb(255, 195, 0)",
        ],
        // 鼠标hover时显示的浮窗
        tooltip: {
          trigger: "item",
          formatter: "{b}: {c} ({d}%)",
          borderColor: "transparent",
          backgroundColor: "rgba(6,167,205,.9)",
          padding: 10,
          textStyle: {
            fontSize: 14,
            fontWeight: 400,
            color: "#fffafa",
          },
        },
        legend: {
          type: "scroll", //这里添加scroll就可以分页了
          orient: "vertical",  //图例列表的布局朝向 horizontal (默认顶部)vertical(默认右边)
          right: "0%",
          // 'circle'(圆形),'rect(矩形)','roundRect(矩形边角为圆弧)'
          // 'triangle(三角形)','diamond(矩形)','pin(形状类似于锤子的尾部)','arrow(飞机形状)','none'
          icon: "circle",
          top: "10%",
          bottom: "30%",
          // 设置图例文字的样式
          formatter: function (name) {
            console.log(name, 99999999);
            let arr = ["{b|" + name + "}"];
            return arr.join(",");
          },
          textStyle: {
            //样式
            rich: {
              a: {
                fontSize: 10,
                color: "yellow",
              },
              // 设置图例的颜色和文字大小
              b: {
                // 图例文字大小
                fontSize: 10,
                // 图例文字颜色
                color: "red",
              },
            },
          },
        },
        series: [
          {
            minShowLabelAngle: 30,
            type: "pie",
            startAngle: 30,
            radius: ["50%", "70%"],
            center: ["40%", "50%"], // 设置图表的位置
            avoidLabelOverlap: false,
            itemStyle: {
              // 图表块周围的红色边
              // borderColor: "red",
              // 图表块周围的红色边宽度
              // borderWidth: 1,
            },
            // 引导线名称样式
            label: {
              formatter: "{b}  {c}",
              color: "#333",
            },
            // 引导线样式
            labelLine: {
              lineStyle: {
                color: "#dddddd",
              },
            },
            data: data,
          },
          {
            minShowLabelAngle: 5,
            type: "pie",
            center: ["40%", "50%"], // 设置图表的位置
            radius: ["40%", "40%"],
            hoverAnimation: false,
            label: {
              normal: {
                show: true,
                position: "center",
                color: "#333",
                formatter: "{total|" + sum + "}" + "\n\r" + `{active|${name}}`,
                // 总数字样式
                rich: {
                  total: {
                    fontSize: 26,
                    fontWeight: 600,
                    color: "yellow",
                  },
                  // 名称样式
                  active: {
                    fontSize: 14,
                    fontWeight: 400,
                    color: "#f73f62",
                    lineHeight: 30,
                  },
                },
              },
              emphasis: {
                //中间文字显示
                show: true,
              },
            },
            lableLine: {
              normal: {
                show: false,
              },
              emphasis: {
                show: true,
              },
              tooltip: {
                show: false,
              },
            },
            // 内部圈样式
            itemStyle: {
              color: "green",
              borderColor: "green",
              borderWidth: 1,
            },
            tooltip: {
              show: false,
            },
            cursor: "default",
            data: [{ value: 1, name: "1" }],
          },
        ],
      };
      this.chart.setOption(options);
    },
  },
};
</script>

在这里插入图片描述

7. 饼状图组件使用

<template>
  <div class="about">
    <div class="box-card">
      <div style="width:100%;height:100%">
        <pieChart :chartData="chartData" height="100%"></pieChart>
      </div>
    </div>
  </div>
</template>
<script>
// 引入饼图组件
import pieChart from "./components/pieChart.vue";  // 饼状图
export default {
  components: {
    pieChart, // 饼图组件
  },
  data() {
    return {
      chartData: {
        name: "识别总数", // 表名
        data: [], // 表数据
      },
    };
  },
  mounted(){
    // 调用接口
    this.getFaceData()
  },
  methods: {
    getFaceData() {
      // 此处应该调用接口
      // 暂时使用假数据
      this.chartData.data = [
        {
          name: "admin",
          value: 80,
        },
        {
          name: "lss",
          value: 106,
        },
        {
          name: "zbw",
          value: 50,
        },
        {
          name: "陌生人",
          value: 200,
        },{
          name: "admin1",
          value: 80,
        },
        {
          name: "lss1",
          value: 106,
        },
        {
          name: "zbw1",
          value: 50,
        },
        {
          name: "陌生人1",
          value: 200,
        },{
          name: "admin2",
          value: 80,
        },
        {
          name: "lss2",
          value: 106,
        },
        {
          name: "zbw2",
          value: 50,
        },
        {
          name: "陌生人2",
          value: 200,
        },{
          name: "admin3",
          value: 80,
        },
        {
          name: "lss3",
          value: 106,
        },
        {
          name: "zbw3",
          value: 50,
        },
        {
          name: "陌生人3",
          value: 200,
        },
      ];
    },
  },
};
</script>
<style lang="scss">
.box-card {
  width: 800px;
  height: 400px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin: 20px;
}
</style>

8. 折线图简单封装

  1. 新建 lineChart.vue

// lineChart.vue

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

<script>
import * as echarts from "echarts";
import resize from "@/echarts/mixins/resize";
export default {
  mixins: [resize],
  props: {
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "280px",
    },
    chartData: {
      type: Object,
      required: true,
    },
    echartsName: {
      type: String,
      default: "",
    },
    echartsUnit: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      chart: null,
      color: [
        "rgb(62, 255, 194)",
        "rgb(255, 195, 0)",
        "rgb(53, 136, 229)",
        "rgb(13, 235, 251)",
        "rgb(227, 59, 90)",
        "rgb(255, 147, 38)",
        "rgb(176, 210, 231)",
        "rgb(138, 92, 247)",
        "rgb(25, 120, 162)",
        "rgb(67, 207, 124)",
      ],
    };
  },
  watch: {
    // 监听表数据变化,重新初始化图表
    chartData: {
      deep: true,
      handler(val) {
        if (this.chart) {
          this.$nextTick(() => {
            this.initChart();
          });
        }
      },
    },
  },
  mounted() {
    // 初始化图表
    this.initChart();
  },
  beforeDestroy() {
    // 页面销毁时 销毁图表
    if (!this.chart) {
      return;
    }
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el);
      this.setOptions(this.chartData);
    },
    // 图表配置项
    setOptions(chartData) {
      let that = this;
      const name = chartData.name;
      const label = chartData.label;
      let series = [];
      let arr = Object.keys(chartData.data);
      arr.forEach((v, index) => {
        series.push({
          name: name[index],
          type: "line",
          symbol: "circle",
          symbolSize: 6,
          showSymbol: false,
          // 此处是折线图的颜色
          itemStyle: {
            color: that.color[index],
          },
          lineStyle: {
            color: that.color[index],
          },
          // 折线图内部区域的颜色
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 1, color: "rgba(0, 206, 218, 0.08)" },
              { offset: 0, color: that.color[index] },
            ]),
          },
          data: chartData.data[v],
        });
      });
      const options = {
        // 图例位置
        grid: {
          top: 50,
          left: 50,
          right: 60,
          bottom: 20,
          containLabel: true,
        },
        legend: {
          top: 8,
          data: name,
          textStyle: {
            color: "#333",
            fontSize: 12,
            lineHeight: 20,
          },
        },
        //  此处判断是否使用自定义 浮框
        tooltip: that.echartsName
          ? {
              trigger: "axis",
              axisPointer: {
                type: "line",
                lineStyle: {
                  color: "rgba(0, 206, 218, 1)",
                },
              },
              borderColor: "transparent",
              backgroundColor: "rgba(6,167,205,.9)",
              padding: 10,
              textStyle: {
                fontSize: 14,
                fontWeight: 400,
                color: "#fffafa",
              },
              // 自定义tip
              formatter: function (params) {
                var htmlStr = "<div>动环信息" + "<br/>";
                htmlStr += "名称:" + that.echartsName + "<br/>";
                htmlStr += "数值:" + params[0].value + "<br/>";
                htmlStr += "时间:" + params[0].name + "<br/>";
                htmlStr += "</div>";
                return htmlStr;
              },
            }
          : {
            // 默认tip
              trigger: "axis",
              axisPointer: {
                type: "line",
                lineStyle: {
                  color: "rgba(0, 206, 218, 1)",
                },
              },
              borderColor: "transparent",
              backgroundColor: "rgba(6,167,205,.9)",
              padding: 10,
              textStyle: {
                fontSize: 14,
                fontWeight: 400,
                color: "#fffafa",
              },
            },
       dataZoom: [
          {
            type: "inside",
            start: 20, //数据窗口范围的起始百分比。范围是:0 ~ 100。表示 0% ~ 100%。
            end: 100,
            xAxisIndex: 0, //设置控制xAxis
            // yAxisIndex: 0, //设置控制yAxis
            zoomOnMouseWheel: true, //设置鼠标滚轮不能触发缩放。
          },
        ],
        xAxis: [
          {
            type: "category",
            boundaryGap: false,
            showMinLabel: true,
            showMaxLabel: true,
            data: label,
            axisLabel: {
              // X 轴刻度样式
              textStyle: {
                color: "#333",
                fontSize: 12,
                fontWeight: 500,
              },
            },
            axisTick: {
              show: false,
            },
            axisLine: {
              show: false,
            },
          },
        ],
        yAxis: [
          {
            type: "value",
            minInterval: 1,
            //  Y轴刻度颜色
            axisLabel: {
              textStyle: {
                color: "#333",
                fontSize: 12,
                fontWeight: 400,
              },
            },
            // Y 轴刻度线
            splitLine: {
              lineStyle: {
                color: "#dddddd",
              },
            },
            axisLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            name: this.echartsUnit, // Y轴显示 单位
            nameTextStyle: {
              color: "#dddddd",
              padding: [0, 0, 12, 0],
            },
          },
        ],
        series: series,
      };
      this.chart.setOption(options);
    },
  },
};
</script>

9. 折线图组件使用
在这里插入图片描述

<template>
  <div class="about">
    <div class="box-card">
      <lineChart
        :chartData="chartData"
        :echartsName="echartsName"
        :echartsUnit="echartsUnit"
        :height="'calc(100% - 30px)'"
      ></lineChart>
    </div>
  </div>
</template>

<script>
import lineChart from "./components/lineChart.vue"; // 折线图
export default {
  components: { lineChart },
  data() {
    return {
      chartData: {
        name: [],
        label:[],
        data:{
          value:[],
          value1:[],
          // ..........
        }
      },
      echartsName: "", // 自定义名称
      echartsUnit: "", // 单位
    };
  },
  mounted() {
    // 调用接口
    this.getFaceData();
  },
  methods: {
    getFaceData() {
      // 一条线
      // 此处应该调用接口
      // 暂时使用假数据
      this.chartData.name = ['温度']
      this.echartsUnit = 'kg'  // 单位
      this.chartData.label = ["2023-11-29 16:00:37","2023-11-29 18:11:36","2023-11-29 19:04:15","2023-11-29 19:21:09","2023-11-29 19:35:39","2023-11-29 19:49:32","2023-11-30 15:38:58"]
      this.chartData.data.value = [24,13,36,11,18,28,8]
      // 多条线
      // this.chartData.name = ['温度','湿度']
      // this.chartData.data.value1 = [11,18,13,25,9,22,10]

    },
  },
};
</script>
<style lang="scss">
.box-card {
  width: 800px;
  height: 400px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 20px;
  margin: 20px;
}
</style>

10. 配置 element-resize-detector 公共方法

  1. List item
  2. 在echarts 文件夹下面新建 mixins 文件夹 然后 新建 resize.js
  3. resize.js 代码(可复制直接用)
// resize.js
import elementResizeDetectorMaker from "element-resize-detector";
import { debounce } from '@/utils/index'
export default {
  data() {
    return {
      $_sidebarElm: null,
      $_resizeHandler: null
    };
  },
  mounted() {
    var erd = elementResizeDetectorMaker();
    setTimeout(() => {
      if (this.chart) {
        erd.listenTo(this.chart._dom, ele => {
          debounce(() => {
            if(typeof this.getDomSizeFn === "function"){
              this.getDomSizeFn(ele);
            }
            if (this.chart && this.chart.resize) {
              this.chart.resize();
            }
          }, 100)();
        });
      }
    });
    this.$_resizeHandler = debounce(() => {
      if (this.chart && this.chart.resize) {
        this.chart.resize();
      }
    }, 100);
    this.$_initResizeEvent();
    this.$_initSidebarResizeEvent();
  },
  beforeDestroy() {
    this.$_destroyResizeEvent();
    this.$_destroySidebarResizeEvent();
  },
  // to fixed bug when cached by keep-alive
  // https://github.com/PanJiaChen/vue-element-admin/issues/2116
  activated() {
    this.$_initResizeEvent();
    this.$_initSidebarResizeEvent();
  },
  deactivated() {
    this.$_destroyResizeEvent();
    this.$_destroySidebarResizeEvent();
  },
  methods: {
    // use $_ for mixins properties
    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
    $_initResizeEvent() {
      window.addEventListener("resize", this.$_resizeHandler);
    },
    $_destroyResizeEvent() {
      window.removeEventListener("resize", this.$_resizeHandler);
    },
    $_sidebarResizeHandler(e) {
      if (e.propertyName === "width") {
        this.$_resizeHandler();
      }
    },
    $_initSidebarResizeEvent() {
      this.$_sidebarElm = document.getElementsByClassName(
        "sidebar-container"
      )[0];
      this.$_sidebarElm &&
        this.$_sidebarElm.addEventListener(
          "transitionend",
          this.$_sidebarResizeHandler
        );
    },
    $_destroySidebarResizeEvent() {
      this.$_sidebarElm &&
        this.$_sidebarElm.removeEventListener(
          "transitionend",
          this.$_sidebarResizeHandler
        );
    }
  }
};

  1. 在 utils 新建 index.js (可复制直接用)

// index.js

/**
 * @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) {
        result = func.apply(context, args)
        context = args = null
      }
      return result
    }
  }
  1. 以上为全部代码,请根据自身需求进行修改配置,完!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1290459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#网络应用程序(Web页面浏览器、局域网聊天程序)

目录 一、创建Web页面浏览器 1.示例源码 2.生成效果 二、局域网聊天程序 1.类 2.服务器端 3.客户端 一、创建Web页面浏览器 TextBox 控件用来输入要浏览的网页地址&#xff0c;Button控件用来执行浏览网页操作&#xff0c; WebBrowser控件用来显示要浏览的网页。这个控…

图像处理中的角点检测Python-OpenCV 中的实现

马丁亚当斯 (Martin Adams)在Unsplash上拍摄的照片 一、说明 在图像处理的背景下&#xff0c;“特征”可以直观地理解为图像中易于识别并用于表示图像的独特或独特的部分。将特征视为图像中使其可区分的“地标”或“焦点”。为了使这一点更具关联性&#xff0c;请考虑一下您如…

gitLab 和Idea分支合并

以下二选1即可完成分支合并建议第一种简单有效 Idea合并方式 切换到被合并的分支&#xff0c;如我想把0701的内容合并到dev&#xff0c;切换到dev分支&#xff0c;然后再点击merge然后选择要合并的分支&#xff0c;即可,此时git上的代码没有更新只是把代码合到本地需要pull才…

使用Java网络编程,窗口,线程,IO,内部类等实现多人在线聊天1.0

1.整体思路 思路图 整体思路如上: 涉及知识点:线程网络编程集合IO等 TCP 协议 2.代码实现过程 服务端 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import jav…

管理和监控CentOS上的HTTP服务

CentOS作为一款稳定的开源服务器操作系统&#xff0c;为各种网络服务提供了优秀的支持。其中&#xff0c;HTTP服务是互联网上最常用的服务之一&#xff0c;它为人们提供了便捷的信息访问和交互方式。在CentOS上管理和监控HTTP服务是一项重要的任务&#xff0c;下面我们将介绍一…

华为数通---BFD多跳检测示例

定义 双向转发检测BFD&#xff08;Bidirectional Forwarding Detection&#xff09;是一种全网统一的检测机制&#xff0c;用于快速检测、监控网络中链路或者IP路由的转发连通状况。 目的 为了减小设备故障对业务的影响&#xff0c;提高网络的可靠性&#xff0c;网络设备需要…

前端“量子纠缠”:multipleWindow3dScene 来了

最近前端实现的量子纠缠在网络上火了起来&#xff0c;作者bgstaal的推文&#xff1a;效果如下&#xff1a; 量子纠缠 那我们一起来看下什么是量子纠缠&#xff0c;以及前端是如何实现的。 什么是量子纠缠&#xff1f; 在量子力学里&#xff0c;当几个粒子在彼此相互作用后&…

【Java】实现顺序表基本的操作(数据结构)

文章目录 前言顺序表1、打印顺序表2、增加元素3、在任意位置增加元素4、判断是否包含某个元素5、查找某个元素对于的位置6、获取任意位置的元素7、将任意位置的元素设为value8、删除第一次出现的关键字9、获取顺序表长度10、清空顺序表总结 前言 在了解顺序表之前我们要先了解…

rust高级 异步编程 二 pin

文章目录 定海神针 Pin 和 Unpin为何需要 PinUnpin深入理解 PinPin 在实践中的运用固定到堆上将固定住的 Future 变为 Unpin总结 定海神针 Pin 和 Unpin 在 Rust 中&#xff0c;所有的类型可以分为两类: 类型的值可以在内存中安全地被移动&#xff0c;例如数值、字符串、布尔…

OpenCV图像相似性比对算法

背景 在做图像处理或者计算机视觉相关的项目的时候&#xff0c;很多时候需要我们对当前获得的图像和上一次的图像做相似性比对&#xff0c;从而找出当前图像针对上一次的图像的差异性和变化点&#xff0c;这需要用到OpenCV中的一些图像相似性和差异性的比对算法&#xff0c;在O…

华为数通---配置端口安全案例

端口安全简介 端口安全&#xff08;Port Security&#xff09;通过将接口学习到的动态MAC地址转换为安全MAC地址&#xff08;包括安全动态MAC、安全静态MAC和Sticky MAC&#xff09;&#xff0c;阻止非法用户通过本接口和交换机通信&#xff0c;从而增强设备的安全性。 组网需…

二百一十三、Flume——Flume拓扑结构介绍

一、目的 最近在看尚硅谷的Flume资料&#xff0c;看到拓扑结构这一块&#xff0c;觉得蛮有意思&#xff0c;于是整理一下Flume的4种拓扑结构 二、拓扑结构 &#xff08;一&#xff09;简单串联 1、结构含义 这种模式是将多个flume顺序连接起来了&#xff0c;从最初的sourc…

一键抠图|3个智能AI抠图软件实现抠图自由!

听说你对如何利用AI抠图技术去除白色背景感兴趣&#xff1f;设想一下&#xff0c;你有一张某人站在白色背景前的照片&#xff0c;而你只希望能留下这个人物。在过去&#xff0c;你可能需要花费大量时间和精力手动进行抠图。但现在&#xff0c;AI技术来拯救你了&#xff01;AI可…

计网实验7

解决&#xff1a;路由器用rip连接&#xff0c;主机通过域名访问&#xff0c;主机之间发送电子邮件 实验步骤 1.搞好部件 2.配好两台主机的ip,掩码&#xff0c;网关 3.连接一下两台主机&#xff0c;由于两台路由器没有连接&#xff0c;所以两台主机也无法连通&#xff0c;丢包率…

搭建个人网盘应用Nextcloud

使用DNF管理软件包 1 使用winscp工具将openeuler-20.03-LTS-x86_64-dvd.iso上传至openeuler虚拟机的/root目录下&#xff0c;然后执行如下命令挂载ISO [rootopenEuler ~]# mount -o loop /root/openEuler-20.03-LTS-everything-x86_64-dvd.iso /mnt/2 添加软件源 [rootope…

智能优化算法应用:基于社交网络算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于社交网络算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于社交网络算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.社交网络算法4.实验参数设定5.算法结果6.参考…

ChatGPT,作为一种强大的自然语言处理模型,具备显著优势,能够帮助您在各个领域取得突破

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

vue2+typescript使用高德地图2.0版本

高德地图 webjs api 2.0官网教程 AMap.Driving使用说明 <div class"mmp"><div id"map" ref"mapcontainer"></div></div><script lang"ts"> //安全密钥 window._AMapSecurityConfig{securityJsCode: &qu…

【南京站-EI会议征稿中】第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024)

第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&#xff09; 2024 3rd International Conference on Cyber Security, Artificial Intelligence and Digital Economy 第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&…

〖大前端 - 基础入门三大核心之JS篇㊼〗- BOM基础之window对象

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…