用表头设置控制表格内列的排序和显示隐藏

项目背景 : react + ant

需求 :  点击表头设置弹窗 , 拖拽可控制外部表格列的排序 , 开关可控制外部表格列的显示和隐藏

实现效果如下 :


注意 :  1. 拖拽效果参考了ant-table中的拖拽效果(这块代码放最后)  
            2. 后台反了json格式(用is_show控制显示和隐藏 , 我给他传递sort值来控制排序 , 后台返回格式如下~)
            3. 将拖拽和显示隐藏后的内容存到了localStorage

实现 : 
 

  const [biaotouData, setBiaotouData] = useState([
    {
      key: 'orderNumber',
      orderNumber: '工单编号'
    },
    {
      key: 'placeName',
      orderNumber: '地点'
    },
.....
 ])

  const biaotouColumns = [
    {
      render: () => <DragHandle />            // 让拖拽图标在第一列
    }, 
     {
      title: (
        <span style={{ color: dropdownOpen1 ? ' var(--main-bg)' : '#333' }}>
          {t('HeaderColumn')}
        </span>
      ),
      dataIndex: 'orderNumber',
      align: 'center',
      key: 'orderNumber'
    },

    {
      title: (
        <span style={{ color: dropdownOpen2 ? ' var(--main-bg)' : '#333' }}>
          {t('WhetherDisplayed')}
        </span>
      ),
      align: 'center',
      dataIndex: 'placeName',
      key: 'placeName',
      render: (data, record) => (
        <div>
          <Switch
            checked={getIsShowForColumn(record.key)} // 使用getIsShowForColumn函数获取当前列的is_show状态
            onChange={data => handleSwitchChange(record, data)}
          />
        </div>
      )
    }
  ]

  const sortedColumns = sortColumnsBySort(tableColumns) // 排序后的列,传递给外部的table
  const [biaotouModal, setBiaotouModal] = useState(false) // 控制表头设置的显示隐藏

  const [sortData, setSortData] = useState() //拿到表头列的显示状态
  // 打开表头设置弹窗
  const biaotouHandle = async () => {
    setBiaotouModal(true)
    const res = await getList7({ type: 3 })
    console.log('res.titleSetContent', res.titleSetContent)
    setSortData(JSON.parse(res.titleSetContent))
  }

  // 排序
  function sortColumnsBySort (columns) {
    return columns.sort((a, b) => a.sort - b.sort)
  }

  // 在渲染Switch的地方,查找当前列对应的is_show值
  const getIsShowForColumn = columnName => {
    return sortData?.find(item => item.name === columnName)?.is_show ?? true // 如果找不到,默认为true
  }

  // 当拖拽和显示和隐藏后外部表格更新
  useEffect(() => {
    if (sortData) {
      const updateAndHandleResponse = async () => {
        const res = await getEditMethod3({
          titleSetContent: JSON.stringify(sortData),
          type: 3
        })

        localStorage.setItem('hiddenColumns1', JSON.stringify(sortData))

        const updatedColumns = tableColumns.map(column => {
          if (
            sortData.find(
              item => item.name === column.key && item.is_show === false
            )
          ) {
            return { ...column, hidden: true }
          } else if (
            sortData.find(
              item => item.name === column.key && item.is_show === true
            )
          ) {
            return { ...column, hidden: false }
          }
          return column
        })

        setTableColumns(updatedColumns)
      }
      updateAndHandleResponse()
    }
  }, [sortData, biaotouModal])

  // 当拖拽和显示和隐藏后外部表格更新
  useEffect(() => {
    const storedHiddenColumns = localStorage.getItem('hiddenColumns1')

    if (storedHiddenColumns) {
      const hiddenColumns = JSON.parse(storedHiddenColumns)

      const updatedTableColumns = tableColumns.map(column => {
        if (
          hiddenColumns.find(
            item => item.name === column.key && item.is_show === false
          )
        ) {
          return { ...column, hidden: true }
        } else if (
          hiddenColumns.find(
            item => item.name === column.key && item.is_show === true
          )
        ) {
          return { ...column, hidden: false }
        }
        return column
      })

      setTableColumns(updatedTableColumns)
    }

    return () => {

    }
  }, [])

------------------------------------------------这是表头设置的table 和 外部的table 和 拖拽代码--------------
 

 // 表头设置里的table      
      <DndContext
                    modifiers={[restrictToVerticalAxis]}
                    onDragEnd={onDragEnd}
                  >
                    <SortableContext
                      items={biaotouData.map(i => i?.key)}
                      strategy={verticalListSortingStrategy}
                    >
                      <SimpleBar
                        style={{
                          maxHeight: '600px',
                          overflowY: 'auto',
                          display: 'block'
                        }}
                        className='SimpleBar'
                      >
                        <Table
                          columns={biaotouColumns}
                          dataSource={biaotouData}
                          loading={loading}
                          pagination={false}
                          components={{
                            body: {
                              row: Row1
                            }
                          }}
                          rowKey='key'
                        ></Table>
                      </SimpleBar>
                    </SortableContext>
                  </DndContext>



// 外部的table
     {TableCom2({ loading, data, columns: sortedColumns })}


  //被拖拽后
  const onDragEnd = ({ active, over }) => {
    console.log('active', active)
    if (active.id !== over?.id) {
      setBiaotouData(biaotouData => {
        const activeIndex = biaotouData.findIndex(
          item => item?.key === active.id
        )
        const overIndex = biaotouData.findIndex(item => item?.key === over?.id)

        const newData = arrayMove(biaotouData, activeIndex, overIndex).map(
          (item, index) => ({
            ...item,
            sort: index + 1
          })
        )
        // 创建一个新的映射以方便查找
        const keyToSortMap = newData.reduce((map, item) => {
          map[item.key] = item.sort
          return map
        }, {})
        console.log('keyToSortMap', keyToSortMap)

        // 遍历sortData,根据name查找对应的新Data中的sort值并赋值
        sortData.forEach(item => {
          if (item.name in keyToSortMap) {
            item.sort = keyToSortMap[item.name]
          }
        })

        // 遍历sortData,根据name查找对应的新Data中的sort值并赋值
        tableColumns.forEach(item => {
          if (item.key in keyToSortMap) {
            item.sort = keyToSortMap[item.key]
          }
        })
        setTableColumns(tableColumns)
        localStorage.setItem('hiddenColumns1', JSON.stringify(sortData))

        console.log('Updated sortData:', sortData)
        console.log('sortData', sortData)
        console.log('newData', newData)
        console.log('tableColumns', tableColumns)

        getEditMethod3({
          titleSetContent: JSON.stringify(sortData),
          type: 3
        })

        return arrayMove(biaotouData, activeIndex, overIndex)
      })
    }
  }


//控制是否可以选中表格里的文字
const Row1 = props => {
  const {
    attributes,
    listeners,
    setNodeRef,
    setActivatorNodeRef,
    transform,
    transition,
    isDragging
  } = useSortable({
    id: props['data-row-key']
  })
  const style = {
    ...props.style,
    transform: CSS.Translate.toString(transform),
    transition,
    ...(isDragging
      ? {
          position: 'relative',
          zIndex: 9999
        }
      : {})
  }
  const contextValue = useMemo(
    () => ({
      setActivatorNodeRef,
      listeners
    }),
    [setActivatorNodeRef, listeners]
  )
  return (
    <RowContext.Provider value={contextValue}>
      <tr {...props} ref={setNodeRef} style={style} {...attributes} />
    </RowContext.Provider>
  )
}

//拖拽图标
const DragHandle = () => {
  const { setActivatorNodeRef, listeners } = useContext(RowContext)
  return (
    <Button
      type='text'
      size='small'
      icon={<HolderOutlined />}
      style={{
        cursor: 'move'
      }}
      ref={setActivatorNodeRef}
      {...listeners}
    />
  )
}

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Element UI 表格组件提供了 `column` 属性来设置表格的列信息,可以通过该属性来隐藏/显示列和排序列。 首先,设置表格的列信息,例如: ```html <el-table :data="tableData" :column="columns"></el-table> ``` 其中,`columns` 是一个数组,包含了每一列的配置信息,例如: ```js columns: [ { label: '姓名', prop: 'name', sortable: true, show: true }, { label: '年龄', prop: 'age', sortable: true, show: true }, { label: '性别', prop: 'gender', sortable: false, show: true } ] ``` 上面的配置中,每一列都有一个 `show` 属性,用于表示该列是否显示。初始情况下,所有列都是显示的。 接下来,我们可以通过一个复选框列表来控制列的显示/隐藏,例如: ```html <el-checkbox-group v-model="showColumns"> <el-checkbox label="name">姓名</el-checkbox> <el-checkbox label="age">年龄</el-checkbox> <el-checkbox label="gender">性别</el-checkbox> </el-checkbox-group> ``` 其中,`showColumns` 是一个数组,包含了所有可选列的标识符。当某个复选框被选中时,将对应列的 `show` 属性设置为 `true`,否则设置为 `false`,例如: ```js watch: { showColumns: function(val) { this.columns.forEach(column => { column.show = val.indexOf(column.prop) !== -1 }) } } ``` 最后,我们可以通过 `sortable` 属性来设置是否允许用户对表格进行排序。当 `sortable` 为 `true` 时,用户可以点击表头来对该列进行升序/降序排序,例如: ```js columns: [ { label: '姓名', prop: 'name', sortable: true, show: true }, // ... ] ``` 这样,我们就实现了表格隐藏显示列和列排序功能。完整的代码示例如下: ```html <template> <div> <el-checkbox-group v-model="showColumns"> <el-checkbox label="name">姓名</el-checkbox> <el-checkbox label="age">年龄</el-checkbox> <el-checkbox label="gender">性别</el-checkbox> </el-checkbox-group> <el-table :data="tableData" :column="columns"></el-table> </div> </template> <script> export default { data() { return { tableData: [ { name: '张三', age: 18, gender: '男' }, { name: '李四', age: 20, gender: '女' }, { name: '王五', age: 22, gender: '男' } ], columns: [ { label: '姓名', prop: 'name', sortable: true, show: true }, { label: '年龄', prop: 'age', sortable: true, show: true }, { label: '性别', prop: 'gender', sortable: false, show: true } ], showColumns: ['name', 'age', 'gender'] } }, watch: { showColumns: function(val) { this.columns.forEach(column => { column.show = val.indexOf(column.prop) !== -1 }) } } } </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值