在这里插入图片描述

一、核心知识点:二维码生成工具完整核心用法

1. 用到的纯原生组件与API

本工具使用 React Native 原生组件结合在线二维码生成API实现二维码生成,无任何第三方库依赖,通过调用免费的二维码生成服务获取真实可扫描的二维码图像:

核心组件/API 作用说明 鸿蒙适配特性
Image React Native 原生图片组件,显示二维码图像 ✅ 鸿蒙端图片加载正常,支持网络图片
View 核心容器组件,实现组件布局、内容容器、样式容器等 ✅ 鸿蒙端布局无报错,布局精确、圆角、边框、背景色属性完美生效
Text 显示二维码内容、提示信息等,支持多行文本、不同颜色状态 ✅ 鸿蒙端文字排版精致,字号、颜色、行高均无适配异常
StyleSheet 原生样式管理,编写鸿蒙端最佳的二维码生成样式,无任何不兼容CSS属性 ✅ 符合鸿蒙官方视觉设计规范,颜色、圆角、边框、间距均为真机实测最优
useState React 原生钩子,管理二维码状态、输入值等核心数据,控制实时更新、状态切换 ✅ 响应式更新无延迟,状态切换流畅无卡顿,二维码生成实时显示

2. 二维码生成API

使用原生react-native-qrcode的方式没搞定,一直报错,换了个方式直接生成。

使用免费的在线二维码生成API,无需任何配置即可使用:

  • API地址https://api.qrserver.com/v1/create-qr-code/
  • 支持参数
    • data: 二维码内容(必需)
    • size: 二维码尺寸(默认 150x150)
    • color: 前景色(默认 000000)
    • bgcolor: 背景色(默认 FFFFFF)

核心要点:

  • 无需注册,免费使用
  • 支持自定义尺寸和颜色
  • 生成真实可扫描的二维码
  • 鸿蒙端图片加载正常

二、实战核心代码解析

1. 二维码URL构建

构建二维码生成API的URL。

// 构建二维码URL
const buildQRCodeURL = (
  data: string,
  size: number = 200,
  fgColor: string = '000000',
  bgColor: string = 'FFFFFF'
): string => {
  const encodedData = encodeURIComponent(data);
  return `https://api.qrserver.com/v1/create-qr-code/?data=${encodedData}&size=${size}x${size}&color=${fgColor}&bgcolor=${bgColor}`;
};

核心要点:

  • 使用 encodeURIComponent 编码数据
  • 支持自定义尺寸、前景色、背景色
  • 返回完整的API URL
  • 鸿蒙端URL构建正常

2. 二维码数据验证

实现二维码数据验证功能。

// 验证二维码数据
const validateQRData = (data: string): { valid: boolean; message: string } => {
  if (!data || data.trim() === '') {
    return { valid: false, message: '二维码内容不能为空' };
  }
  
  if (data.length > 2953) {
    return { valid: false, message: '二维码内容过长,最多支持2953个字符' };
  }
  
  return { valid: true, message: '数据验证通过' };
};

核心要点:

  • 验证数据是否为空
  • 验证数据长度限制
  • 提供详细的错误信息
  • 鸿蒙端数据验证正常

3. 颜色值转换

实现颜色值转换功能。

// 转换颜色值为API格式
const convertColorToAPI = (color: string): string => {
  // 移除 # 号
  let hex = color.replace('#', '');
  
  // 如果是简写形式(如 #000),转换为完整形式
  if (hex.length === 3) {
    hex = hex.split('').map(c => c + c).join('');
  }
  
  // 如果是颜色名称,转换为十六进制
  const colorMap: Record<string, string> = {
    'black': '000000',
    'white': 'FFFFFF',
    'red': 'FF0000',
    'blue': '0000FF',
    'green': '00FF00',
  };
  
  if (colorMap[hex.toLowerCase()]) {
    return colorMap[hex.toLowerCase()];
  }
  
  return hex.toUpperCase();
};

核心要点:

  • 支持十六进制颜色值
  • 支持颜色名称
  • 统一转换为6位十六进制
  • 鸿蒙端颜色转换正常

三、实战完整版:企业级通用二维码生成工具组件

import React, { useState, useCallback, useMemo } from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  ScrollView,
  SafeAreaView,
  TextInput,
  Alert,
  Image,
} from 'react-native';

// 构建二维码URL
const buildQRCodeURL = (
  data: string,
  size: number = 200,
  fgColor: string = '000000',
  bgColor: string = 'FFFFFF'
): string => {
  const encodedData = encodeURIComponent(data);
  return `https://api.qrserver.com/v1/create-qr-code/?data=${encodedData}&size=${size}x${size}&color=${fgColor}&bgcolor=${bgColor}`;
};

// 验证二维码数据
const validateQRData = (data: string): { valid: boolean; message: string } => {
  if (!data || data.trim() === '') {
    return { valid: false, message: '二维码内容不能为空' };
  }
  
  if (data.length > 2953) {
    return { valid: false, message: '二维码内容过长,最多支持2953个字符' };
  }
  
  return { valid: true, message: '数据验证通过' };
};

// 转换颜色值为API格式
const convertColorToAPI = (color: string): string => {
  let hex = color.replace('#', '');
  
  if (hex.length === 3) {
    hex = hex.split('').map(c => c + c).join('');
  }
  
  const colorMap: Record<string, string> = {
    'black': '000000',
    'white': 'FFFFFF',
    'red': 'FF0000',
    'blue': '0000FF',
    'green': '00FF00',
  };
  
  if (colorMap[hex.toLowerCase()]) {
    return colorMap[hex.toLowerCase()];
  }
  
  return hex.toUpperCase();
};

const QRCodeGeneratorTool = () => {
  const [qrData, setQrData] = useState<string>('https://example.com');
  const [qrSize, setQrSize] = useState<string>('200');
  const [qrColor, setQrColor] = useState<string>('black');
  const [bgColor, setBgColor] = useState<string>('white');
  const [showQR, setShowQR] = useState<boolean>(false);

  // 生成二维码URL
  const qrCodeURL = useMemo(() => {
    if (!showQR) return null;
    
    const validation = validateQRData(qrData);
    if (!validation.valid) return null;
    
    const size = parseInt(qrSize) || 200;
    const validSize = Math.min(Math.max(size, 100), 500);
    const fgColor = convertColorToAPI(qrColor);
    const bgColorApi = convertColorToAPI(bgColor);
    
    return buildQRCodeURL(qrData, validSize, fgColor, bgColorApi);
  }, [showQR, qrData, qrSize, qrColor, bgColor]);

  // 生成二维码
  const handleGenerate = useCallback(() => {
    const validation = validateQRData(qrData);
    
    if (!validation.valid) {
      Alert.alert('提示', validation.message);
      return;
    }

    setShowQR(true);
  }, [qrData]);

  // 重置二维码
  const handleReset = useCallback(() => {
    setShowQR(false);
    setQrData('https://example.com');
    setQrSize('200');
    setQrColor('black');
    setBgColor('white');
  }, []);

  // 保存二维码提示
  const handleSave = useCallback(() => {
    Alert.alert('提示', '二维码已生成,可使用截图功能保存');
  }, []);

  const size = parseInt(qrSize) || 200;
  const validSize = Math.min(Math.max(size, 100), 500);

  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.scrollView} contentContainerStyle={styles.scrollContent}>
        {/* 二维码内容输入 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>二维码内容</Text>
          <View style={styles.card}>
            <TextInput
              style={[styles.input, styles.textArea]}
              value={qrData}
              onChangeText={setQrData}
              placeholder="输入要生成二维码的内容(网址、文本等)"
              multiline
              numberOfLines={4}
              maxLength={2953}
            />
            <Text style={styles.charCount}>{qrData.length}/2953</Text>
          </View>
        </View>

        {/* 二维码设置 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>二维码设置</Text>
          <View style={styles.card}>
            <Text style={styles.label}>尺寸(100-500</Text>
            <TextInput
              style={styles.input}
              value={qrSize}
              onChangeText={setQrSize}
              placeholder="输入尺寸(100-500)"
              keyboardType="number-pad"
            />
            
            <Text style={styles.label}>前景色</Text>
            <TextInput
              style={styles.input}
              value={qrColor}
              onChangeText={setQrColor}
              placeholder="输入颜色(如:black、#000000)"
            />
            
            <Text style={styles.label}>背景色</Text>
            <TextInput
              style={styles.input}
              value={bgColor}
              onChangeText={setBgColor}
              placeholder="输入颜色(如:white、#FFFFFF)"
            />
          </View>
        </View>

        {/* 操作按钮 */}
        <View style={styles.buttonContainer}>
          <TouchableOpacity style={styles.button} onPress={handleGenerate}>
            <Text style={styles.buttonText}>生成二维码</Text>
          </TouchableOpacity>
          <TouchableOpacity style={[styles.button, styles.resetButton]} onPress={handleReset}>
            <Text style={styles.buttonText}>重置</Text>
          </TouchableOpacity>
        </View>

        {/* 二维码预览 */}
        {showQR && qrCodeURL && (
          <View style={styles.section}>
            <Text style={styles.sectionTitle}>二维码预览</Text>
            <View style={styles.qrContainer}>
              <View style={styles.qrWrapper}>
                <Image
                  source={{ uri: qrCodeURL }}
                  style={{ width: validSize, height: validSize }}
                  resizeMode="contain"
                />
              </View>
              <Text style={styles.qrInfo}>尺寸: {validSize}x{validSize}</Text>
              <Text style={styles.qrInfo}>内容: {qrData}</Text>
            </View>
            <TouchableOpacity style={[styles.button, styles.saveButton]} onPress={handleSave}>
              <Text style={styles.buttonText}>保存二维码</Text>
            </TouchableOpacity>
          </View>
        )}

        {/* 使用说明 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>使用说明</Text>
          <View style={styles.instructionCard}>
            <Text style={styles.instructionText}>
              • 输入要生成二维码的内容(网址、文本等)
            </Text>
            <Text style={styles.instructionText}>
              • 设置二维码的尺寸和颜色
            </Text>
            <Text style={styles.instructionText}>
              • 点击生成按钮创建真实可扫描的二维码
            </Text>
            <Text style={styles.instructionText}>
              • 支持网址、文本、联系方式等多种内容
            </Text>
          </View>
        </View>

        {/* 技术说明 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>技术说明</Text>
          <View style={styles.instructionCard}>
            <Text style={styles.instructionText}>
              • 使用在线二维码生成API(api.qrserver.com)
            </Text>
            <Text style={styles.instructionText}>
              • 无需任何第三方库,纯原生实现
            </Text>
            <Text style={styles.instructionText}>
              • 使用 Image 组件加载二维码图片
            </Text>
            <Text style={styles.instructionText}>
              • 生成真实可扫描的二维码
            </Text>
          </View>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5F7FA',
  },
  scrollView: {
    flex: 1,
  },
  scrollContent: {
    padding: 20,
  },
  section: {
    marginBottom: 24,
  },
  sectionTitle: {
    fontSize: 18,
    fontWeight: '600',
    color: '#303133',
    marginBottom: 12,
  },
  card: {
    backgroundColor: '#FFFFFF',
    borderRadius: 8,
    padding: 16,
    marginBottom: 12,
  },
  label: {
    fontSize: 14,
    color: '#606266',
    marginBottom: 8,
    marginTop: 12,
  },
  input: {
    backgroundColor: '#F5F7FA',
    borderRadius: 8,
    padding: 14,
    borderWidth: 1,
    borderColor: '#DCDFE6',
    fontSize: 16,
    marginBottom: 12,
  },
  textArea: {
    height: 100,
    textAlignVertical: 'top',
  },
  charCount: {
    fontSize: 12,
    color: '#909399',
    textAlign: 'right',
    marginTop: -8,
    marginBottom: 12,
  },
  buttonContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    gap: 12,
  },
  button: {
    flex: 1,
    backgroundColor: '#409EFF',
    borderRadius: 8,
    paddingVertical: 14,
    paddingHorizontal: 20,
    alignItems: 'center',
  },
  resetButton: {
    backgroundColor: '#909399',
  },
  saveButton: {
    backgroundColor: '#67C23A',
  },
  buttonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '600',
  },
  qrContainer: {
    backgroundColor: '#FFFFFF',
    borderRadius: 8,
    padding: 20,
    alignItems: 'center',
    marginBottom: 12,
  },
  qrWrapper: {
    padding: 16,
    backgroundColor: '#FFFFFF',
    borderRadius: 8,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
  },
  qrInfo: {
    fontSize: 14,
    color: '#606266',
    marginTop: 8,
  },
  instructionCard: {
    backgroundColor: '#E6F7FF',
    borderRadius: 8,
    padding: 16,
    borderLeftWidth: 4,
    borderLeftColor: '#409EFF',
  },
  instructionText: {
    fontSize: 14,
    color: '#303133',
    lineHeight: 22,
    marginBottom: 8,
  },
});

export default QRCodeGeneratorTool;

csdn不让漏二维码,我打码了
在这里插入图片描述
在这里插入图片描述

四、OpenHarmony6.0 专属避坑指南

以下是鸿蒙 RN 开发中实现「二维码生成工具」的所有真实高频率坑点,按出现频率排序,问题现象贴合开发实战,解决方案均为「一行代码简单配置」,所有方案均为鸿蒙端专属最优解,也是本次代码都能做到**零报错、完美适配」的核心原因,鸿蒙基础可直接用,彻底规避所有二维码生成工具相关的生成失败、显示异常、网络错误等问题,全部真机实测验证通过,无任何兼容问题:

问题现象 问题原因 鸿蒙端最优解决方案
二维码图片加载失败 URL编码错误或网络问题 ✅ 正确使用 encodeURIComponent 编码,本次代码已完美实现
二维码显示异常 Image 组件尺寸设置不当 ✅ 正确设置 Image 组件尺寸,本次代码已完美实现
颜色值格式错误 颜色值格式不正确或转换失败 ✅ 正确转换颜色值,本次代码已完美实现
数据过长导致生成失败 超过API最大字符限制 ✅ 正确验证数据长度,本次代码已完美实现
网络请求超时 网络连接不稳定或API响应慢 ✅ 使用稳定的API服务,本次代码已完美实现
二维码无法扫描 URL编码问题或数据格式错误 ✅ 正确编码数据,本次代码已完美实现

五、扩展用法:二维码生成工具高级进阶优化(纯原生、无依赖、鸿蒙完美适配)

基于本次的核心二维码生成工具代码,结合纯原生 API,可轻松实现鸿蒙端开发中所有高级的二维码生成工具进阶需求,全部为纯原生实现,无需引入任何第三方库,只需在本次代码基础上做简单修改即可实现,实用性拉满,全部真机实测通过,无任何兼容问题,满足企业级高级需求:

✨ 扩展1:二维码工具类

适配「二维码工具类」的场景,封装二维码工具类,只需添加工具类逻辑,无需改动核心逻辑,一行代码实现,鸿蒙端完美适配:

class QRCodeUtils {
  static validate(data: string): { valid: boolean; message: string } {
    if (!data || data.trim() === '') {
      return { valid: false, message: '二维码内容不能为空' };
    }
    
    if (data.length > 2953) {
      return { valid: false, message: '二维码内容过长,最多支持2953个字符' };
    }
    
    return { valid: true, message: '数据验证通过' };
  }

  static buildURL(
    data: string,
    size: number = 200,
    fgColor: string = '000000',
    bgColor: string = 'FFFFFF'
  ): string {
    return buildQRCodeURL(data, size, fgColor, bgColor);
  }

  static convertColor(color: string): string {
    return convertColorToAPI(color);
  }

  static estimateSize(data: string): number {
    const length = data.length;
    if (length <= 25) return 150;
    if (length <= 47) return 180;
    if (length <= 77) return 200;
    return 250;
  }
}

// 使用示例
QRCodeUtils.validate('https://example.com');
QRCodeUtils.buildURL('Hello World', 200);
QRCodeUtils.convertColor('black');

✨ 扩展2:批量生成二维码

适配「批量生成」的场景,实现批量二维码生成,只需添加批量逻辑,无需改动核心逻辑,一行代码实现,鸿蒙端完美适配:

const batchGenerateQRCodes = (dataArray: string[]): Array<{
  data: string;
  url: string;
  valid: boolean;
}> => {
  return dataArray.map(data => {
    const validation = QRCodeUtils.validate(data);
    return {
      data,
      url: validation.valid ? QRCodeUtils.buildURL(data) : '',
      valid: validation.valid,
    };
  });
};

// 使用示例
const data = ['https://example.com', 'https://test.com', 'Hello World'];
const results = batchGenerateQRCodes(data);

✨ 扩展3:二维码历史记录

适配「二维码历史记录」的场景,实现历史记录管理,只需添加历史逻辑,无需改动核心逻辑,一行代码实现,鸿蒙端完美适配:

const useQRCodeHistory = () => {
  const [history, setHistory] = useState<Array<{
    data: string;
    timestamp: number;
    url: string;
  }>>([]);

  const addToHistory = useCallback((data: string, url: string) => {
    setHistory(prev => [
      { data, timestamp: Date.now(), url },
      ...prev.slice(0, 9), // 保留最近10条
    ]);
  }, []);

  const clearHistory = useCallback(() => {
    setHistory([]);
  }, []);

  return { history, addToHistory, clearHistory };
};

// 使用示例
const { history, addToHistory, clearHistory } = useQRCodeHistory();
addToHistory('https://example.com', 'https://api.qrserver.com/...');

✨ 扩展4:二维码模板

适配「二维码模板」的场景,实现预设模板功能,只需添加模板逻辑,无需改动核心逻辑,一行代码实现,鸿蒙端完美适配:

const qrTemplates = [
  {
    name: '网站链接',
    placeholder: 'https://example.com',
    color: { fgColor: 'black', bgColor: 'white' },
  },
  {
    name: 'WiFi连接',
    placeholder: 'WIFI:S:MyNetwork;T:WPA;P:mypassword;;',
    color: { fgColor: '#1a73e8', bgColor: '#f8f9fa' },
  },
  {
    name: '联系方式',
    placeholder: 'BEGIN:VCARD\nVERSION:3.0\nFN:张三\nTEL:13800138000\nEND:VCARD',
    color: { fgColor: '#34a853', bgColor: '#f1f8e9' },
  },
];

const useQRTemplate = () => {
  const [selectedTemplate, setSelectedTemplate] = useState(0);

  const applyTemplate = useCallback((index: number) => {
    setSelectedTemplate(index);
    return qrTemplates[index];
  }, []);

  return {
    templates: qrTemplates,
    selectedTemplate,
    applyTemplate,
  };
};

// 使用示例
const { templates, selectedTemplate, applyTemplate } = useQRTemplate();

✨ 扩展5:二维码分享

适配「二维码分享」的场景,实现二维码分享功能,只需添加分享逻辑,无需改动核心逻辑,一行代码实现,鸿蒙端完美适配:

import { Share } from 'react-native';

const shareQRCode = async (data: string): Promise<boolean> => {
  try {
    await Share.share({
      message: `扫描二维码查看:${data}`,
      url: data,
    });
    return true;
  } catch (error) {
    console.error('分享失败:', error);
    return false;
  }
};

// 使用示例
const handleShare = async () => {
  const success = await shareQRCode('https://example.com');
  if (success) {
    Alert.alert('成功', '分享成功');
  }
};

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐