如何实现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;

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

最开始我使用了给元素添加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 });
  };
}

 

html5提供了一个contenteditable 属性 让普通的标签也能具有编辑功能 contenteditable="true"