vue 实现Tabs 组件自定义删除+拖拽排序功能

前言:目前市面上有很多实现拖拽排序功能的插件和方法,本节不过多累述,只讲一种:vue的v-dragging内置组件

效果图:

主图:

 拖拽中的图:

 1. 安装

npm install awe-dnd --save

2. 在 main.js 文件中引入

import VueDND from 'awe-dnd'
Vue.use(VueDND)

3. v-dragging 调用

v-dragging="{ list: tabList, item: item, group: 'item' }"

4. v-dragging 参数

5. 重构带删除的Tabs组件

因为element的el-tabs组件不支持拖拽排序功能,并且该标签封装了多层嵌套div,不利于拖动排序的时候操作内部的DOM节点,所以首先重写一个带删除的Tab组件

  • 重构DOM
  • <span class="all-app" :class="{tabActiveAll:activeAllFlag}" @click="changeTab">{{$t('apps.all_app')}}</span>
    <div class=""tab-container>
        <div class="tab-box" v-for="(item, index) in categoryList" v-dragging="{ list: categoryList, item: item, group: 'item' }" :key="item.id" :class="{tabActive:currentIndex === index}" @click="changeTab(item, index)">
             // Tab标签超出长度显示el-tooltip提示  placement为提示显示位置  disabled为提示是否显示(本案例是文字长度超过了7个才显示)
             <el-tooltip class="item" effect="dark" :content="item.name" placement="right" :disabled="item.name.length < 7">
                 <div class="tab-pane"> {{item.name}}</div>
             </el-tooltip>
             // 删除图标
             <i class="el-icon-close" @click.stop="removeTab(item.id)"></i>
        </div>
    </div>
  • Data中定义数据

<script>
     export default {
         data() {
             return {
                 categoryList: [],  // Tab 数组
                 tabActive: '', // 当前点击的Tab
                 currentIndex: 0, // 当前点击的Tab索引
                 activeAllFlag: true // 是否选中全部应用
             }
         }
     }
</script>

6. methods方法中使用

Tab 自定义删除功能

   // 点击Tab
    changeTab(tab, index) {
        this.currentTabId = tab.id
        // 动态添加tabActive样式,模拟element Tab被选中,呈现下边线样式
        this.currentIndex = index
        // index为undefined时, 为点击的是全部应用
        if (index === undefined) {
            this.currentTabId = ''、
            // 动态添加tabActiveAll类名,模拟element Tab被选中,呈现下边线样式
            this.activeAllFlag = true
        } else {
            // 未点击全部应用,则动态移除当前样式
            this.activeAllFlag = false
        }
    },
    // 删除Tab标签
    removeTab(targetId) {
        let data = []
        let currentId = ''
        // 当前删除Tab ID
        this.categoryList.forEach(item => {
            if (item.id === targetId) currentId = item.id
        })
        // 调用删除接口,时时同步数据
        delTab(currentId).then(res => {
            this.$message.success('删除成功')
        })
     }

Tab 拖拽排序功能

    mounted() {
        this.$dragging.$on('dragend', () => {
            this.orderIds = []
            this.categoryList.forEach((item) => {
                this.orderIds.push(item.id)
            })
            // 推荐此种前后端交互:
             此接口交互,是将拖拽后重组的ID集合,传给接口,时时更新数据,和v-dragging 数据处理结构保存一致
            changeOrder(this.orderIds).then((res) => {
                this.$message.success('拖拽排序成功')
            })
        })
    }

7. 模拟element Tab 标签样式

<style lang="scss" scoped>
    .all-app {
        height: 48px;
        cursor: pointer;
        color: #1F2226;
        font-size: 16px;
    }
    .tabActiveAll {
        height: 47px;
        color: #526ECC;
        border-bottom: 2px solid #526ECC;
    }
    .tabActive {
        height: 48px;
        border-bottom: 2px solid #526ECC;
        .tab-pane {
            color: #526ECC!important;
        }
        .el-icon-close {
            color: #526ECC;
        }
    }
    .tab-container {
        display: flex;
        height: 50px;
        line-height: 50px;
        .tab-box {
            max-width: 140px;
            display: flex;
            margin-left: 30px;
            cursor: pointer;
            .tab-pane {
                max-width: 97px;
                height: 48px;
                cursor: pointer;
                color: #1F2226;
                font-size: 16px;
                text-align: center;
                margin-right: 7px;
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
            }
            .el-icon-close {
                color: #1F2226;
                line-height: 51px;
            }
        }
    }
</style>

转载自:

掘金https://juejin.cn/post/7021066895478489095

end...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值