Taro小程序生成二维码保存本地

1,443 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

步骤 生成二维码 - 获取二维码的base64 - 获取权限 - 获得地址 -- 保存

import { QRCode } from "taro-code";

const ref = useRef<any>();

 <TView ref={ref}>
  <QRCode
    text='world'
    size={200}
    scale={4}
    errorCorrectLevel='M'
    typeNumber={2}
  />
</TView>

在外面加一层View 是为了获取taro-code生成的image 从而获得src 也就是base64格式的二维码图片

处理权限相关操作

import {
  getSetting,
  authorize,
  saveImageToPhotosAlbum,
  getFileSystemManager,
  env,
} from "@tarojs/taro";

const handleSaveCode = useCallback(() => {
 getSetting({
   success: function ({ authSetting }) {
     //没有权限则申请
     if (!authSetting["scope.writePhotosAlbum"]) {
       authorize({
         scope: "scope.writePhotosAlbum",
         success: () => {
           //存储二维码
           handleWriteFile();
         },
       });
     } else handleWriteFile();
   },
 });
}, []);

handleWriteFile 存储本地逻辑


  const handleWriteFile = useCallback(() => {
    const { src } = ref.current.childNodes[0].props;
    const data = src.split(",")[1];
    const filePath = `${env.USER_DATA_PATH}/${Date.now()}.png`;
    const { writeFile } = getFileSystemManager();
    // 写入 获得文件路径
    writeFile({
      data,
      filePath,
      encoding: "base64",
      success: () => {
      //存入相册
        saveImageToPhotosAlbum({
          filePath,
          success: () => {
            console.log("👏");
          },
        });
      },
      fail: (err) => {
        console.error(err);
      },
    });
  }, []);

完整代码 未必能直接用 进攻参考

import { FC, ReactElement, useCallback, useRef, useState } from "react";
import { View as TView } from "@tarojs/components";
import {
  getSetting,
  authorize,
  saveImageToPhotosAlbum,
  getFileSystemManager,
  env,
} from "@tarojs/taro";
import { Button, FlexView, View } from "../BUI";
import { ICode } from "./types";
import Mask from "./Mask";
//@ts-nocheck
import { QRCode } from "taro-code";

import "./feedQRCode.css";
import { createCode } from "../../api/feedQRCodeAPI";

interface IProps {
  code: ICode;
}

const GenerateQRCode: FC<IProps> = ({ code }): ReactElement => {
  const [show, setShow] = useState(false);
  const [loading, setLoading] = useState(false);
  const ref = useRef<any>();

  const handlePostCode = useCallback(() => {
    console.log(code);
    setLoading(true);
    createCode(code)
      .then((res) => {
        console.log("res", res);
        setLoading(false);
      })
      .catch((err) => {
        console.log("err", err);
      });
  }, [code]);

  const handleGenerate = useCallback(() => {
    setShow(!show);
    //发送请求
    if (!show) handlePostCode();
  }, [handlePostCode, show]);

  const handleWriteFile = useCallback(() => {
    const base64 = ref.current.childNodes[0].props.src;
    const data = base64.split(",")[1];
    const filePath = `${env.USER_DATA_PATH}/${Date.now()}.png`;
    console.log(filePath);
    const { writeFile } = getFileSystemManager();
    writeFile({
      data,
      filePath,
      encoding: "base64",
      success: (res) => {
        console.log(res);
        //
        saveImageToPhotosAlbum({
          filePath,
          success: () => {
            console.log("👏");
          },
        });
      },
      fail: (err) => {
        console.error(err);
      },
    });
  }, []);

  const handleSaveCode = useCallback(() => {
    getSetting({
      success: function ({ authSetting }) {
        //没有权限则申请
        if (!authSetting["scope.writePhotosAlbum"]) {
          authorize({
            scope: "scope.writePhotosAlbum",
            success: () => {
              //存储二维码
              handleWriteFile();
            },
          });
        } else handleWriteFile();
      },
    });
  }, []);

  return (
    <View
      className='container'
      style={{ bottom: show ? 0 : "calc(46px - 50vh)" }}
    >
      <Button
        width='100%'
        onClick={handleGenerate}
        letterSpacing='2px'
        radius='0'
      >
        生成二维码
      </Button>
      <FlexView
        column
        width='100%'
        alignItems='center'
        justifyContent='space-evenly'
        style={{
          filter: loading ? "blur(10rpx)" : undefined,
          flex: 1,
        }}
      >
        <TView ref={ref}>
          <QRCode
            text='world'
            size={200}
            scale={4}
            errorCorrectLevel='M'
            typeNumber={2}
          />
        </TView>

        <FlexView width='100%'>
          <Button onClick={handleSaveCode}>保存本地</Button>
          <Button>查看页面</Button>
        </FlexView>
      </FlexView>
      <Mask state={loading} />
    </View>
  );
};

export default GenerateQRCode;