如何实现el-tabs标签页的可编辑功能

如何实现el-tabs标签页的可编辑功能?

目标是实现el-tabs标签页的标题可以修改;

目前我的思路是给el-tab-pane元素添加一个input输入框,点击时触发选择框,鼠标移开时保存输入文字,但不知道代码该如何写;点击保存后如何把修改后的标题渲染到页面上

这是我已有的代码,展示了el-tabs标签页

框架语言是vue+JS,使用了Element组件库;
tableList是要渲染的内容数组,格式如下:

tableList:[
  {  
    name:'title1',
    content:[
        {  
            name:'title1',
            value: 1                 
        },{  
            name:'title1',
            value: 1                 
        },{  
            name:'title1',
            value: 1                 
        }
      },
       {  
    name:'title2',
    content:[
        {  
            name:'title2',
            value: 2                 
        },{  
            name:'title2',
            value: 2                
        },{  
            name:'title2',
            value: 2               
        }
      }
    ]
]

代码

<el-tabs type="card" v-model="defaultValue" :before-leave="beforeLeave" closable  @tab-remove="removeTab">
      <el-tab-pane v-for="item in tableList" :name="item.name" :label="item.name">
        { item.name}}
              
          
         -->
        <span slot="label" :contenteditable="contenteditable">
          {{ item.name }}
          <el-button type="text" v-on:click="handleEdit"><i :class="contenteditable ? 'el-icon-check' : 'el-icon-edit'" >i>el-button>
        span>
        <el-row :gutter="20">
          <vuedraggable
            v-model="item.value"
            handle=".dargBtn"
            @end="end"
            :move="onMove"
            :options="{animation:800}"
          >
          <el-col :span="6" 
            v-for="obj in item.content" 
            :key="obj.id"
            class="preViewCard">
            <el-card :body-style="{ padding: '0px' }">
              <div class="preViewDiv dargBtn">
                <div class="demo-image__preview">
                   <span>{{obj.value}}span>
                div>
            
                <el-button-group class="button" v-if="isEdit">
                  <el-button
                    size="mini"
                    type="primary"
                    icon="el-icon-edit"
                    style="width: 50%"
                    @click="handleUpdate(obj)"
                  >el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    style="width: 50%"
                    icon="el-icon-delete"
                    @click="handleDelete(obj)"
                  >el-button>
                el-button-group>
              div>
            el-card>
          el-col>
        vuedraggable>
        el-row>
      el-tab-pane>
    el-tabs>


你的思路很正确,在handleEdit切换显示input, 然后给input绑定一个onblur事件,在onblur事件的回调中,切换显示tab标题,并把input的值保存在tabList的相应的元素的name上面去

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    很感谢您的问题,不过我需要指出您提供的参考资料似乎与您的问题不太相关。对于您的问题,以下是一个可能的解决方案:

    1. 在el-tab-pane元素内添加一个input输入框,并绑定一个v-model指令来保存用户输入的文本。同时,这个输入框的display设置为none来隐藏它。
    <el-tab-pane label="CPU占用 TOP5">
      <div class="tab-title-container">
        <span class="tab-title-text">{{tabTitle}}</span>
        <input class="tab-title-input" v-model="tabTitle" @blur="saveTabTitle" style="display:none;">
      </div>
      <cpu-chart />
    </el-tab-pane>
    
    data(){
      return{
        tabTitle: 'CPU占用 TOP5'
      }
    },
    methods:{
      saveTabTitle(){
        //在这里保存用户输入的文本
      },
      editTabTitle(){
        const titleText = this.$el.querySelector('.tab-title-text');
        const titleInput = this.$el.querySelector('.tab-title-input');
        titleText.style.display = 'none';
        titleInput.style.display = 'inline-block';
        titleInput.select();
      }
    }
    
    1. 为标签页标题添加一个点击事件,来触发上一步中新添加的input输入框的显示,并为标签页标题绑定一个双击事件来触发这个点击事件。
    <el-tabs type="border-card" style="width: 50%; float: left">
      <el-tab-pane label="{{tabTitle}}" @dblclick="editTabTitle">
        <div class="tab-title-container">
          <span class="tab-title-text">{{tabTitle}}</span>
          <input class="tab-title-input" v-model="tabTitle" @blur="saveTabTitle" style="display:none;">
        </div>
        <cpu-chart />
      </el-tab-pane>
      <el-tab-pane label="内存使用 TOP5">
        <memory-chart />
      </el-tab-pane>
    </el-tabs>
    
    methods:{
      //...上一步中的代码
      editTabTitle(){
        //通过调用$nextTick方法,确保DOM元素已经完全生成后再绑定点击事件
        this.$nextTick(()=>{
          const titleText = this.$el.querySelector('.tab-title-text');
          titleText.addEventListener('click', ()=>{
            this.$emit('edit-title');
          })
        });
      }
    }
    
    1. 在要实现标签页功能的父组件中监听edit-title事件来调用editTabTitle方法,从而显示input输入框。同时,在saveTabTitle方法中获取到用户输入的文本并将其更新到当前标签页的label属性上。
    <el-tabs-wrapper>
      <el-tabs type="border-card" style="width: 50%; float: left">
        <el-tab-pane :label="tabTitle" @dblclick="editTabTitle" @edit-title="editTabTitle">
          <div class="tab-title-container">
            <span class="tab-title-text">{{tabTitle}}</span>
            <input class="tab-title-input" v-model="tabTitle" @blur="saveTabTitle" style="display:none;">
          </div>
          <cpu-chart />
        </el-tab-pane>
        <el-tab-pane label="内存使用 TOP5">
          <memory-chart />
        </el-tab-pane>
      </el-tabs>
    </el-tabs-wrapper>
    
    <template>
      <div>
        <el-tabs-wrapper>
         <!--  el-tabs标签页和表格内容的代码 -->
        </el-tabs-wrapper>
      </div>
    </template>
    
    <script>
    import ElTabs from 'element-ui/lib/tabs';
    import ElTabPane from 'element-ui/lib/tab-pane';
    
    export default {
      components: {
        'el-tabs-wrapper': {
          components: {ElTabs, ElTabPane},
          template: `<el-tabs v-bind='$attrs' @tab-click="$emit('tab-click')">
                        <slot></slot>
                      </el-tabs>`
        },
        //其他子组件的代码
      },
      data(){
        return{
          tabTitle: 'CPU占用 TOP5'
        }
      },
      methods:{
        //...上面的两个方法的代码
        saveTabTitle(){
          const titleText = this.$el.querySelector('.tab-title-text');
          const titleInput = this.$el.querySelector('.tab-title-input');
          titleText.textContent = this.tabTitle;
          titleText.style.display = 'inline-block';
          titleInput.style.display = 'none';
        }
      }
    }
    </script>
    

    通过以上三个步骤的实现,您应该可以很轻松地实现一个可以编辑标签页标题的el-tabs组件,并将修改后的标签页标题显示出来。不过这个实现方式还有一些问题:如果一个标签页的标题很长,而它所在的el-tabs组件非常短,则显示出来的标签页标题可能会被截断。对于这个问题的解决,您可能需要使用某些css技巧来实现自适应宽度。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^