vue 组件水平滚动_基于 vue 封装 横向滑动 tab栏 组件

本文介绍基于Vue封装的可水平滚动的Tab栏组件,涵盖了父子组件传值、DOM操作、点击高亮、屏幕宽度计算等技术点。通过示例展示了两种实现方式,并提供了详细的代码实现和界面效果。
摘要由CSDN通过智能技术生成

基于vue封装的横向滚动tab栏组件

知识点:1,父子组件传值 ,2,vue如何获取dom元素(ref,$refs),3,点击高亮,4,获取屏幕宽度(window.innerWidth),5,左偏移量(offsetLeft),6,当前元素宽度(offsetWidth),7,左滚动(scrollLeft);

有两种写法:一,逻辑代码在父组件中实现(本篇);二,逻辑代码在子组件中实现(第二篇博客中); 如果一个项目中多次使用,建议采用第二种。

界面效果 (可横向滑动)

父组件

:listArray="list"

:current="current"

@change="changeTab"

ref="tab"

>

import HeaderTab from "../components/HeaderTab";

export default {

name: "home",

components: {

HeaderTab,

},

data() {

return {

list:[],

current: 1,

imgSrc: "",

};

},

created() {

this.getlist();

this.imgSrc = require("../assets/img/search.png");

},

methods: {

getlist() {

this.list = [

{ id: 1, name: "关注" },

{ id: 2, name: "推荐" },

{ id: 3, name: "科技" },

{ id: 4, name: "财经" },

{ id: 5, name: "生活" },

{ id: 6, name: "职场" },

{ id: 7, name: "时尚" },

{ id: 8, name: "汽车" },

{ id: 9, name: "娱乐" },

];

},

changeTab(index, e) {

this.current = index; // 高亮当前

let tab = this.$refs.tab.$refs.headertab; // 包裹 ul的 div

let tabitem = this.$refs.tab.$refs.tabitem; // 包裹 li的 ul

let winWidth = window.innerWidth; // 当前屏幕的宽度

let liList = e.target; // 当前点击的li

if (liList) { // 当前li左偏移, li的宽度, 中间值(当前屏幕的宽度 - li的宽度) /2, 目标值 (中间值 - 当前li左偏移), 整个ul的宽度

let liLeft = liList.offsetLeft,

liWidth = liList.offsetWidth,

liCenter = (winWidth - liWidth) / 2,

liTarget = liLeft - liCenter;

let ulWidth = tabitem.offsetWidth;

if (liTarget < 0) {

tab.scrollLeft = 0;

return;

}

// winWidth(375) - ulWidth(436) = -61

if (liTarget < winWidth - ulWidth) {

tab.scrollLeft = -(winWidth - ulWidth) + liWidth;

return;

}

tab.scrollLeft = liTarget;

}

},

},

};

子组件

  • v-for="(item, index) in listArray"

    :key="index"

    :class="index == current ? 'activeheader' : ''"

    @click="getTab(index, $event)"

    >

    {{ item.name }}

export default {

name: "HeaderTab",

props: {

listArray: {

type: Array,

},

current:{

type:Number,

default:1,

}

},

data() {

return {

};

},

methods: {

getTab(index, e) {

this.$emit('change',index,e)

},

},

};

.header {

width: 100%;

height: 45px;

background-color: #fff;

display: flex;

}

.header_tab {

width: 90%;

height: 45px;

display: flex;

flex-wrap: nowrap;

overflow: scroll;

}

.header_tab::-webkit-scrollbar {

display: none;

}

ul {

display: inline-block;

white-space: nowrap;

}

li {

display: inline-block;

line-height: 45px;

padding: 0px 10px;

font-size: 14px;

color: #333;

// 点击高亮某一项时,将原来的字体变大,会导致没有高亮的元素距离上面有空隙,会出现纵向滚动条

margin-top: -1px;

}

.activeheader {

font-size: 16px;

font-weight: 700;

position: relative;

}

.activeheader:after {

position: absolute;

content: "";

width: 35%;

height: 2px;

bottom: 0;

left: 15px;

background-color: #333;

border-radius: 50px;

}

.header_search {

width: 10%;

height: 45px;

position: relative;

}

.header_search img {

position: absolute;

top: 0;

right: 0;

bottom: 0;

left: 0;

margin: auto;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值