LLINK2233 2021-04-23 10:09 采纳率: 100%
浏览 702
已采纳

如何实现Tabs标签页的可编辑功能?

目标是实现Tabs标签页的文字可以修改;

目前我的思路是给Tab元素添加一个input输入框,点击时触发,鼠标移开时保存输入文字,但不知道代码该如何写;

这是我已有的代码,展示了Tabs标签页,并实现了新增删除功能;

框架语言是React+JS,使用了Antd组件库;

import { Tabs, Input } from 'antd';
import React from 'react';

const { TabPane } = Tabs;

const initialPanes = [
  { title: 'Tab 1', content: 'Content of Tab 1', key: '1' },
  { title: 'Tab 2', content: 'Content of Tab 2', key: '2' },
  {
    title: 'Tab 3',
    content: 'Content of Tab 3',
    key: '3',
  },
];

class Demo extends React.Component {
  newTabIndex = 0;

  state = {
    activeKey: initialPanes[0].key,
    panes: initialPanes,
  };

  onChange = (activeKey) => {
    this.setState({ activeKey });
  };

  onEdit = (targetKey, action) => {
    this[action](targetKey);
  };

  add = () => {
    const { panes } = this.state;
    const activeKey = `newTab${this.newTabIndex++}`;
    const newPanes = [...panes];
    newPanes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey });
    this.setState({
      panes: newPanes,
      activeKey,
    });
  };

  remove = (targetKey) => {
    const { panes, activeKey } = this.state;
    let newActiveKey = activeKey;
    let lastIndex;
    panes.forEach((pane, i) => {
      if (pane.key === targetKey) {
        lastIndex = i - 1;
      }
    });
    const newPanes = panes.filter((pane) => pane.key !== targetKey);
    if (newPanes.length && newActiveKey === targetKey) {
      if (lastIndex >= 0) {
        newActiveKey = newPanes[lastIndex].key;
      } else {
        newActiveKey = newPanes[0].key;
      }
    }
    this.setState({
      panes: newPanes,
      activeKey: newActiveKey,
    });
  };

  render() {
    const { panes, activeKey } = this.state;
    return (
      // eslint-disable-next-line react/react-in-jsx-scope
      // eslint-disable-next-line react/jsx-filename-extension
      <Tabs
        type="editable-card"
        onChange={this.onChange}
        activeKey={activeKey}
        onEdit={this.onEdit}
      >
        <Input type="text" />
        {panes.map((pane) => (
          <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>
            {pane.content}
          </TabPane>
        ))}
      </Tabs>
    );
  }
}

export default Demo;

如果大佬愿意提供具体的代码的话,万分感谢!

  • 写回答

2条回答 默认 最新

  • 上官熊猫 2021-04-23 14:31
    关注

    最开始我使用了给元素添加contenteditable属性,也是最简单的一种方式,但会有一个问题,在第一次点击该tab时该属性生效,但页面上元素还不是可编辑状态,需要点击第二次才生效;

    第二种方式动态加input,完整示例代码如下,可根据你的代码稍作更改就可以了:

    import React, { Component } from "react";
    import { Tabs, Input } from "antd";
    const { TabPane } = Tabs;
    export default class Add extends Component {
      state = {
        tabList: [
          {
            id: "1",
            title: "标签一",
          },
          {
            id: "2",
            title: "标签二",
          },
          {
            id: "3",
            title: "标签三",
          },
        ],
        activeKey: "0",
      };
      render() {
        return (
          <div>
            <Tabs defaultActiveKey="1" onChange={this.callback}>
              {this.state.tabList.map((item) => (
                <TabPane tab={this.tabDom(item)} key={item.id}></TabPane>
              ))}
            </Tabs>
          </div>
        );
      }
      //tabs的change事件
      callback = (key) => {
        this.setState({ activeKey: key });
      };
      //渲染tab内容,并判断当前tab是否需要编辑
      tabDom = (item) => {
        return (
          <>
            {this.state.activeKey !== item.id ? (
              <span style={{ outline: "none" }}>{item.title}</span>
            ) : (
              <Input
                style={{ width: "80px" }}
                value={item.title}
                onChange={this.inputChange.bind(this, item.id)}
              />
            )}
          </>
        );
      };
      //监听输入框事件
      inputChange = (id, e) => {
        let { tabList } = this.state;
        tabList.forEach((item) => {
          if (item.id === id) {
            item.title = e.target.value;
          }
        });
        this.setState({ tabList });
      };
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 VB.NET2022如何生成发布成exe文件
  • ¥30 matlab appdesigner私有函数嵌套整合
  • ¥15 给我一个openharmony跑通webrtc实现视频会议的简单demo项目,sdk为12
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?
  • ¥15 求SC-LIWC词典!
  • ¥20 有关esp8266连接阿里云
  • ¥15 C# 调用Bartender打印机打印