Echarts 技术学习指南:从入门到精通

引言

Echarts 是一款由百度公司推出的强大且高度可定制化的 JavaScript 数据可视化库,广泛应用于各种 Web 开发场景中,它能帮助开发者快速构建出丰富多样、交互性强的图表应用。本文旨在为初学者及进阶开发者提供一份详尽的 Echarts 学习路径和技术要点,助您全面掌握 Echarts 的核心功能与高级特性。

一、图表初始化与配置

1. 图表初始化

图表的初始化是创建一个 ECharts 实例并将其绑定到 HTML 容器元素上的过程。首先,你需要在 HTML 页面中引入 ECharts 的 JS 文件,然后通过 echarts.init() 方法来创建一个 ECharts 实例。
以下是一个简单的示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts 示例</title>
    <!-- 引入 ECharts 的 JS 文件 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js"></script>
</head>
<body>
    <!-- 创建图表容器 -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
        // 创建 ECharts 实例并绑定到容器
        var myChart = echarts.init(document.getElementById('main'));
    </script>
</body>
</html>

在上面的示例中,我们首先在 <head> 标签中引入了 ECharts 的 JS 文件,然后创建了一个 div 容器,并给它指定了一个 ID(main)。接着,在 <script> 标签中创建了一个名为 myChart 的 ECharts 实例,并将它绑定到了具有 main ID 的容器上。


2. 图表配置

图表配置是指通过 JavaScript 对象或 JSON 格式的配置项来设置图表的样式、数据、交互行为等方面的内容。图表配置项可以分为全局配置项和系列配置项。


2.1 全局配置项

全局配置项是对整个图表生效的设置,例如标题、图例、数据区域缩放、网格线、X/Y 轴等。以下是一个包含全局配置项的示例代码:

var option = {
    title: {
        text: '示例图表'
    },
    legend: {
        data: ['数据序列1', '数据序列2']
    },
    dataZoom: {
        show: true,
        start: 0,
        end: 100
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        name: '数据序列1',
        type: 'bar',
        data: [820, 932, 901, 934, 1290, 1330, 1320]
    }, {
        name: '数据序列2',
        type: 'line',
        smooth: true,
        data: [230, 150, 901, 340, 1290, 1330, 1320]
    }]
};

myChart.setOption(option);

在上面的示例中,我们定义了一个名为 option 的 JavaScript 对象,它包含了图表的全局配置项。然后,我们通过 myChart.setOption(option) 将这个配置项应用到 ECharts 实例上。


2.2 系列配置项

系列配置项是对图表中每个数据序列的单独设置,例如颜色、样式、动画等。在上面的示例代码中,series 属性就是一个系列配置项,它包含了两个数据序列的配置。

series: [{
    name: '数据序列1',
    type: 'bar',
    color: '#1f77b4',
    data: [820, 932, 901, 934, 1290, 1330, 1320]
}, {
    name: '数据序列2',
    type: 'line',
    smooth: true,
    color: '#ff7f0e',
    data: [230, 150, 901, 340, 1290, 1330, 1320]
}]

在上面的示例中,我们为每个数据序列设置了名称(name)、类型(type)、颜色(color)和数据(data)等属性。

二、数据处理

ECharts 中的数据处理主要包括数据的格式化、过滤、聚合等操作,以确保数据能够正确地映射到图表的不同部分。ECharts 支持多种数据格式,但通常要求数据以某种结构化形式呈现,以便于图表理解和解析。
以下是一个基础的数据处理示例,展示如何将数据格式化为 ECharts 可接受的格式,然后将其应用到柱状图:

// 原始数据,假设是从数据库或其他来源获取的数据
var raw_data = [
  { day: 'Mon', value1: 120, value2: 220 },
  { day: 'Tue', value1: 132, value2: 182 },
  { day: 'Wed', value1: 101, value2: 191 },
  { day: 'Thu', value1: 134, value2: 234 },
  { day: 'Fri', value1: 90, value2: 290 },
  { day: 'Sat', value1: 230, value2: 330 },
  { day: 'Sun', value1: 210, value2: 310 }
];

// 将原始数据转化为 ECharts 的 series 数据格式
var formatted_data = [
  {
    name: '数据序列1',
    type: 'bar',
    data: raw_data.map(item => item.value1)
  },
  {
    name: '数据序列2',
    type: 'bar',
    data: raw_data.map(item => item.value2)
  }
];

// 初始化 ECharts 实例
var myChart = echarts.init(document.getElementById('main'));

// 设置 ECharts 的选项
var option = {
  xAxis: {
    type: 'category',
    data: raw_data.map(item => item.day)
  },
  yAxis: {
    type: 'value'
  },
  series: formatted_data
};

// 将配置项应用到图表实例
myChart.setOption(option);

在上述示例中:

  1. 我们有原始数据 raw_data,它是一个对象数组,其中每个对象代表一天的数据,包含日期(day)和两个值(value1 和 value2)。
  2. 我们将原始数据转换为 ECharts 需要的 series 数据格式。这里我们有两个数据序列,分别对应 value1 和 value2 的值,它们都是独立的柱形图序列。
  3. 在 option 对象中,我们设置了 xAxis 类型为 category,并将 data 设置为原始数据中日期列表;yAxis 类型为 value 表示这是数值轴。
  4. series 部分的数据直接来自于前面转化后的 formatted_data,这已经是我们需要的 ECharts 数据格式。
  5. 最后,将配置好的 option 应用到已初始化的 ECharts 实例 myChart 上。

三、坐标系与多轴系统

ECharts 支持单轴和多轴系统,这意味着在同一图表内可以同时显示多个相互独立的坐标轴。这对于对比分析多维度的数据非常有用。下面我们将通过代码示例详细讲解 ECharts 中的坐标系配置及其多轴系统的应用。


基础坐标轴配置

单个坐标轴的基本配置如下:

option = {
    xAxis: {
        type: 'category', // 类别轴(适用于离散的类别数据)
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], // X轴标签
    },
    yAxis: {
        type: 'value', // 数值轴(适用于连续的数值数据)
        min: 0, // 设置最小值
        max: 300, // 设置最大值
        splitLine: { // 分割线配置
            show: true
        }
    },
    series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320], // 数据序列
        type: 'bar', // 柱状图
    }]
};

多轴系统示例

在 ECharts 中,我们可以配置多个 X 轴和 Y 轴,以展示不同的数据系列。以下是一个包含两个 Y 轴的柱状图示例:

option = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },

    yAxis: [
        {
            type: 'value',
            name: '销售额(元)',
            position: 'left', // 左侧Y轴,默认为左侧
            min: 0,
            max: 2000,
            axisLabel: {
                formatter: '{value} 元'
            }
        },
        {
            type: 'value',
            name: '客户数',
            position: 'right', // 右侧Y轴
            min: 0,
            max: 100,
            axisLabel: {
                formatter: '{value} 人'
            }
        }
    ],

    series: [
        {
            name: '销售额',
            type: 'bar',
            yAxisIndex: 0, // 使用左侧的Y轴
            data: [820, 932, 901, 934, 1290, 1330, 1320]
        },
        {
            name: '客户数',
            type: 'bar',
            yAxisIndex: 1, // 使用右侧的Y轴
            data: [10, 20, 30, 40, 50, 60, 70]
        }
    ]
};

在上述示例中:

  • 我们设置了两个 yAxis,每个都有自己的名称、位置(左侧或右侧)和范围限制。
  • yAxisIndex 属性在 series 中指定使用的 Y 轴索引,0 代表左轴,1 代表右轴。
  • 两个数据序列分别关联到不同的 Y 轴,这样可以在一张图表上对比展示两种不同单位的数据。

四、交互性与事件监听

ECharts 提供了丰富的交互性和事件监听机制,允许开发者通过监听图表的各种事件,以实现诸如数据更新、跳转、提示框显示等功能。以下是一个关于 ECharts 事件监听的基本示例,详细说明如下:


示例:监听图表点击事件

// 初始化 ECharts 实例
var myChart = echarts.init(document.getElementById('main'));

// 配置图表选项
var option = {
  // ... 其他配置项省略
  series: [{
    // ... 系列配置项省略
  }]
};

// 将配置应用到图表
myChart.setOption(option);

// 添加点击事件监听器
myChart.on('click', function (params) {
  console.log('图表被点击,点击的系列和数据信息:', params);

  // 根据点击的参数执行相应操作,例如:
  if (params.seriesIndex > -1 && params.dataIndex > -1) {
    // 用户点击了某个数据项
    var clickedData = option.series[params.seriesIndex].data[params.dataIndex];
    alert('您点击了数据项:' + clickedData.name + ',值为:' + clickedData.value);
  } else if (params.componentType === 'series') {
    // 用户点击了空白区域或者其他非数据点的部分
    console.log('用户点击了图表的空缺部分或系列区域');
  } else if (params.componentType === 'toolbox') {
    // 用户点击了工具箱内的按钮
    console.log('用户点击了工具箱按钮');
  } else {
    // 其他组件的点击事件
    console.log('用户点击了其它组件:', params.componentType);
  }
});

在上面的示例中:

  • 首先,我们初始化了一个 ECharts 实例并设置了基本的图表选项。
  • 接着,我们通过 myChart.on('click', callback) 方法添加了一个点击事件监听器。当用户点击图表时,回调函数会被触发。
  • 回调函数接收一个 params 参数,这个参数对象包含了关于点击事件的详细信息,如系列索引(seriesIndex)、数据索引(dataIndex)、组件类型(componentType)等。
  • 根据 params 的内容,我们可以判断用户点击的具体位置和内容,并执行相应的逻辑。

五、定制样式与主题

ECharts 提供了丰富的定制样式和主题功能,可以让开发者根据自己的需求和品牌风格自定义图表的样式和颜色。下面将分别介绍如何定制样式和主题。

定制样式

ECharts 的样式可以通过设置 option 中的 grid、axis、series 等属性来自定义。以下是一些常见的样式定制示例:

定制图表边框和背景色

option = {
  grid: {
    show: true, // 显示 grid 区域
    borderWidth: 1, // 边框宽度
    borderColor: '#ccc', // 边框颜色
    backgroundColor: '#f3f3f3', // 背景颜色
    containLabel: true // 包含图例
  },
  // ... 其他配置项
};

定制坐标轴样式

option = {
  xAxis: {
    type: 'category',
    data: ['A', 'B', 'C', 'D'],
    axisLine: {
      lineStyle: {
        color: '#333', // 设置坐标轴颜色
        width: 2, // 设置坐标轴线宽度
        type: 'dashed' // 设置坐标轴线类型为虚线
      }
    },
    axisLabel: {
      color: '#666', // 设置坐标轴标签颜色
      fontSize: 12, // 设置坐标轴标签字体大小
      fontWeight: 'bold' // 设置坐标轴标签加粗
    }
  },
  yAxis: {
    type: 'value',
    axisLine: {
      show: false // 隐藏坐标轴线
    },
    axisLabel: {
      formatter: '{value} %', // 标签格式化模板
      color: '#333',
      fontSize: 14,
      fontWeight: 'normal'
    }
  },
  // ... 其他配置项
};

定制系列样式

option = {
  series: [
    {
      name: 'Series 1',
      type: 'bar',
      data: [1, 2, 3, 4],
      itemStyle: {
        color: 'red', // 设置单个系列颜色
        barWidth: 30, // 设置柱状图宽度
        barGap: '30%', // 设置柱状图之间间距
        emphasis: {
          color: 'blue' // 设置高亮状态下颜色
        }
      }
    },
    {
      name: 'Series 2',
      type: 'bar',
      data: [5, 6, 7, 8],
      itemStyle: {
        color: ['#ffcc00', '#ff9900', '#ff6600', '#ff3300'], // 设置多个颜色
        barWidth: 20,
        barGap: 0,
        emphasis: {
          color: '#0099ff'
        }
      }
    }
  ]
};

定制主题

ECharts 提供了多种内置的主题,同时也支持自定义主题。下面分别介绍如何使用内置主题和自定义主题。


使用内置主题

ECharts 内置了多种主题,可以通过设置 option 中的 theme 属性来应用不同的主题,例如:

option = {
  theme: 'dark', // 应用 dark 主题
  // ... 其他配置项
};

自定义主题

如果内置的主题不能满足需求,可以通过自定义主题来实现。自定义主题可以通过定义 myTheme 对象来实现,然后通过 setTheme 方法应用到 ECharts 实例中。以下是一个自定义主题的示例:

// 定义自定义主题
var myTheme = {
  color: ['#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'],
  title: {
    itemGap: 8,
    textStyle: {
      fontWeight: 'bold',
      color: '#fff',
      fontSize: 16
    }
  },
  tooltip: {
    axisPointer: {
      lineStyle: {
        color: ['#ccc'],
        width: 1
      },
      crossStyle: {
        color: ['#ccc'],
        width: 1
      }
    }
  },
  legend: {
    textStyle: {
      color: '#fff'
    }
  },
  toolbox: {
    iconStyle: {
      color: ['#bbb']
    }
  },
  dataZoom: {
    brushStyle: {
      color: ['#2f4554', '#61a0a8', '#d48265', '#91c7ae'].map(function (color) {
        return color + '20';
      })
    }
  },
  timeline: {
    lineStyle: {
      color: ['#2f4554']
    },
    controlStyle: {
      itemColor: '#2f4554',
      itemHoverColor: '#444',
      itemGap: 20
    }
  },
  xAxis: {
    axisLine: {
      lineStyle: {
        color: ['#ccc']
      }
    },
    axisTick: {
      show: false
    },
    axisLabel: {
      textStyle: {
        color: '#fff'
      }
    },
    splitLine: {
      lineStyle: {
        color: ['#2f4554'],
        type: 'dashed'
      }
    },
    splitArea: {
      show: true,
      areaStyle: {
        color: ['rgba(255,255,255,0.05)', 'rgba(0,0,0,0.02)']
      }
    }
  },
  yAxis: {
    axisLine: {
      lineStyle: {
        color: ['#ccc']
      }
    },
    axisTick: {
      show: false
    },
    axisLabel: {
      textStyle: {
        color: '#fff'
      }
    },
    splitLine: {
      lineStyle: {
        color: ['#2f4554'],
        type: 'dashed'
      }
    },
    splitArea: {
      show: true,
      areaStyle: {
        color: ['rgba(255,255,255,0.05)', 'rgba(0,0,0,0.02)']
      }
    }
  },
  series: {
    label: {
      normal: {
        textStyle: {
          color: '#fff'
        }
      }
    },
    markPoint: {
      label: {
        normal: {
          textStyle: {
            color: '#fff'
          }
        }
      }
    },
    markLine: {
      label: {
        normal: {
          textStyle: {
            color: '#fff'
          }
        }
      }
    }
  }
};

// 应用自定义主题
myChart.setTheme(myTheme);

六、扩展与插件

ECharts 提供了强大的扩展机制,允许开发者基于其核心功能创建自定义插件来增强图表的功能。以下是关于如何使用 ECharts 插件的一个简单示例以及详细讲解:


示例:使用 Kforce.js 扩展力导向布局图

由于 ECharts 本身并未内置力导向布局,开发者可以引入第三方扩展插件,比如 Kforce.js,来实现力导向图的效果。虽然没有具体的 Kforce.js 插件代码示例,但可以简述其大致使用方法:

// 引入 ECharts 主体库
import * as echarts from 'echarts';

// 引入 Kforce.js 扩展插件(此处假设已经下载并引用该插件)
import Kforce from 'path/to/kforce.js';

// 初始化 ECharts 图表实例
const chart = echarts.init(document.getElementById('chart-container'));

// 创建图表的基础配置
const option = {
  // 基本图表配置...
  // 注意,对于力导向图的特殊配置将会在Kforce插件中设定
};

// 加载 Kforce 插件并设置力导向布局
echarts.use(Kforce); // 注册插件
option.plugins = [new Kforce(/* 插件配置 */)];

// 将配置应用到图表实例
chart.setOption(option);

// 在 Kforce 插件内部可能会通过修改option中的layout属性来进行力导向布局计算
// 并且可能会提供额外的方法来动态调整布局参数等

详细讲解:

  1. 引入扩展插件:首先需要将所需的扩展插件引入到项目中。插件通常是一个JS文件,它可以是全局加载,也可以是模块化加载(如CommonJS或ES6模块方式)。
  2. 注册插件:使用 echarts.use() 方法注册插件,这样ECharts就可以识别并使用新插件提供的功能。
  3. 配置插件:在 option 对象中,根据插件的文档指导,通常会在 plugins 属性下配置插件实例,传入必要的参数。
  4. 应用插件:将包含插件配置的 option 应用到 ECharts 实例上,此时图表会结合插件的功能进行渲染。

七、响应式设计与移动端适配

ECharts 提供了响应式设计的支持,使其能够在不同尺寸的屏幕,特别是移动端设备上很好地展示图表。为了使 ECharts 图表能够自适应屏幕大小,你需要监听窗口变化并调用 ECharts 实例的 resize 方法重新计算和绘制图表。以下是一个使用 Vue.js 结合 ECharts 实现响应式设计的示例:

<template>
  <div id="chart-container" ref="chartRef"></div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  data() {
    return {
      chartInstance: null,
    };
  },
  mounted() {
    this.initChart();
    window.addEventListener('resize', this.resizeChart, { passive: true });
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChart);
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
  },
  methods: {
    initChart() {
      const chartDom = this.$refs.chartRef;
      this.chartInstance = echarts.init(chartDom);
      
      // 设置初始的图表配置
      const option = {/* 你的图表配置 */};
      this.chartInstance.setOption(option);
    },
    resizeChart() {
      if (this.chartInstance) {
        this.chartInstance.resize();
      }
    },
  },
};
</script>

<style scoped>
#chart-container {
  width: 100%;
  height: 400px; /* 可根据需求设置固定高度或采用相对单位 */
}
</style>

在这个示例中:

  1. 我们在 Vue 组件的模板中创建一个具有 ref 属性的 div,它将作为 ECharts 图表的容器。
  2. 在 mounted 生命周期钩子中,我们初始化图表实例,并监听窗口的 resize 事件。当窗口尺寸发生变化时,调用 resizeChart 方法。
  3. resizeChart 方法中,我们调用了 ECharts 实例的 resize 方法,此方法会根据当前容器的实际尺寸重新计算和绘制图表。
  4. 当组件销毁时,我们移除 resize 事件监听器,并调用 dispose 方法清理图表资源。
  5. CSS 中设置图表容器的宽度为100%,确保它能随着父元素的变化而变化,高度可以设为固定像素值,也可以根据实际情况使用相对单位(如 vh 或 vw)来实现完全自适应。

八、国际化支持

ECharts 提供了国际化的支持,允许开发者为图表中的文字元素如标题、图例、提示框等配置不同语言的文本。下面是一个 ECharts 国际化配置的代码示例及详细讲解:

// 引入 ECharts 及国际化相关文件
import * as echarts from 'echarts';
import 'echarts/dist/extension/bmap.min';
import 'echarts/dist/extension/dataTool.min';
import 'echarts/locale/zh-CN'; // 引入中文语言包

// 初始化 ECharts 实例
let chart = echarts.init(document.getElementById('main'), 'macarons');

// 设置图表的默认语言为中文
echarts.locale(echarts.locale.zhCN);

// 配置图表选项,注意这里的提示框和图例等元素会自动使用当前语言环境的文本
let option = {
  title: {
    text: '折线图'
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['销量']
  },
  xAxis: {
    type: 'category',
    data: ['一月', '二月', '三月', '四月', '五月', '六月']
  },
  yAxis: {
    type: 'value'
  },
  series: [{
    name: '销量',
    type: 'line',
    data: [120, 132, 101, 134, 90, 230]
  }]
};

// 将配置应用到图表
chart.setOption(option);

在上述代码中:

  • 首先,通过 echarts.locale(echarts.locale.zhCN); 设置 ECharts 的默认语言环境为中文,这里的 echarts.locale.zhCN 是 ECharts 中预定义好的中文语言包。
  • 在配置 option 时,无需为标题、提示框、图例等元素单独设置语言,因为它们会自动根据当前的语言环境展示对应的语言文本。

如果你想在运行时动态切换语言,可以按需引入其他语言包,并再次调用 echarts.locale() 方法:

import 'echarts/locale/en-US'; // 引入英语语言包

// 切换至英语环境
echarts.locale(echarts.locale.enUS);

// 如果需要更新图表内容以反映新的语言设置,可以重新设置选项并调用 setOption 方法
chart.setOption(option);

九、性能优化

ECharts 性能优化主要涉及到减少不必要的计算、合理管理内存、控制数据传输量以及利用 ECharts 内置的优化功能等方面。以下是一些关键的性能优化策略及其代码示例:

1. 动态更新数据时使用 setData 和 setOption 的合理选择

  • 当仅需要更新图表数据时,使用 setOption 方法并只更新 series.data 更高效,避免整体刷新图表配置。
// 不推荐的整体刷新
chartInstance.setOption({
  series: [{
    data: newDataArray
  }]
});

// 推荐的局部更新
chartInstance.setOption({
  series: [{
    id: 'mySeriesId', // 必须要有唯一ID用于更新
    data: newDataArray
  }]
}, true); // 第二个参数为true,表示合并而非替换现有option

2. 使用 echarts.getInstanceByDom 减少重复实例化

  • 当页面中有多个图表时,复用已存在的实例而不是每次都重新实例化。
let chartElement = document.getElementById('chartContainer');
if (!echarts.getInstanceByDom(chartElement)) {
  let chartInstance = echarts.init(chartElement);
  // 设置配置项...
} else {
  let chartInstance = echarts.getInstanceByDom(chartElement);
  // 更新数据或配置...
}

3. 数据预处理和懒加载

  • 对于大数据量,可以考虑分段加载或者滚屏加载数据,降低一次性渲染的数据量。
// 滚动加载数据示例
let totalData = []; // 存储所有数据
let displayedData = []; // 存储当前显示的数据段
let currentIndex = 0;

function updateChartData() {
  displayedData = totalData.slice(currentIndex, currentIndex + displayLimit);
  chartInstance.setOption({
    series: [{
      data: displayedData
    }]
  });

  // 触发滚动或其他条件时,更新currentIndex
  currentIndex += displayLimit;
}

// 初始化时加载一部分数据
updateChartData();

4. 清理不需要的实例和资源

  • 当图表不再需要时,释放其所占有的资源。
// 在 Vue 生命周期卸载阶段或在页面离开时清理实例
beforeDestroy() {
  if (this.echartsInstance) {
    this.echartsInstance.dispose();
    this.echartsInstance = null;
  }
}

5. 开启图形渐进式渲染

  • 对于大型图表,尤其是地理坐标系上的大规模点图,可以开启渐进式渲染提高性能。
option = {
  progressive: true, // 开启渐进式渲染
  series: [{
    type: 'scatter',
    large: true, // 对大量数据开启高性能模式
    data: largeDataArray
  }]
};

6. 合理配置动画和交互

  • 根据实际需求适当关闭不需要的动画效果和不必要的交互功能,如鼠标悬停提示等。
option = {
  animation: false, // 关闭全局动画
  tooltip: {
    triggerOn: 'none' // 关闭默认的提示框触发行为
  },
  series: [{
    animationDurationUpdate: 0, // 关闭该系列的更新动画
    silent: true // 关闭该系列的默认交互(如点击、hover等)
  }]
};

总结

掌握 Echarts 技术不仅要求扎实的基础知识,更需要结合实际应用场景深入探索和实践。希望这份指南能为您的 Echarts 学习之旅提供清晰的方向和实用的指导,祝您早日成为 Echarts 高手!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码快撩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值