Vue封装element-UI Tag组件(包含右键点击+纵向滚动)

张英范
2023-12-01

在components中新建一个vue文件,写入如下代码:

<template>
    <div class="tags-view">
        <el-scrollbar style="height: 60px; white-space: nowrap" ref="elscrollbar">
            <el-tag :key="tag.index" v-for="(tag,index) in Tages" closable :disable-transitions="true"  @close="TagsClose(tag,index)" 
            @click="tagsjump(tag)" class="tags" @contextmenu.prevent.native="openMenu($event,tag,index)"
            :class="$route.fullPath == tag.path?'eltagbg':''">
            <i :class="$route.fullPath == tag.path?'cricle':''"></i>
              {{tag.title}}  //这里是显示的文字
            </el-tag>
        </el-scrollbar>
        <ul class="contextmenu" id="menu" v-show="menu">
            <li @click="tagrefresh">刷新</li>
            <li @click="closeTag">关闭</li>
            <li @click="closeOther">关闭其他</li>
            <li @click="closeAll">关闭所有</li>
        </ul>
    </div>
</template>

<script>
export default {
    props:{
        Tages:{  // 传过来的数组
            type:Array,
            required:true
        }
    },
    data() {
        return {
            menu : false, //右键
            tagsingle:{}, //右键当前数据
            tagindex:''  //右键当前下标
        };
    },
     mounted() {
        // 调用初始化方法,这里一定是在DOM加载之后调用
        this.scrollInit();
    },
    methods: {
        // 刷新
        tagrefresh(){
            this.menu = false
            this.$router.replace({
                path: '/Back',
                query: {
                t: Date.now()
                }
            })
            //这里是解决重复路由的报错
            if(this.$route.fullPath != this.tagsingle.path){
                this.$router.push(this.tagsingle.path)
            }
        },
        // 关闭
        closeTag(){
            this.menu = false
            this.TagsClose(this.tagsingle,this.tagindex)
        },
        // 关闭其他
        closeOther(){
            this.menu = false
            // arr.splice(下标,多少个位数,新替换上去的值)
            this.Tages.splice(0, this.Tages.length,this.Tages[this.tagindex]);
            if(this.$route.fullPath != this.tagsingle.path ){
                this.$router.push(this.tagsingle.path)
            }
        },
        // 关闭所有
        closeAll(){
            this.menu = false
            this.Tages.splice(0, this.Tages.length,{
                title:'首页',
                path:'/Home/Page'
            });
            if(this.$route.fullPath != '/Home/Page' ){
                this.$router.push('/Home/Page')
            }
        },
        // 标签右键
        openMenu(event,tag,index){
       		//获取到右键当前的tag和下标
            this.tagsingle = tag
            this.tagindex = index
            this.menu = false
            this.menu = true
            var menu = document.querySelector('#menu')
            document.addEventListener('click', this.foo) // 给整个document添加监听鼠标事件,点击任何位置执行foo方法
            menu.style.display = "block";
            menu.style.left = event.clientX - 0 + 'px'
            menu.style.top = event.clientY - 0 + 'px'
        },
        //点击任何地方取消右键
        foo(){
            this.menu = false
        },
        // 标签跳转
        tagsjump(tag){
            if(this.$route.fullPath != tag.path){
                this.$router.push(tag.path) 
            }
        },
        // 关闭单个标签
        TagsClose(tag,index) {
            const delItem = this.Tages.splice(index, 1)[0];
            const item = this.Tages[index] ? this.Tages[index] : this.Tages[index - 1];
            if (item) {
                delItem.path === this.$route.fullPath && this.$router.push(item.path);
                this.activepath = this.$route.fullPath
            } else {
                if(this.$route.fullPath == '/Home/Page'){
                this.Tages.push({
                    title:'首页',
                    path:'/Home/Page'
                })
                }else{
                this.Tages.push({
                    title:'首页',
                    path:'/Home/Page'
                })
                this.$router.push(this.Tages[0].path);
                }
            }
        },
        scrollInit() {
            // 获取要绑定事件的元素
            const scrollDiv = this.$refs["elscrollbar"].$refs["wrap"];
            // document.addEventListener('DOMMouseScroll', handler, false)
            // 添加滚轮滚动监听事件,一般是用下面的方法,上面的是火狐的写法
            scrollDiv.addEventListener("mousewheel", handler, false);
            // 滚动事件的出来函数
            function handler(event) {
                // 获取滚动方向
                const detail = event.wheelDelta || event.detail;
                // 定义滚动方向,其实也可以在赋值的时候写
                const moveForwardStep = 1;
                const moveBackStep = -1;
                // 定义滚动距离
                let step = 0;
                // 判断滚动方向,这里的100可以改,代表滚动幅度,也就是说滚动幅度是自定义的
                if (detail < 0) {
                step = moveForwardStep * 100;
                } else {
                step = moveBackStep * 100;
                }
                // 对需要滚动的元素进行滚动操作
                scrollDiv.scrollLeft += step;
            }
        },

    },
};
</script>

<style lang="scss" scoped>
//tag
.el-tag{
  background: #fff;
  color: #495060;
}
.eltagbg{
  background: rgb(72, 164, 250);
  color: #fff;
}
.cricle{
    display: inline-block;
    width: 8px;
    height: 8px;
    background-color: white;
    border-radius: 13px;
}
.tags-view{
  width: 100%;
  height: 40px;
  background: #fff;
  line-height: 40px;

  .tags{
    margin-left: 10px;
    cursor: pointer;
    position: relative;

  }
  .contextmenu{
    margin:0;
    padding: 5px 0;
    background: #fff;
    position: absolute;
    z-index:10;
    border-radius: 5px;
    box-shadow: 2px 2px 3px 0 rgb(0 0 0 / 30%);
    li{
      list-style: none;
      line-height: 25px;
      font-size: 14px;
      color: #333;
      padding: 0 10px;
      cursor: pointer;
    }
    li:hover{
      background: rgb(236, 233, 233);
    }
  }
  ::v-deep .el-icon-close {
    color: #333 !important;
    transition: all 0.3s;
    &:hover {
      background-color: red !important;
      color: #fff !important;
    }
  }
}
</style>

直接在需要使用的页面引入注册即可

import Tag from '@/components/Tagenca.vue';
export default{
	components: {
	  Tag,
	},
	data() {
    return {
      Tags:[],
    };
  },
}


模板使用

<Tag :Tages="Tags"></Tag>
 类似资料: