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

·  阅读 1159

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

效果图:

主图: image.png

拖拽中的图: image.png

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 参数

image.png

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('拖拽排序成功')
            })
        })
    },
复制代码
  1. 模拟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>
复制代码

end...

分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改