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

【Element-ui】el-table大數(shù)據(jù)量渲染卡頓問題

這篇具有很好參考價(jià)值的文章主要介紹了【Element-ui】el-table大數(shù)據(jù)量渲染卡頓問題。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1、場景描述

在項(xiàng)目開發(fā)中,遇到在表格中一次性加載完的需求,且加載數(shù)量不少,有幾百幾千條,并且每條都可能有自己的下拉框,輸入框來做編輯功能,此時(shí)普通的el-table肯定會(huì)導(dǎo)致瀏覽器卡死,那么怎么辦呢?

2、解決方案

當(dāng)然很多童鞋肯定會(huì)想到利用插件,其實(shí)我本人是不咋喜歡插件的,能自己寫就自己寫,畢竟插件可能也有bug或者啥的,萬一出現(xiàn)了,作者不去改咋辦,所以我總結(jié)了下面幾個(gè)解決方法

提示:本篇博客基本都用的tsx + vue3 composition-api體驗(yàn)版 來寫的噢,用vue2或者vue3模板語法寫會(huì)更簡單噢,照葫蘆畫瓢邏輯都是一樣的,我這里就不寫了,想了解相關(guān)的vue3知識(shí)我另一篇博客上有噢~

Vue3知識(shí)點(diǎn)學(xué)習(xí)

1、滾動(dòng)觸底分頁(良)

當(dāng)縱向滾動(dòng)條觸底的時(shí)候,加載新的數(shù)據(jù)到當(dāng)前表格中,邏輯如下:

table.scrollTop + table.clientHeight === table.scrollHeight 

當(dāng)上述成立時(shí)候觸發(fā)加載,table為表格dom, 但是如果數(shù)據(jù)很多的話,每次滾動(dòng)都會(huì)將新的tr加入到表格中,那表格tr dom總數(shù)還是會(huì)依次遞增,dom一多照樣卡死

2、滾動(dòng)區(qū)間分頁(良+)

如果你沒有表格編輯功能,全是展示數(shù)據(jù)的話,那么這個(gè)解決方案已經(jīng)完全可以了

比如你當(dāng)前表格可顯示區(qū)域能夠展示十條數(shù)據(jù),那么首次進(jìn)來時(shí),顯示數(shù)據(jù)的區(qū)間為 [0, 9],每次表格滾動(dòng)時(shí),都動(dòng)態(tài)的去獲取當(dāng)前展示的區(qū)間,其實(shí)這種方式是比較好的,為啥呢?因?yàn)椴还苣?span style="color:#fe2c24;">幾千幾萬條數(shù)據(jù),我同一時(shí)刻就只有10行,完全不會(huì)因?yàn)閠r數(shù)量過多導(dǎo)致瀏覽器渲染卡頓,當(dāng)然這可視區(qū)域能展示多少條數(shù)據(jù),是有你表格可視高度和單行tr高度一起決定的

const selectWrap = table.querySelector('.el-table__body-wrapper');

const selectRow = table.querySelector('table tr');

展示tr數(shù)量 = Math.ceil(selectWrap.clientHeight / selectRow.clientHeight)

tsx:頁面

setup() {
? return () => (
? ? <el-table
? ? ? data={visibleResult.value} // 可視區(qū)域的數(shù)據(jù)
? ? >
? ? </el-table>
? )
}

ts:邏輯

  /** 表格上展示的數(shù)據(jù) */
  const visibleResult = computed(() => {
    return result.value.filter((_item, index) => {
      if (index < curStartIndex.value) {
        return false;
      } else if (index > curEndIndex.value) {
        return false;
      } else {
        return true;
      }
    });
  })

那么如何去控制這個(gè)滾動(dòng)區(qū)間呢?這個(gè)方法很多,監(jiān)聽滾動(dòng)條的scroll,當(dāng)向下滾動(dòng)或向上滾動(dòng),我們都可以監(jiān)聽到,然后改變curStartIndex和curEndIndex的值就可以改變啦,這樣的話,光是只看數(shù)據(jù)倒是解決了,但是要是表格要實(shí)現(xiàn)編輯效果咋辦?每行數(shù)據(jù)有十幾個(gè)下拉框和輸入框,你要知道,el-select dom層級很高,像這種el-select數(shù)量一多,就算你當(dāng)前展示區(qū)域沒有多少條數(shù)據(jù),也會(huì)導(dǎo)致渲染卡頓的,所以就有下面的優(yōu)化版方案

3、滾動(dòng)區(qū)間分頁 + 表格編輯(優(yōu))

當(dāng)前表格可視區(qū)域有30條數(shù)據(jù),每條數(shù)據(jù)有10個(gè)el-select和5個(gè)el-input(當(dāng)然可能有童鞋會(huì)說,el-select dom層級高,那我就自己寫select鴨~但是你自己寫的未必有el-select好看且功能相當(dāng))。此時(shí)首次加載就很卡頓了,原因就是el-select多了,那么我首先想的是這些el-select又不是直接要用,為啥不在我點(diǎn)擊這個(gè)單元格時(shí)候再彈出下拉呢?不點(diǎn)擊單元格時(shí)候,就直接展示文本效果(el-select沒有值時(shí)展示 '請選擇', 有值時(shí)展示你選擇的值)

例圖如下:

【Element-ui】el-table大數(shù)據(jù)量渲染卡頓問題

?滾動(dòng)區(qū)間分頁

?不管你有多少條數(shù)據(jù),我始終首次只加載這么十多個(gè)tr,tr數(shù)量不變,變化的是每次的區(qū)間取值,大家會(huì)發(fā)現(xiàn)下面有個(gè)tr id為 virtual-scroll,那這是干什么 的呢?其實(shí)核心思路是:

顯示區(qū)的高度 + 已經(jīng)滾動(dòng)過的高度 + 虛擬滾動(dòng)條高度 === 總的數(shù)據(jù)高度

table-wrapper.clientHeight + table-wrapper.scrollTop + virtual-scroll.height === data.lentth * tr.clientHeight

?是不是發(fā)現(xiàn)和方案1類似,但是區(qū)別不同的是,虛擬條高度可是一來就會(huì)被計(jì)算出來的,因?yàn)殚_始時(shí)候scrollTop為0, 那么 虛擬條高度 就是 總的數(shù)據(jù)高度 - 顯示區(qū)高度

tsx: 通過自定義指令來監(jiān)聽表格的滾動(dòng),返回值觸發(fā)loadMore方法,來決定顯示區(qū)展示數(shù)據(jù)的區(qū)間

setup() {
    return () => (
        <el-table
            data={visibleResult.value} // 可視區(qū)域的數(shù)據(jù)
            {...{ directives: [{ name: 'load-more', value: methods.loadMore }] }}
        >
        </el-table>
    )
}

ts: 邏輯

  /** 表格上展示的數(shù)據(jù) */
  const visibleResult = computed(() => {
    return result.value.filter((_item, index) => {
      if (index < curStartIndex.value) {
        return false;
      } else if (index > curEndIndex.value) {
        return false;
      } else {
        return true;
      }
    });
  })

const methods = {
    /**
     * 懶加載回調(diào)
     * @param startIndex 區(qū)段位置開始索引
     * @param endIndex 區(qū)段位置結(jié)束索引
     */
    loadMore(startIndex: number, endIndex: number) {
      curStartIndex.value = startIndex
      curEndIndex.value = endIndex
    },
}

那上面是實(shí)現(xiàn)滾動(dòng)區(qū)間的代碼,那說的表格編輯相關(guān)在哪里呢?下面即是:

表格編輯

當(dāng)我們表格中有很多下拉框和輸入框時(shí),其實(shí)拖垮性能的多半是el-select,那解決方法是將渲染input和select的邏輯提出來,input不做處理,select當(dāng)前單元格row,column索引和focusCell的值一致時(shí)說明單元格被聚焦了,就顯示el-select,否則直接展示文本

關(guān)鍵方法及屬性講解:

inputChange:輸入框回調(diào)

selectChange:下拉框選擇回調(diào)

selectPerofrmance:下拉框當(dāng)前值渲染

domPropsInnerHTML: 等同于v-html,但是jsx中不能用v-html

decorateHeader:表格各列數(shù)據(jù)我都是動(dòng)態(tài)配置的,后續(xù)我會(huì)出一期博客來講解vue3+tsx下如何封裝表格

然后效果大致如下,總結(jié)下就是同一時(shí)間最多只會(huì)存在一個(gè)el-select,既然el-select dom減少了,那么表格渲染速度就自然而然快了

【Element-ui】el-table大數(shù)據(jù)量渲染卡頓問題

?上面例圖中被黃色圈中的就是聚焦,沒有被聚焦的都展示文本,源碼講解如下:

const focusCell = ref<string>('0,0') // 表格數(shù)據(jù)第0行第0列

?你在el-table 里有 cell-click 這個(gè)事件,它會(huì)將當(dāng)前row, column全都回調(diào)回去,那么你就會(huì)知道你當(dāng)前點(diǎn)擊單元格的索引值, 我們將索引值生成, 在同一時(shí)間,focusCell只會(huì)有一條數(shù)據(jù),所以我們直接用字符串來存儲(chǔ)就好

<el-table
? on-cell-click={methods.cellClick}
>
</el-table>

const methods = {
? cellClick(row, column) {
? ? if (focusCell.value !== `${row.index},${column.index}`) {
? ? ? ? focusCell.value = `${row.index},${column.index}`
? ? ? }
? }
}

那么關(guān)鍵來了,下拉框單元格聚焦的時(shí)候,我們才顯示下拉框,其他時(shí)候展示文本,輸入框類型單元格聚焦的時(shí)候不做處理,代碼該如何寫呢?

setup() {
  return () => {
    /** 輸入框類型渲染 */
    const inputDomRender = (scope, item) => (
      <el-input
        value={scope.row[item.prop]}
        on-input={e => methods.inputChange(e, scope, item)}
      />
    )
    /** 下拉框類型渲染 */
    const selectDomRender = (scope, item) => (
      (focusCell.value === `${scope.row.autoIndex},${scope.column.index}` ? <el-select
        value-key='id'
        value={scope.row[item.prop]}
        onChange={e => methods.selectChange(e, scope, item)}
      >
        {
          item.selects.map(item1 => {
            return <el-option
              key={item1.id}
              label={item1.label}
              value={item1.id}
            >
            </el-option>
          })
        }
      </el-select> : <div
        domPropsInnerHTML={methods.selectPerofrmance(scope.row[item.prop], item.prop)}></div>)
    )
    return <el-table
      on-cell-click={methods.cellClick}
    >
    {
      decorateHeader.map((item: TableLabel) => {
        return <el-table-column
          width={item.width}
          label={item.label}
          align={item.align ? item.align : 'center'}
          prop={item.prop}
          scopedSlots={{
            default: scope => {
              return <div
              >
                {
                  item.mode !== 'input' ? selectDomRender(scope, item) : inputDomRender(scope, item)
                }
              </div>
            }
          }}
        >
        </el-table-column>
      })
    }
    </el-table>
  }
}

自此上述兩步優(yōu)化,其實(shí)就能使我們一次性加載幾千條可編輯數(shù)據(jù)不會(huì)卡頓了~

3、v-load-more自定義指令

源碼:

import {
  VNodeDirective
} from 'vue'
let timeout;
/** 設(shè)置表格滾動(dòng)區(qū)間 */
const setRowScrollArea = (topNum, showRowNum, binding) => {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(() => {
    binding.value.call(null, topNum, topNum + showRowNum);
  });
};
const loadMore= {
  bind(el: Element, _binding) {
    setTimeout(() => {
      // 創(chuàng)建虛擬滾動(dòng)條
      const selectWrap = el.querySelector('.el-table__body-wrapper');
      const selectTbody = selectWrap.querySelector('table tbody');
      const createElementTR = document.createElement('tr');
      createElementTR.id = 'virtual-scroll'
      selectTbody.append(createElementTR); // 先行將虛擬滾動(dòng)條加入進(jìn)來
    })
  },
  componentUpdated(el: Element, binding: VNodeDirective, vnode, oldVnode) {
    setTimeout(() => {
      const dataSize = vnode.data.attrs['data-size'];
      const oldDataSize = oldVnode.data.attrs['data-size'];
      // 當(dāng)數(shù)量相同時(shí),表明當(dāng)前未發(fā)生更新,減少后續(xù)操作
      if (dataSize === oldDataSize) {
        return;
      }
      const selectWrap = el.querySelector('.el-table__body-wrapper');
      const selectTbody = selectWrap.querySelector('table tbody');
      const selectRow = selectWrap.querySelector('table tr');
      // 當(dāng)一行都沒有,說明無數(shù)據(jù)渲染,但一般邏輯都不會(huì)進(jìn)入這里
      if (!selectRow) {
        return;
      }
      const rowHeight = selectRow.clientHeight;
      // 能夠在當(dāng)前顯示區(qū)的展示條數(shù),本項(xiàng)目就是11條
      const showRowNum = Math.round(selectWrap.clientHeight / rowHeight);
      const createElementTRHeight = (dataSize - showRowNum) * rowHeight;
      const createElementTR = selectTbody.querySelector('#virtual-scroll')
      // 監(jiān)聽滾動(dòng)后事件
      selectWrap.addEventListener('scroll', function() {
        let topPx = this.scrollTop;
        let topNum = Math.round(topPx / rowHeight);
        const minTopNum = dataSize - showRowNum;
        if (topNum > minTopNum) {
          topNum = minTopNum;
        }
        if (topNum < 0) {
          topNum = 0;
          topPx = 0;
        }
        selectTbody.setAttribute('style', `transform: translateY(${topPx}px)`);
        // 本來觸底的話,應(yīng)該設(shè)置為0,但是觸底后 就沒有滾動(dòng)條了
        createElementTR.setAttribute('style', `height: ${createElementTRHeight - topPx > 0 ? createElementTRHeight - topPx : rowHeight}px;`);
        setRowScrollArea(topNum, showRowNum, binding);
      })
    });
  }
}

export default loadMore

?不太了解自定義指令是啥的可以參考我另一篇博客

vue學(xué)習(xí)(6)自定義指令詳解及常見自定義指令

4、有趣拓展

1、我想在上述表格中對指定列實(shí)現(xiàn)高亮搜索怎么做?

當(dāng)有值時(shí)滾動(dòng)到指定位置,無值時(shí)不動(dòng),那首先在加載數(shù)據(jù)時(shí),要先寫下面代碼

 // 先讓他觸發(fā)滾動(dòng),才能讓virtual-scroll高度生成
table.$el.querySelector('.el-table__body-wrapper').scrollTo({ top: 1, behavior: 'smooth' })

輸入框執(zhí)行邏輯如下,防抖肯定是要的,然后搜索的列是?originName,當(dāng)發(fā)現(xiàn)有搜索到值時(shí),找到第一個(gè)被匹配到的行索引,然后去計(jì)算表格應(yīng)該滾動(dòng)到哪個(gè)高度位置,然后滾動(dòng)

    /**
     * 滾動(dòng)定位到表格指定位置
     * @param flag 是否能執(zhí)行滾動(dòng)的標(biāo)志
     * @returns
     */
    scrollToTable: () => $debounce(function() {
      // 當(dāng)沒有值時(shí),不進(jìn)行搜索
      if (dialogSearchKey.value) {
        const vmEl = table.value.$el;
        const selectWrap = vmEl.querySelector('.el-table__body-wrapper')
        if (vmEl) {
          const autoIndex = result.value.find((item: TableDataItem) => {
            return item.originName.indexOf(dialogSearchKey.value) !== -1
          })?.autoIndex ?? -1
          if (autoIndex !== -1) {
            scrollToIndex(selectWrap, autoIndex)
          }
        }
      }
    }, 500, false),
    /**
     * 表格滾動(dòng)到指定索引值行
     * @param selectWrap 表格dom
     * @param autoIndex 索引
     */
    scrollToIndex(selectWrap, autoIndex) {
      const showNum = 12 // 當(dāng)顯示條數(shù)小于次數(shù)時(shí),不進(jìn)行滾動(dòng)操作
      const topPx = autoIndex * columnHeight.value
      if (autoIndex > showNum) {
        selectWrap.scrollTo({ top: topPx, behavior: 'smooth' })
      }
    }

?然后高亮被搜索文字源碼如下:

setup() {
  return () => {
    return <el-table
      on-cell-click={methods.cellClick}
    >
    {
      decorateHeader.map((item: TableLabel) => {
        return <el-table-column
          width={item.width}
          label={item.label}
          align={item.align ? item.align : 'center'}
          prop={item.prop}
          scopedSlots={{
            default: scope => {
              return <div
              >
                <div
                  class='multiline'
                  domPropsInnerHTML={methods.textRender(scope.row[item.prop], item.prop)}
                />
              </div>
            }
          }}
        >
        </el-table-column>
      })
    }
    </el-table>
  }
}

?props.heightLight ?為輸入框的搜索關(guān)鍵詞

    /**
     * 文字渲染
     * @param word 被渲染的文字
     * @param prop 屬性名
     * @returns 替換后的渲染文字
     */
    textRender(word: string, prop: string): string {
      const reg = new RegExp(`${props.heightLight}`, 'ig')
      // 有搜索關(guān)鍵詞 && 是否有該子字符串
      if (props.heightLight && word.indexOf(props.heightLight) !== -1) {
        return word.replace(reg, `<font color='red'>$&</font>`)
      // 正常返回的列
      } else {
        return word
      }
    }

---本篇還是相當(dāng)實(shí)用,喜歡就一鍵三連吧~歡迎評論---文章來源地址http://www.zghlxwxcb.cn/news/detail-449688.html

到了這里,關(guān)于【Element-ui】el-table大數(shù)據(jù)量渲染卡頓問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 使用element-ui中的el-table回顯已選中數(shù)據(jù)時(shí)toggleRowSelection報(bào)錯(cuò)

    使用element-ui中的el-table回顯已選中數(shù)據(jù)時(shí)toggleRowSelection報(bào)錯(cuò)

    最近在寫一個(gè)后臺(tái),需要在表格中多選,然后點(diǎn)擊編輯按鈕的時(shí)候,需要回顯已經(jīng)選中的表單項(xiàng) 之前根據(jù)以上代碼,就可以實(shí)現(xiàn)回顯,但是這次沒有,還報(bào)了一個(gè)錯(cuò),報(bào)錯(cuò)如下 找了一下原因,這個(gè)回顯是一個(gè)彈框,我在剛進(jìn)頁面就走了這部分邏輯,相當(dāng)于在請求接口的時(shí)候

    2024年02月10日
    瀏覽(22)
  • 【element-ui】使用el-checkbox完成el-table表格數(shù)據(jù)的全選操作

    【element-ui】使用el-checkbox完成el-table表格數(shù)據(jù)的全選操作

    需求:表格有一列為勾選框列,表格下面有單獨(dú)的按鈕本頁勾選和全部勾選,跨頁狀態(tài)可以保存回顯,如下圖所示: 思路:使用一個(gè)數(shù)組[]存儲(chǔ)每一頁是否全選的狀態(tài),再使用{}來存儲(chǔ)數(shù)據(jù)的所有選中狀態(tài),其中key為對應(yīng)的頁碼,value為每一頁的選中數(shù)據(jù)【核心?】 1、el-tab

    2024年02月11日
    瀏覽(28)
  • vue中數(shù)據(jù)滾動(dòng)顯示 實(shí)現(xiàn)Element-UI中el-table內(nèi)數(shù)據(jù)的懶加載

    工作中我們經(jīng)常會(huì)用到element-ui組件庫中的le-table組件來展示數(shù)據(jù),但當(dāng)table的數(shù)據(jù)源數(shù)量過大的時(shí)候統(tǒng)一展示可能會(huì)出現(xiàn)頁面卡頓,且會(huì)影響用戶體驗(yàn),為此我們可以嘗試對el-table中的數(shù)據(jù)做懶加載的效果展示: 1. 掛在階段監(jiān)聽el-table的scroll滾動(dòng)事件 2. 當(dāng)table表格滾動(dòng)條的位置

    2023年04月08日
    瀏覽(17)
  • element-ui的樹形表格el-table懶加載lazy子節(jié)點(diǎn)修改數(shù)據(jù)后局部刷新

    在使用element-ui的樹形表格(el-table)懶加載(lazy),并使用了懶加載,出現(xiàn)了一個(gè)問題,在對當(dāng)前節(jié)點(diǎn)添加、修改、刪除一個(gè)子節(jié)點(diǎn)數(shù)據(jù)時(shí),當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)數(shù)據(jù)并不自動(dòng)刷新出來。element-ui官方?jīng)]有提供子節(jié)點(diǎn)修改數(shù)據(jù)后局部刷新方法。 首先,在data(){}中定義一個(gè)maps:new Map();

    2024年02月12日
    瀏覽(23)
  • 【vue】element-ui、el-table使用V-for循環(huán)動(dòng)態(tài)添加表頭和數(shù)據(jù)

    【vue】element-ui、el-table使用V-for循環(huán)動(dòng)態(tài)添加表頭和數(shù)據(jù)

    參考鏈接 https://blog.csdn.net/xz1589155358/article/details/126597271

    2024年02月11日
    瀏覽(28)
  • element-ui中的el-table合并單元格

    element-ui中的el-table合并單元格

    在寫項(xiàng)目的時(shí)候有時(shí)候會(huì)經(jīng)常遇到把行和列合并起來的情況,因?yàn)橛行?shù)據(jù)是重復(fù)渲染的,不合并行列會(huì)使表格看起來非常的混亂,如下: ?而我們想要的數(shù)據(jù)是下面這種情況,將重復(fù)的行進(jìn)行合并,使表格看起來簡單明了,如下: ? 1:html部分 所謂的合并行就是將多行相同

    2024年02月10日
    瀏覽(28)
  • [element-ui] el-table點(diǎn)擊高亮當(dāng)前行

    1、highlight-current-row 2、:row-class-name=“tableRowClassName”,需要借助@row-click=\\\"handleRowClick\\\"獲取當(dāng)前點(diǎn)擊行的下標(biāo) 參考: elementUI中table點(diǎn)擊高亮當(dāng)前行的兩種方式

    2024年03月21日
    瀏覽(31)
  • [element-ui] el-table行添加陰影懸浮效果

    問題: 在el-table每一行獲得焦點(diǎn)與鼠標(biāo)經(jīng)過時(shí),顯示一個(gè)整行的陰影懸浮效果 沒有什么效果 原因: box-shadow對display:table-row元素是不起作用的 解決方案: 弊端 給el-table行加陰影的問題算是解決了,但是卻導(dǎo)致表格內(nèi)容無法操作 1、通常,項(xiàng)目設(shè)計(jì)中,el-table會(huì)帶一些按鈕,比如

    2024年02月04日
    瀏覽(30)
  • element-ui el-table 樹形結(jié)構(gòu) 父子級聯(lián)動(dòng)

    el-table 表格 為 select 和 select-all 設(shè)置回調(diào)函數(shù) 簡要數(shù)據(jù)格式 單選 全選 操作 ids 不再設(shè)置 selection-change 回調(diào)函數(shù),直接監(jiān)聽ids 感謝 element-ui el-table 實(shí)現(xiàn)全選且父級子級聯(lián)動(dòng) 提供的思路 另附 el-table 文檔

    2024年02月10日
    瀏覽(108)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包