vue click on a menu to center a menu, move left and right to move the menu

Effect picture:

The core function is implemented by jquery. Considering the convenience of jquery to realize the scrolling animation of animation, you need to introduce jquery into index.html.

When a component is used in multiple places, you need to pass in domIndex to an absolute value to prevent the state of multiple components from being modified at the same time.

Code:

<!--测试文件-->
<template>
<div style="display:flex;">
    <span class="btn" @click="toLeft()">左</span>
    <div class="tagBox" :class="'tagBox'+domIndex">
        <div v-for="(item,index) in list" :key="index" class="tag" :ref="'tag'+index" :class="{'active':tagActive==index}" @click="clickTag(index)">
        {
   
   {item.name}}</div>
    </div>
    <span class="btn" @click="toRight()">右</span>
</div>
</template>

<script>
export default {
    name: '',
    props: {
        //节点索引,防止组件被多处使用时
        domIndex:{
            type:String,
            default:'0'
        }
    },
    components: {

    },
    data () {
        return {
            list:[{name:'苹果'},{name:'香蕉'},{name:'梨子'},{name:'葡萄'},{name:'菠萝'},{name:'苹果'},{name:'香蕉'},{name:'梨子'},{name:'葡萄'},{name:'菠萝'}],
            tagActive:0,
        }
    },
    mounted() {

    },
    methods: {
        toLeft(){
            if(this.tagActive==0){
                //提示用户第一项不能左移
            }else{
                this.tagActive-=1;
                this.move();
            }
        },
        toRight(){
            if(this.tagActive==this.list.length-1){
                //提示用户最后一项不能右移
            }else{
                this.tagActive+=1;
                this.move();
            }
        },
        //移动
        move(){
            let index=this.tagActive;
            let obj=this.$refs['tag'+index][0];//dom本身、子元素宽度
            let box=$(`.tagBox${this.domIndex}`);  //盒子
            //保持选中元素在中间,为了效果好看,最左边和最右边不保证在中间。
            //滚动距离=子元素相对父元素的滚动距离-盒子宽度/2(保证元素在中间)-子元素的宽度/2(因为获取子元素的位置始终是左上角的,所以需要居中)
            box.animate({scrollLeft:obj.offsetLeft-box.width()/2+obj.offsetWidth/2});
        },
        //点击中心元素
        clickTag(index){
            this.tagActive=index;
            this.move();
        }
    },
}
</script>

<style scoped lang='less'>
.btn{
    display: flex;
    align-items: center;
    justify-content: center;
    width:80px;
    background: #409EFF;
    border: 3px solid #328ce9;
    color: white;
    box-sizing: border-box;
}
.tagBox{
    width:300px;
    overflow:auto;
    display:flex;
    background:#ccc;
    white-space: nowrap;
    position:relative;/**需要设置在盒子设置相对定位,不然offsetLeft会基于整个页面body */
}
.tagBox::-webkit-scrollbar {
    display: none;
}
.tagBox::-webkit-scrollbar {
    width: 0;
    background: 0 0;
}
.tag{
    width:80px;
    text-align:center;
    margin:5px;
    padding:5px 5px;
    background:white;
    flex-shrink: 0;
}
.tag.active{
    background:#67C23A;
    color:white;
}
</style>

Guess you like

Origin blog.csdn.net/qq_42740797/article/details/123071947