從零開始-文件資源管理器-20-文件呈現(xiàn)排序

JavaScript 的 array sort 方法對字符串的排序有些問題。

純數(shù)字

[1, 2, 3, 11].sort()
=> [1, 11, 2, 3]

字符串

['a', 'e', 'b', 'c', 'd'].sort()
=> ['a', 'b', 'c', 'd', 'e']

數(shù)字加字符串

['a-1', 'a-2', 'a-2', 'a-11'].sort()
=> ['a-1', 'a-11', 'a-2', 'a-3']

上面的例子發(fā)現(xiàn),字符串的可以排序正常,數(shù)字的 11 會拍在 2 的前面。純數(shù)字的可以通過 sort((a, b) => a - b) 的回調(diào)控制掙錢排序。

如果涉及到"字符串+數(shù)字"的時候,簡單的 a - b 無法完成排序任務(wù)。

這里引用一個自然排序的依賴 natural-compare-lite可以正確處理文件名的排序問題。

開發(fā)

explorer

安裝依賴

pnpm i natural-compare-lite

pnpm i @types/natural-compare-lite -D

創(chuàng)建 sort 排序 context 組件,并創(chuàng)建四個排序方法

  • 時間的正排序與逆排序
  • 文件名正排序與逆排序

對文件名的排序使用 naturalCompare 依賴方法。

'use client'
import naturalCompare from 'natural-compare-lite'
import { ReaddirItemType } from '@/explorer-manager/src/type'
import createCtx from '@/lib/create-ctx'
import React from 'react'

export type SortAction = (a: ReaddirItemType, b: ReaddirItemType) => number

export const nameAscSort: SortAction = (a, b) => naturalCompare(a.name, b.name)
export const dateAscSort: SortAction = (a, b) => (a?.stat?.mtimeMs || 0) - (b?.stat?.mtimeMs || 0)
export const nameDescSort: SortAction = (a, b) => naturalCompare(b.name, a.name)
export const dateDescSort: SortAction = (a, b) => (b?.stat?.mtimeMs || 0) - (a?.stat?.mtimeMs || 0)

export const sortMap = {
  asc_name: nameAscSort,
  asc_date: dateAscSort,
  desc_name: nameDescSort,
  desc_date: dateDescSort,
}

export const SortContext = createCtx<'asc_name' | 'asc_date' | 'desc_name' | 'desc_date'>()

export const useSortStore = SortContext.useStore

export const useSortDispatch = SortContext.useDispatch

export const SortProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
  return <SortContext.ContextProvider value="asc_name">{children}</SortContext.ContextProvider>
}

創(chuàng)建一個控制排序的下拉菜單組件

'use client'
import React from 'react'
import { Button, Dropdown } from 'antd'
import { SortAscendingOutlined, SortDescendingOutlined } from '@ant-design/icons'
import { useSortDispatch, useSortStore } from '@/components/readdir-sort/sort-context'

const ReaddirSort: React.FC = () => {
  const sort = useSortStore()
  const sortDispatch = useSortDispatch()

  return (
    <Dropdown
      placement="top"
      arrow={true}
      trigger={['hover', 'click']}
      menu={{
        selectedKeys: [sort],
        items: [
          {
            key: 'asc_name',
            icon: <SortAscendingOutlined />,
            onClick: () => {
              sortDispatch('asc_name')
            },
            label: '名稱正排',
          },
          {
            key: 'desc_name',
            icon: <SortDescendingOutlined />,
            onClick: () => {
              sortDispatch('desc_name')
            },
            label: '名稱倒排',
          },
          {
            key: 'asc_date',
            icon: <SortAscendingOutlined />,
            onClick: () => {
              sortDispatch('asc_date')
            },
            label: '時間正排',
          },
          {
            key: 'desc_date',
            icon: <SortDescendingOutlined />,
            onClick: () => {
              sortDispatch('desc_date')
            },
            label: '時間倒排',
          },
        ],
      }}
    >
      <Button icon={<SortAscendingOutlined />} />
    </Dropdown>
  )
}

export default ReaddirSort

為 readdir-context 內(nèi)的 useReaddirContext 讀取 sort 屬性對 readdir_list 進行 sort 排序

export const useReaddirContext = () => {
  const readdir_list = ReaddirContext.useStore()
  const sort = useSortStore()

  return readdir_list.sort(sortMap[sort])
}

為保證能正確讀取到 useSortStore 屬性。需要將 SortProvider 插入 ReaddirProvider 上下文組件之前。

...

export const PathContextProvider: React.FC<React.ProviderProps<ReaddirListType>> = ({ value, children }) => {
  return (
    <SortProvider>
      <ReaddirProvider value={value}>
        ...
                        <VideoInfoProvider>{children}</VideoInfoProvider>
        ...
      </ReaddirProvider>
    </SortProvider>
  )
}

到此,對文件排序功能完成

效果

截屏2023-12-24 10.51.36.png

git-repo

yangWs29/share-explorer

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容