欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript提取PDF和Word文檔內(nèi)圖片

 更新時(shí)間:2025年03月13日 09:33:59   作者:Moment  
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)提取PDF和Word文檔內(nèi)的圖片,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下

最近接了個(gè)需求,要求就是基于文檔的 AI 問答,文檔里面最常見的就是 PDF 和 Word 文檔了,里面的內(nèi)容無非就是文本和圖片了,目前是沒有直接接收這種文檔的模型的,那么我們需要經(jīng)過一些處理來進(jìn)行。

首先我們要先把圖片和文本來進(jìn)行處理,我這邊的處理方式就是圖片調(diào)用圖片的模型來識(shí)別圖片信息,將返回的信息和文檔的文本作為后面的問答的前置 prompt,至于這些 prompt 就可以根據(jù)不同的需求來做不同處理了,這里不多解釋。

在接下來,我們將使用 NextJs 項(xiàng)目作為例子進(jìn)行講解,后面的內(nèi)容跟框架依性不是很大,vue,astro 等項(xiàng)目都可以直接拿來使用。

提取 PDF 中的圖片

PDF.js 是一個(gè)開源的 JavaScript 庫,用于在網(wǎng)頁上直接顯示和渲染 PDF 文件。它將 PDF 文件解析為 HTML5 元素,使得瀏覽器可以無插件地加載和查看 PDF 文檔。PDF.js 支持多種功能,如文本選擇、搜索、頁面導(dǎo)航等,提供了良好的瀏覽體驗(yàn)。通過它,開發(fā)者可以輕松集成 PDF 查看功能到網(wǎng)站或應(yīng)用中。

為了避免 PDF 解析過程阻塞主線程,PDF.js 使用 Web Worker ,因?yàn)?PDF 解析是一個(gè) CPU 密集型的操作,涉及大量計(jì)算和內(nèi)存處理。

首先我們需要在項(xiàng)目中安裝相關(guān)依賴包:

pnpm add pdfjs-dist

安裝完成之后,我們需要設(shè)置 WebWorker 的路徑,我們不使用 cdn 的文件,我們聰明人用聰明的方法:

我們可以將 node_modules 中 pdfjs-dist 目錄下的 build 目錄下 pdf.worker.mjs 文件放到 public/js 目錄下,但是要把 mjs 后綴改成 js。

最后在項(xiàng)目中引入即可:

import * as pdfjsLib from "pdfjs-dist";

pdfjsLib.GlobalWorkerOptions.workerSrc = "/js/pdf.worker.js";

處理文件上傳

const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
  const file = e.target.files?.[0];
  if (!file) return;

  try {
    const arrayBuffer = await file.arrayBuffer(); // 讀取文件為 ArrayBuffer
    const typedarray = new Uint8Array(arrayBuffer); // 轉(zhuǎn)換為 Uint8Array
    const loadingTask = pdfjsLib.getDocument(typedarray); // 使用 pdf.js 加載文檔
    await loadPDFFile(loadingTask); // 加載 PDF 文件
  } catch (err) {
    setError(err instanceof Error ? err.message : "Failed to read file");
    console.error("File reading error:", err);
  }
};

當(dāng)用戶選擇文件時(shí),將文件轉(zhuǎn)化為 ArrayBuffer,然后再轉(zhuǎn)為 Uint8Array,最終使用 pdfjsLib.getDocument 加載 PDF 文件并調(diào)用 loadPDFFile。

加載 PDF 文件并提取圖像和文本

const loadPDFFile = async (loadingTask: pdfjsLib.PDFDocumentLoadingTask) => {
  try {
    setIsLoading(true);
    setError(null);
    const pdf = await loadingTask.promise; // 獲取 PDF 實(shí)例
    const numPages = pdf.numPages; // 獲取 PDF 總頁數(shù)
    const allImages: PDFImage[] = [];
    const allTexts: PDFText[] = [];

    // 循環(huán)加載每一頁
    for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
      const page = await pdf.getPage(pageNumber); // 獲取單個(gè)頁面

      // 提取圖像
      const pageImages = await extractImagesFromPage(page, pageNumber);
      allImages.push(...pageImages);

      // 提取文本
      const pageTexts = await extractTextFromPage(page, pageNumber);
      allTexts.push(...pageTexts);
    }

    setImages(allImages); // 更新圖像數(shù)據(jù)
    setTexts(allTexts); // 更新文本數(shù)據(jù)
  } catch (err) {
    setError(err instanceof Error ? err.message : "Failed to process PDF");
    console.error("PDF processing error:", err);
  } finally {
    setIsLoading(false);
  }
};

loadPDFFile 函數(shù)加載 PDF 文件并提取所有頁面的圖像和文本。通過 getPage 獲取每一頁,調(diào)用 extractImagesFromPageextractTextFromPage 提取數(shù)據(jù)。

提取圖像

const extractImagesFromPage = async (
  page: pdfjsLib.PDFPageProxy,
  pageNumber: number
): Promise<PDFImage[]> => {
  const extractedImages: PDFImage[] = [];
  const ops = await page.getOperatorList(); // 獲取頁面的操作列表
  const imageNames = ops.fnArray.reduce<string[]>((acc, curr, i) => {
    if ([pdfjsLib.OPS.paintImageXObject, pdfjsLib.OPS.paintXObject].includes(curr)) {
      acc.push(ops.argsArray[i][0]); // 過濾出圖像對(duì)象名稱
    }
    return acc;
  }, []);

  // 提取圖像
  for (const imageName of imageNames) {
    try {
      const image = await new Promise<PDFImageObject>((resolve) =>
        page.objs.get(imageName, resolve) // 獲取圖像對(duì)象
      );
      if (!image || !image.bitmap) continue;

      const bmp = image.bitmap;
      const resizeScale = 1 / 4; // 縮放比例
      const width = Math.floor(bmp.width * resizeScale); // 計(jì)算縮放后的寬度
      const height = Math.floor(bmp.height * resizeScale); // 計(jì)算縮放后的高度

      const canvas = new OffscreenCanvas(width, height); // 創(chuàng)建離屏 canvas
      const ctx = canvas.getContext("bitmaprenderer");
      if (!ctx) continue;

      ctx.transferFromImageBitmap(bmp); // 將圖片渲染到 canvas 上
      const blob = await canvas.convertToBlob(); // 轉(zhuǎn)換為 Blob 對(duì)象
      const imgURL = URL.createObjectURL(blob); // 生成圖像 URL

      extractedImages.push({
        url: imgURL,
        pageNumber,
      });
    } catch (err) {
      console.error(`Error processing image ${imageName}:`, err);
    }
  }

  return extractedImages;
};

extractImagesFromPage 從頁面的操作列表中提取圖像對(duì)象,并將圖像渲染到離屏 OffscreenCanvas 上,最后轉(zhuǎn)換為 Blob 并生成 URL。返回一個(gè)包含所有圖像的數(shù)組。

提取文本

const extractTextFromPage = async (
  page: pdfjsLib.PDFPageProxy,
  pageNumber: number
): Promise<PDFText[]> => {
  const extractedTexts: PDFText[] = [];
  try {
    const textContent = (await page.getTextContent()) as TextContent; // 獲取文本內(nèi)容
    const text = textContent.items.map((item) => item.str).join(" "); // 拼接所有文本
    extractedTexts.push({
      text,
      pageNumber,
    });
  } catch (err) {
    console.error(`Error processing text on page ${pageNumber}:`, err);
  }
  return extractedTexts;
};

extractTextFromPage 使用 getTextContent 方法提取頁面的文本內(nèi)容,并將所有文本拼接成一個(gè)字符串,返回提取的文本。

完整代碼

完整代碼如下所示:

"use client";

import { useState } from "react";
import * as pdfjsLib from "pdfjs-dist";

pdfjsLib.GlobalWorkerOptions.workerSrc = "/js/pdf.worker.js";

interface PDFImage {
  url: string;
  pageNumber: number;
}

interface PDFText {
  text: string;
  pageNumber: number;
}

interface PDFImageObject {
  bitmap: ImageBitmap;
}

interface TextItem {
  str: string;
  dir: string;
  width: number;
  height: number;
  transform: number[];
  fontName: string;
}

interface TextStyle {
  fontFamily: string;
  ascent: number;
  descent: number;
  vertical: boolean;
}

interface TextContent {
  items: TextItem[];
  styles: Record<string, TextStyle>;
}

export default function Home() {
  const [images, setImages] = useState<PDFImage[]>([]);
  const [texts, setTexts] = useState<PDFText[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 提取圖像
  const extractImagesFromPage = async (
    page: pdfjsLib.PDFPageProxy,
    pageNumber: number
  ): Promise<PDFImage[]> => {
    const extractedImages: PDFImage[] = [];
    const ops = await page.getOperatorList();
    const imageNames = ops.fnArray.reduce<string[]>((acc, curr, i) => {
      if (
        [pdfjsLib.OPS.paintImageXObject, pdfjsLib.OPS.paintXObject].includes(
          curr
        )
      ) {
        acc.push(ops.argsArray[i][0]);
      }
      return acc;
    }, []);

    for (const imageName of imageNames) {
      try {
        const image = await new Promise<PDFImageObject>((resolve) =>
          page.objs.get(imageName, resolve)
        );
        if (!image || !image.bitmap) continue;

        const bmp = image.bitmap;
        const resizeScale = 1 / 4;
        const width = Math.floor(bmp.width * resizeScale);
        const height = Math.floor(bmp.height * resizeScale);

        const canvas = new OffscreenCanvas(width, height);
        const ctx = canvas.getContext("bitmaprenderer");

        if (!ctx) continue;

        ctx.transferFromImageBitmap(bmp);
        const blob = await canvas.convertToBlob();
        const imgURL = URL.createObjectURL(blob);

        extractedImages.push({
          url: imgURL,
          pageNumber,
        });
      } catch (err) {
        console.error(`Error processing image ${imageName}:`, err);
      }
    }

    return extractedImages;
  };

  // 提取文本
  const extractTextFromPage = async (
    page: pdfjsLib.PDFPageProxy,
    pageNumber: number
  ): Promise<PDFText[]> => {
    const extractedTexts: PDFText[] = [];
    try {
      const textContent = (await page.getTextContent()) as TextContent;
      const text = textContent.items.map((item) => item.str).join(" ");
      extractedTexts.push({
        text,
        pageNumber,
      });
    } catch (err) {
      console.error(`Error processing text on page ${pageNumber}:`, err);
    }
    return extractedTexts;
  };

  // 加載 PDF 文件
  const loadPDFFile = async (loadingTask: pdfjsLib.PDFDocumentLoadingTask) => {
    try {
      setIsLoading(true);
      setError(null);
      const pdf = await loadingTask.promise;
      const numPages = pdf.numPages;
      const allImages: PDFImage[] = [];
      const allTexts: PDFText[] = [];

      for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
        const page = await pdf.getPage(pageNumber);

        // 提取圖像
        const pageImages = await extractImagesFromPage(page, pageNumber);
        allImages.push(...pageImages);

        // 提取文本
        const pageTexts = await extractTextFromPage(page, pageNumber);
        allTexts.push(...pageTexts);
      }

      setImages(allImages);
      setTexts(allTexts); // 設(shè)置提取的文本
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to process PDF");
      console.error("PDF processing error:", err);
    } finally {
      setIsLoading(false);
    }
  };

  // 處理文件上傳
  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    try {
      const arrayBuffer = await file.arrayBuffer();
      const typedarray = new Uint8Array(arrayBuffer);
      const loadingTask = pdfjsLib.getDocument(typedarray);
      await loadPDFFile(loadingTask);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to read file");
      console.error("File reading error:", err);
    }
  };

  const handleImageLoad = (imgURL: string) => {
    // Clean up object URL when image is loaded
    URL.revokeObjectURL(imgURL);
  };

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">PDF 圖像提取器</h1>

      <div className="mb-6">
        <label className="block text-sm font-medium text-gray-700 mb-2">
          選擇 PDF 文件
          <input
            type="file"
            accept="application/pdf"
            onChange={handleFileChange}
            className="mt-1 block w-full text-sm text-gray-500
              file:mr-4 file:py-2 file:px-4
              file:rounded-full file:border-0
              file:text-sm file:font-semibold
              file:bg-blue-50 file:text-blue-700
              hover:file:bg-blue-100"
          />
        </label>
      </div>

      {isLoading && (
        <div className="text-center py-4">
          <p className="text-blue-600">正在處理 PDF 文件,請(qǐng)稍候...</p>
        </div>
      )}

      {error && (
        <div className="bg-red-50 border-l-4 border-red-500 p-4 mb-4">
          <p className="text-red-700">{error}</p>
        </div>
      )}

      {!isLoading && images.length > 0 && (
        <div>
          <h2 className="text-xl font-semibold mb-4">提取的圖像:</h2>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {images.map((image, index) => (
              <div key={index} className="border rounded-lg p-4">
                <img
                  src={image.url}
                  alt={`Extracted Image ${index + 1} from page ${
                    image.pageNumber
                  }`}
                  className="max-w-full h-auto"
                  onLoad={() => handleImageLoad(image.url)}
                />
                <p className="text-sm text-gray-600 mt-2">
                  來自第 {image.pageNumber} 頁
                </p>
              </div>
            ))}
          </div>
        </div>
      )}

      {!isLoading && !error && images.length === 0 && (
        <p className="text-gray-600 text-center py-8">
          上傳 PDF 文件以提取其中的圖像
        </p>
      )}

      {/* 顯示提取的文本 */}
      {!isLoading && texts.length > 0 && (
        <div>
          <h2 className="text-xl font-semibold mb-4">提取的文本:</h2>
          <div className="space-y-4">
            {texts.map((text, index) => (
              <div key={index} className="border rounded-lg p-4">
                <p className="text-sm text-gray-600">{text.text}</p>
                <p className="text-sm text-gray-600 mt-2">
                  來自第 {text.pageNumber} 頁
                </p>
              </div>
            ))}
          </div>
        </div>
      )}

      {!isLoading && !error && texts.length === 0 && (
        <p className="text-gray-600 text-center py-8">
          上傳 PDF 文件以提取其中的文本
        </p>
      )}
    </div>
  );
}

最終輸出結(jié)果如下圖所示:

這個(gè)原文檔是這樣的:

完美輸出

提取 Word 文檔

Mammoth 是一個(gè) JavaScript 庫,專門用于將 .docx 格式的文件轉(zhuǎn)換為 HTML 或其他格式。它的目標(biāo)是提供一個(gè)高質(zhì)量的 Word 文檔轉(zhuǎn)換工具,特別適用于將 Word 文檔內(nèi)容轉(zhuǎn)化為干凈、結(jié)構(gòu)化的 HTML,而不包含多余的樣式和復(fù)雜的 HTML 標(biāo)簽。與其他文檔轉(zhuǎn)換工具不同,Mammoth 強(qiáng)調(diào)簡潔和可讀性,幫助開發(fā)者輕松將 Word 文檔的內(nèi)容嵌入到網(wǎng)頁中。它特別適合處理簡單的文本內(nèi)容和基本的格式化。

接下來我們就用這個(gè)包來出來這個(gè)類型的文檔:

pnpm add mammoth

這里就不做前面講解得那么詳細(xì)了:

"use client";

import React, { useState } from "react";
import mammoth from "mammoth";

const FileUpload = () => {
  const [images, setImages] = useState<string[]>([]); // 存儲(chǔ)圖片
  const [text, setText] = useState<string>(""); // 存儲(chǔ)提取的文本
  const [error, setError] = useState<string | null>(null); // 存儲(chǔ)錯(cuò)誤信息
  const [isLoading, setIsLoading] = useState(false); // 加載狀態(tài)

  // 處理文件上傳
  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setIsLoading(true);
    setError(null);
    setImages([]);
    setText("");

    try {
      const arrayBuffer = await file.arrayBuffer();
      await processDocxFile(arrayBuffer);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to read file");
    } finally {
      setIsLoading(false);
    }
  };

  // 使用 mammoth 提取文本和圖片
  const processDocxFile = async (arrayBuffer: ArrayBuffer) => {
    try {
      const extractedImages: string[] = [];

      const options = {
        convertImage: mammoth.images.imgElement((image) => {
          return image.read("base64").then((imageBuffer) => {
            const imageType = image.contentType || "image/png";
            const base64Image = `data:${imageType};base64,${imageBuffer}`;
            extractedImages.push(base64Image);
            return {
              src: base64Image,
              alt: "Extracted image",
            };
          });
        }),
      };

      const result = await mammoth.convertToHtml({ arrayBuffer }, options);

      // 去除重復(fù)的文本
      const uniqueText = removeDuplicateText(result.value);
      setText(uniqueText);
      setImages(extractedImages);

      if (result.messages.length > 0) {
        console.log("Conversion messages:", result.messages);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to process file");
      console.error("Error processing DOCX:", err);
    }
  };

  // 去除文本中的重復(fù)內(nèi)容
  const removeDuplicateText = (htmlText: string): string => {
    const cleanText = htmlText.replace(/<img[^>]*>/g, ""); // 移除 img 標(biāo)簽
    const paragraphs = cleanText.split("<p>").filter((p) => p.trim());
    const uniqueParagraphs = Array.from(new Set(paragraphs));
    return uniqueParagraphs.map((p) => `<p>${p}`).join("\n");
  };

  return (
    <div className="p-4">
      <h1 className="text-2xl font-bold mb-4">Upload DOCX File</h1>
      <input
        type="file"
        accept=".docx"
        onChange={handleFileChange}
        className="mb-4 p-2 border rounded"
      />

      {isLoading && <p className="text-blue-500">Processing...</p>}
      {error && <p className="text-red-500">{error}</p>}

      {/* 顯示提取的文本 */}
      {text && (
        <div className="mt-4">
          <h3 className="text-xl font-semibold">Extracted Text:</h3>
          <div
            dangerouslySetInnerHTML={{ __html: text }}
            className="mt-2 p-4 border rounded"
          />
        </div>
      )}

      {/* 顯示提取的圖片 */}
      {images.length > 0 && (
        <div className="mt-4">
          <h3 className="text-xl font-semibold">Extracted Images:</h3>
          <div className="grid grid-cols-3 gap-4 mt-2">
            {images.map((img, index) => (
              <img
                key={index}
                src={img}
                alt={`Extracted Image ${index + 1}`}
                className="max-w-full h-auto border rounded"
              />
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default FileUpload;

這段代碼實(shí)現(xiàn)了一個(gè) DOCX 文件上傳并提取文本和圖片的功能。用戶通過文件上傳控件選擇一個(gè) .docx 文件,觸發(fā) handleFileChange 方法來讀取文件并將其轉(zhuǎn)換為 arrayBuffer。然后,processDocxFile 函數(shù)使用 mammoth 庫對(duì)文件進(jìn)行處理,提取其中的文本和圖片。

在提取過程中,mammoth 通過 convertToHtml 方法將 DOCX 文件轉(zhuǎn)換為 HTML,同時(shí)通過 convertImage 選項(xiàng)將圖片提取為 Base64 編碼的格式。提取的文本會(huì)經(jīng)過去除重復(fù)內(nèi)容的處理,最終顯示在頁面上。圖片以 Base64 格式顯示,用戶可以查看提取的圖像。

isLoading 狀態(tài)用于顯示文件正在處理中,error 狀態(tài)用來捕獲并顯示錯(cuò)誤信息。提取的文本和圖片被存儲(chǔ)在 textimages 狀態(tài)變量中,并在界面上相應(yīng)地展示。

最終輸出結(jié)果如下圖所示;

參考

JavaScript提取PDF圖片

以上就是JavaScript提取PDF和Word文檔內(nèi)圖片的詳細(xì)內(nèi)容,更多關(guān)于JavaScript提取PDF和Word圖片的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Echarts Bar橫向柱狀圖實(shí)例代碼

    Echarts Bar橫向柱狀圖實(shí)例代碼

    柱狀圖主要用于表示離散數(shù)據(jù)的頻數(shù),也是一種基礎(chǔ)可視化圖,這篇文章主要給大家介紹了關(guān)于Echarts Bar橫向柱狀圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • JavaScript中querySelectorAll的基本用法及詳細(xì)解析

    JavaScript中querySelectorAll的基本用法及詳細(xì)解析

    querySelectorAll是一個(gè)用于獲取文檔中所有匹配指定選擇器的元素的方法,這篇文章主要介紹了JavaScript中querySelectorAll的基本用法及詳細(xì)解析,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • javascript中閉包c(diǎn)losure的深入講解

    javascript中閉包c(diǎn)losure的深入講解

    這篇文章主要給大家介紹了關(guān)于javascript中閉包c(diǎn)losure的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 在Z-Blog中運(yùn)行代碼[html][/html](純JS版)

    在Z-Blog中運(yùn)行代碼[html][/html](純JS版)

    在Z-Blog中運(yùn)行代碼[html][/html](純JS版)...
    2007-03-03
  • 微信小程序之onLaunch與onload異步問題詳解

    微信小程序之onLaunch與onload異步問題詳解

    這篇文章主要介紹了微信小程序之onLaunch與onload異步問題詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 微信小程序動(dòng)態(tài)增加按鈕組件

    微信小程序動(dòng)態(tài)增加按鈕組件

    這篇文章主要為大家詳細(xì)介紹了微信小程序動(dòng)態(tài)增加按鈕組件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • javascript點(diǎn)擊按鈕實(shí)現(xiàn)隱藏顯示切換效果

    javascript點(diǎn)擊按鈕實(shí)現(xiàn)隱藏顯示切換效果

    這篇文章主要介紹了javascript點(diǎn)擊按鈕實(shí)現(xiàn)隱藏顯示切換效果,以一個(gè)完整的實(shí)例為大家分析了js點(diǎn)擊按鈕實(shí)現(xiàn)隱藏顯示切換的功能,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 來自chinaz的ajax獲取評(píng)論代碼

    來自chinaz的ajax獲取評(píng)論代碼

    chinaz利用了ajax實(shí)現(xiàn)評(píng)論的讀取操作,下面我們參考chinaz的代碼
    2008-05-05
  • JavaScript模塊隨意拖動(dòng)示例代碼

    JavaScript模塊隨意拖動(dòng)示例代碼

    這篇文章主要介紹了JavaScript模塊隨意拖動(dòng)的具體實(shí)現(xiàn),需要的朋友可以參考下
    2014-05-05
  • 微信小程序select下拉框?qū)崿F(xiàn)源碼

    微信小程序select下拉框?qū)崿F(xiàn)源碼

    這篇文章主要介紹了微信小程序select下拉框?qū)崿F(xiàn)源碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評(píng)論