国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ant.design 組件庫(kù)中的 Tree 組件實(shí)現(xiàn)可搜索的樹(shù): React+and+ts

這篇具有很好參考價(jià)值的文章主要介紹了ant.design 組件庫(kù)中的 Tree 組件實(shí)現(xiàn)可搜索的樹(shù): React+and+ts。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

ant.design 組件庫(kù)中的 Tree 組件實(shí)現(xiàn)可搜索的樹(shù),在這里我會(huì)詳細(xì)介紹每個(gè)方法,以及容易踩坑的點(diǎn)。

效果圖:

ant.design 組件庫(kù)中的 Tree 組件實(shí)現(xiàn)可搜索的樹(shù): React+and+ts,react.js,javascript,前端

首先是要導(dǎo)入的文件

// React 自帶的屬性
import React, { useMemo, useState } from 'react'; 
// antd 組件庫(kù)中的,輸入框和樹(shù)形控件
import { Input, Tree } from 'antd'; 
// ts
import type { DataNode } from 'antd/es/tree';

下面是要渲染在 Tree 上的的數(shù)據(jù),這是一個(gè)偽數(shù)據(jù),如果你在開(kāi)發(fā)時(shí)使用,直接修改給對(duì)應(yīng)的變量名,賦值即可

const { Search } = Input;

const x = 3;
const y = 2;
const z = 1;
const defaultData: DataNode[] = [];

const generateData = (_level: number, _preKey?: React.Key, _tns?: DataNode[]) => {
  const preKey = _preKey || '0';
  const tns = _tns || defaultData;

  const children: React.Key[] = [];
  for (let i = 0; i < x; i++) {
    const key = `${preKey}-${i}`;
    tns.push({ title: key, key });
    if (i < y) {
      children.push(key);
    }
  }
  if (_level < 0) {
    return tns;
  }
  const level = _level - 1;
  children.forEach((key, index) => {
    tns[index].children = [];
    return generateData(level, key, tns[index].children);
  });
};
generateData(z);

這個(gè)方法是 Tree 組件提供的,用來(lái)篩選出要渲染的數(shù)據(jù),篩選應(yīng)該是優(yōu)化一些性能的,因?yàn)樵谀玫浇涌跀?shù)據(jù)時(shí),每一項(xiàng)都可能會(huì)有很多的數(shù)據(jù),而這一步是篩選出有用的值,過(guò)濾到其他,dataList 就是用來(lái)接收這個(gè)篩選后的數(shù)據(jù)的。

// 得到篩選后的值,根據(jù)當(dāng)前要渲染的內(nèi)容來(lái)篩選
const dataList: { key: React.Key; title: string }[] = [];

// 將篩選后的值,賦給 dataList
const generateList = (data: DataNode[]) => {
  for (let i = 0; i < data.length; i++) {
    const node = data[i];
    const { key } = node;
    dataList.push({ key, title: key as string });
    if (node.children) {
      generateList(node.children);
    }
  }
};
generateList(defaultData);

觸發(fā)了搜索后

觸發(fā)了搜索后,會(huì)使用這個(gè)方法來(lái)對(duì)比兩個(gè)參數(shù)key 和 tree,得到符合條件的值

key:當(dāng)前搜索的值

tree:所有渲染的數(shù)據(jù)

const getParentKey = (key: React.Key, tree: DataNode[]): React.Key => {
  let parentKey: React.Key;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some((item) => item.key === key)) {
        parentKey = node.key;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey!;
};

現(xiàn)在進(jìn)入進(jìn)入組件內(nèi),處理邏輯,以下內(nèi)容都包裹在 App組件中

const App: React.FC = () => {}

export default App;

要使用到的可修改狀態(tài)的值

expandedKeys :(受控)展開(kāi)指定的樹(shù)節(jié)點(diǎn)

searchValue : 在觸發(fā)搜索時(shí),存儲(chǔ)當(dāng)期輸入的字段

autoExpandParent :是否自動(dòng)展開(kāi)父節(jié)點(diǎn),所以它的默認(rèn)值是布爾值

  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [searchValue, setSearchValue] = useState('');
  const [autoExpandParent, setAutoExpandParent] = useState(true);

每次樹(shù)狀圖變動(dòng),會(huì)更新 expandedKeys ,來(lái)做接下來(lái)的操作

onExpand :展開(kāi)/收起節(jié)點(diǎn)時(shí)觸發(fā)

const onExpand = (newExpandedKeys: React.Key[]) => {
    setExpandedKeys(newExpandedKeys);
    setAutoExpandParent(false);
  };

處理函數(shù)`onChange

下面這段代碼是一個(gè)事件處理函數(shù)onChange,它接收一個(gè)React.ChangeEvent<HTMLInputElement>類(lèi)型的事件對(duì)象作為參數(shù)。這個(gè)事件函數(shù)通常用于處理輸入框的值變化事件。

在函數(shù)內(nèi)部,首先通過(guò)解構(gòu)賦值取出事件對(duì)象的value屬性,即輸入框的當(dāng)前值。

然后,通過(guò)dataList數(shù)組的map方法遍歷每個(gè)元素,并根據(jù)元素的title屬性是否包含輸入框的值來(lái)判斷是否展開(kāi)節(jié)點(diǎn)。如果包含,則調(diào)用getParentKey函數(shù)獲取該節(jié)點(diǎn)的父節(jié)點(diǎn)的key,否則返回null。這個(gè)步驟用于更新展開(kāi)的節(jié)點(diǎn)。

接下來(lái),使用filter方法對(duì)newExpandedKeys數(shù)組進(jìn)行過(guò)濾,去除其中的null值,并且去掉重復(fù)的元素,得到最終的展開(kāi)節(jié)點(diǎn)數(shù)組newExpandedKeys。

調(diào)用setExpandedKeys函數(shù)將最終的展開(kāi)節(jié)點(diǎn)數(shù)組更新到狀態(tài)中。

接著,通過(guò)setSearchValue函數(shù)將輸入框的值更新到狀態(tài)中。

最后,調(diào)用setAutoExpandParent函數(shù)將autoExpandParent狀態(tài)設(shè)置為true,表示父節(jié)點(diǎn)也會(huì)被自動(dòng)展開(kāi)。

這段代碼的作用是實(shí)現(xiàn)一個(gè)用于過(guò)濾和展開(kāi)樹(shù)節(jié)點(diǎn)的搜索功能。當(dāng)輸入框的值發(fā)生變化時(shí),根據(jù)輸入的值進(jìn)行過(guò)濾,找到匹配的節(jié)點(diǎn),并展開(kāi)它們的父節(jié)點(diǎn),同時(shí)更新輸入框的值和展開(kāi)節(jié)點(diǎn)的狀態(tài)。

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    const newExpandedKeys = dataList
      .map((item) => {
        if (item.title.indexOf(value) > -1) {
          return getParentKey(item.key, defaultData);
        }
        return null;
      })
      .filter((item, i, self) => item && self.indexOf(item) === i);
    setExpandedKeys(newExpandedKeys as React.Key[]);
    setSearchValue(value);
    setAutoExpandParent(true);
  };

下面這段代碼使用了useMemo鉤子來(lái)創(chuàng)建一個(gè)名為treeData的變量。useMemo的作用是在依賴(lài)項(xiàng)(這里是searchValue)發(fā)生變化時(shí)執(zhí)行內(nèi)部的函數(shù),并將函數(shù)的返回值作為treeData的值。

函數(shù)內(nèi)部定義了一個(gè)名為loop的遞歸函數(shù),用于遍歷樹(shù)形結(jié)構(gòu)的數(shù)據(jù)data。

loop函數(shù)中,首先將item.title轉(zhuǎn)換為字符串類(lèi)型,并使用indexOf方法查找searchValue在字符串中的位置。

根據(jù)索引的結(jié)果,通過(guò)substringslice方法將字符串分割成前后兩部分,然后構(gòu)建一個(gè)新的title元素。如果搜索值在標(biāo)題中存在,使用<span>元素將搜索值高亮顯示;如果不存在,則直接使用原始的標(biāo)題。

接著,判斷item是否有子節(jié)點(diǎn)(item.children),如果有,則遞歸調(diào)用loop函數(shù)處理子節(jié)點(diǎn),并將返回的結(jié)果作為children屬性的值。

最后,在每個(gè)節(jié)點(diǎn)的處理中,都會(huì)返回一個(gè)包含titlekey屬性的對(duì)象。

最外層的useMemo的返回值就是使用loop函數(shù)處理defaultData得到的結(jié)果,它代表了樹(shù)形結(jié)構(gòu)數(shù)據(jù)經(jīng)過(guò)搜索值過(guò)濾和處理后的新數(shù)據(jù)。

總而言之,這段代碼的作用是根據(jù)搜索值searchValue對(duì)樹(shù)形結(jié)構(gòu)數(shù)據(jù)進(jìn)行過(guò)濾,并對(duì)匹配的節(jié)點(diǎn)標(biāo)題進(jìn)行處理,添加搜索值的高亮顯示。最后返回經(jīng)過(guò)處理后的新的樹(shù)形結(jié)構(gòu)數(shù)據(jù)treeData。

const treeData = useMemo(() => {
    const loop = (data: DataNode[]): DataNode[] =>
      data.map((item) => {
        const strTitle = item.title as string;
        const index = strTitle.indexOf(searchValue);
        const beforeStr = strTitle.substring(0, index);
        const afterStr = strTitle.slice(index + searchValue.length);
        const title =
          index > -1 ? (
            <span>
              {beforeStr}
              <span className="site-tree-search-value">{searchValue}</span>
              {afterStr}
            </span>
          ) : (
            <span>{strTitle}</span>
          );
        if (item.children) {
          return { title, key: item.key, children: loop(item.children) };
        }

        return {
          title,
          key: item.key,
        };
      });

    return loop(defaultData);
  }, [searchValue]);

組件的結(jié)構(gòu)

最后就是組件的結(jié)構(gòu)了,這段代碼中使用了 Search 組件,通過(guò) placeholder 屬性設(shè)置了一個(gè)提示文本 Search ,并通過(guò) onChange 屬性指定了一個(gè)事件處理函數(shù) onChange 來(lái)處理搜索框的值變化事件。這個(gè) onChange 函數(shù)通常用于更新?tīng)顟B(tài)或執(zhí)行其他邏輯,以響應(yīng)搜索框中輸入的值的變化。

總而言之,這段代碼創(chuàng)建了一個(gè)包含搜索框和樹(shù)形結(jié)構(gòu)的組件,并將搜索框的值變化和樹(shù)節(jié)點(diǎn)的展開(kāi)或折疊事件與相應(yīng)的事件處理函數(shù)關(guān)聯(lián)起來(lái)。

  return (
    <div>
      <Search style={{ marginBottom: 8 }} placeholder="Search" onChange={onChange} />
      <Tree
        onExpand={onExpand}
        expandedKeys={expandedKeys}
        autoExpandParent={autoExpandParent}
        treeData={treeData}
      />
    </div>
  );
};

完整代碼:


import React, { useMemo, useState } from 'react';
import { Input, Tree } from 'antd';
import type { DataNode } from 'antd/es/tree';

const { Search } = Input;

const x = 3;
const y = 2;
const z = 1;
const defaultData: DataNode[] = [];

const generateData = (_level: number, _preKey?: React.Key, _tns?: DataNode[]) => {
  const preKey = _preKey || '0';
  const tns = _tns || defaultData;

  const children: React.Key[] = [];
  for (let i = 0; i < x; i++) {
    const key = `${preKey}-${i}`;
    tns.push({ title: key, key });
    if (i < y) {
      children.push(key);
    }
  }
  if (_level < 0) {
    return tns;
  }
  const level = _level - 1;
  children.forEach((key, index) => {
    tns[index].children = [];
    return generateData(level, key, tns[index].children);
  });
};
generateData(z);

const dataList: { key: React.Key; title: string }[] = [];
const generateList = (data: DataNode[]) => {
  for (let i = 0; i < data.length; i++) {
    const node = data[i];
    const { key } = node;
    dataList.push({ key, title: key as string });
    if (node.children) {
      generateList(node.children);
    }
  }
};
generateList(defaultData);

const getParentKey = (key: React.Key, tree: DataNode[]): React.Key => {
  let parentKey: React.Key;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some((item) => item.key === key)) {
        parentKey = node.key;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey!;
};

const App: React.FC = () => {
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [searchValue, setSearchValue] = useState('');
  const [autoExpandParent, setAutoExpandParent] = useState(true);

  const onExpand = (newExpandedKeys: React.Key[]) => {
    setExpandedKeys(newExpandedKeys);
    setAutoExpandParent(false);
  };

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    const newExpandedKeys = dataList
      .map((item) => {
        if (item.title.indexOf(value) > -1) {
          return getParentKey(item.key, defaultData);
        }
        return null;
      })
      .filter((item, i, self) => item && self.indexOf(item) === i);
    setExpandedKeys(newExpandedKeys as React.Key[]);
    setSearchValue(value);
    setAutoExpandParent(true);
  };

  const treeData = useMemo(() => {
    const loop = (data: DataNode[]): DataNode[] =>
      data.map((item) => {
        const strTitle = item.title as string;
        const index = strTitle.indexOf(searchValue);
        const beforeStr = strTitle.substring(0, index);
        const afterStr = strTitle.slice(index + searchValue.length);
        const title =
          index > -1 ? (
            <span>
              {beforeStr}
              <span className="site-tree-search-value">{searchValue}</span>
              {afterStr}
            </span>
          ) : (
            <span>{strTitle}</span>
          );
        if (item.children) {
          return { title, key: item.key, children: loop(item.children) };
        }

        return {
          title,
          key: item.key,
        };
      });

    return loop(defaultData);
  }, [searchValue]);

  return (
    <div>
      <Search style={{ marginBottom: 8 }} placeholder="Search" onChange={onChange} />
      <Tree
        onExpand={onExpand}
        expandedKeys={expandedKeys}
        autoExpandParent={autoExpandParent}
        treeData={treeData}
      />
    </div>
  );
};

export default App;

官網(wǎng)地址: 樹(shù)形控件 Tree - Ant Design文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-629740.html

到了這里,關(guān)于ant.design 組件庫(kù)中的 Tree 組件實(shí)現(xiàn)可搜索的樹(shù): React+and+ts的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 第九篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:使用內(nèi)置組件實(shí)現(xiàn)響應(yīng)式設(shè)計(jì)

    第九篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:使用內(nèi)置組件實(shí)現(xiàn)響應(yīng)式設(shè)計(jì)

    第一篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:從helloworld開(kāi)始 第二篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:天氣應(yīng)用 第三篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:健身追蹤 第四篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移

    2024年01月21日
    瀏覽(89)
  • vue3+ts實(shí)現(xiàn)element Plus Tree組件單選和取消單選的功能(取消已經(jīng)選中的樹(shù)節(jié)點(diǎn)),及vue3的proxy對(duì)象轉(zhuǎn)換

    vue3+ts實(shí)現(xiàn)element Plus Tree組件單選和取消單選的功能(取消已經(jīng)選中的樹(shù)節(jié)點(diǎn)),及vue3的proxy對(duì)象轉(zhuǎn)換

    ?具體效果和代碼如下: 點(diǎn)擊了\\\"節(jié)點(diǎn)1\\\"并高亮顯示 打印結(jié)果如下 ?vue3的打印對(duì)象是proxy,如需變成單純的數(shù)組對(duì)象可以使用 JSON.parse(JSON.stringify(list))進(jìn)行轉(zhuǎn)換。 ?再次點(diǎn)擊\\\"節(jié)點(diǎn)1\\\"則取消當(dāng)前選中 ? 如果對(duì)您有幫助點(diǎn)個(gè)贊,關(guān)注收藏一下吧 。

    2024年02月12日
    瀏覽(22)
  • 第十二篇【傳奇開(kāi)心果系列】Ant Design Mobile of React開(kāi)發(fā)移動(dòng)應(yīng)用:內(nèi)置組件實(shí)現(xiàn)酷炫CSS 動(dòng)畫(huà)

    第十二篇【傳奇開(kāi)心果系列】Ant Design Mobile of React開(kāi)發(fā)移動(dòng)應(yīng)用:內(nèi)置組件實(shí)現(xiàn)酷炫CSS 動(dòng)畫(huà)

    第一篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:從helloworld開(kāi)始 第二篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:天氣應(yīng)用 第三篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移動(dòng)應(yīng)用:健身追蹤 第四篇【傳奇開(kāi)心果系列】Ant Design Mobile of React 開(kāi)發(fā)移

    2024年01月20日
    瀏覽(26)
  • vue3+ant design vue+ts實(shí)戰(zhàn)【ant-design-vue組件庫(kù)引入】

    vue3+ant design vue+ts實(shí)戰(zhàn)【ant-design-vue組件庫(kù)引入】

    ????更多內(nèi)容見(jiàn)Ant Design Vue官方文檔 ??點(diǎn)擊復(fù)習(xí)vue3【watch檢測(cè)/監(jiān)聽(tīng)】相關(guān)內(nèi)容 ??????一個(gè)好項(xiàng)目的編寫(xiě)不僅需要完美的邏輯,以及相應(yīng)的技術(shù),同時(shí)也需要一個(gè) 設(shè)計(jì)規(guī)范的高質(zhì)量UI組件庫(kù) 。??????本期文章將會(huì)詳細(xì)講解 Ant Design of Vue 組件庫(kù)的 安裝、使用、引入 。

    2024年02月02日
    瀏覽(49)
  • React安裝ant design組件庫(kù),并使用

    React安裝ant design組件庫(kù),并使用

    ant design是一個(gè)很棒的組件庫(kù),官方地址:快速上手 - Ant Design 但是如何在React里面用起來(lái),好像并不是很順暢,沒(méi)有像Vue里面那么友好,因?yàn)槲也冗^(guò)這個(gè)坑,雖然安裝很簡(jiǎn)單,但是想要出樣式,還是有點(diǎn)步驟的。 npm命令: yarn命令: pnpm命令: 千萬(wàn)不要簡(jiǎn)單的只看官方的文檔

    2024年02月14日
    瀏覽(21)
  • 按需引入ant-design-vue組件

    一、首先創(chuàng)建一個(gè)新的Vue項(xiàng)目 選擇default含有babel和eslint?;蛘咦远xManually select features。 babel是一個(gè)轉(zhuǎn)碼器,主要用于ES2015+ 代碼轉(zhuǎn)換為 JavaScript 向后兼容版本的代碼 eslint是一個(gè)代碼檢測(cè)工具。用來(lái)規(guī)范編碼規(guī)范用。 自定義可選的插件有,Babel,TypeScript,Progressive Web App (P

    2024年02月13日
    瀏覽(34)
  • React——Ant Design組件庫(kù)Message全局提示的使用

    官網(wǎng)推薦使用Hook調(diào)用的方法 ? ? ? ? 這種方法只能在本頁(yè)顯示,如果顯示后跳轉(zhuǎn)頁(yè)面就不會(huì)顯示。因?yàn)閧contextHolder}是寫(xiě)在本頁(yè)面的。如果需要跳轉(zhuǎn)頁(yè)面可以用promise調(diào)用 傳遞的參數(shù)依次為,提示信息、顯示時(shí)間、關(guān)閉后觸發(fā)的回調(diào)

    2024年02月11日
    瀏覽(21)
  • Ant Design Vue的table組件高度自適應(yīng)問(wèn)題

    Ant Design Vue的table組件高度自適應(yīng)問(wèn)題

    今天在編寫(xiě)公司項(xiàng)目的時(shí)候碰到ant design vue的table組件高度沒(méi)辦法自適應(yīng)的問(wèn)題,會(huì)出現(xiàn)如下頁(yè)面情況。 ?最終嘗試的解決方案只能通過(guò)監(jiān)聽(tīng)瀏覽器窗口變化實(shí)現(xiàn)自適應(yīng) (1)給表格的srcoll定義一個(gè)動(dòng)態(tài)接收參數(shù),方便后面數(shù)據(jù)增加動(dòng)態(tài)改變滾動(dòng)高度。 ?(2)vue3項(xiàng)目中就直接

    2024年02月16日
    瀏覽(24)
  • 【Blazor之關(guān)于組件庫(kù)Ant Design of Blazor組件樣式的修改】

    【Blazor之關(guān)于組件庫(kù)Ant Design of Blazor組件樣式的修改】

    例如:我們?cè)谑褂肂lazor框架時(shí)為了節(jié)省時(shí)間提升效率會(huì)使用到Ant Design of Blazor組件庫(kù)。在使用過(guò)程中我們會(huì)根據(jù)需求去修改樣式,但是由于組件庫(kù)里面的樣式基本上都是封裝好的,要想達(dá)到自己所需的效果,這時(shí)候就需要我們?nèi)バ薷臉邮?。本文就介紹一下我在使用Ant Design of

    2024年02月14日
    瀏覽(44)
  • 26、react UI 組件庫(kù) Ant-design 螞蟻金服UI組件庫(kù)

    26、react UI 組件庫(kù) Ant-design 螞蟻金服UI組件庫(kù)

    material-ui (國(guó)外) 官網(wǎng):https://mui.com/zh/material-ui/getting-started/installation/ 這是國(guó)外非常流行的 react UI 組件庫(kù),但是在國(guó)內(nèi)并不是很常用。 Ant-design UI組件庫(kù) 官網(wǎng):https://ant.design/index-cn 這是國(guó)內(nèi)比較流行 react UI 組件庫(kù),又螞蟻金服團(tuán)隊(duì)開(kāi)發(fā)。這一篇博客主要來(lái)講解在 react 項(xiàng)目中

    2024年02月08日
    瀏覽(32)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包