uniapp v-tabs修改了几项功能,根据自己需求自己改

ops/2024/12/21 18:12:46/

根据自己的需求都可以改

这里写自定义目录标题

    • 1.数组中的名字过长,导致滑动异常
    • 2.change 事件拿不到当前点击的数据,通过index在原数组中查找得到所需要的id 各种字段麻烦
    • 3.添加指定下标下新加红点显示样式

在这里插入图片描述

1.数组中的名字过长,导致滑动异常

2.change 事件拿不到当前点击的数据,通过index在原数组中查找得到所需要的id 各种字段麻烦

直接帮点前点击的传上来 change方法中 直接获取 item ,index

<v-tabs v-model="current" v-model:tipsindex='tipsindex' ellipsisNums='3'  v-model:tipsnums='tipsnums'  isEllipsis :tabs="tabs" @change="changeTab">
const changeTab =(item,index)=>{console.log(item)console.log(index)
}

3.添加指定下标下新加红点显示样式

一般情况下只能会在某一项上添加红点,所以只用传显示的下标以及数量,每一项都显示的话这种场景直接在作者的源码里v-tabs.vue里面 slot这里直接添加一个布局,显示每一列的数量就行,

直觉贴代码

props.js 里面新加
  // 名字过长是否缩写isEllipsis: {type: Boolean,default: false},// 超过数量ellipsisNums: {type: [Number, String],default: 5},// 红点显示的下标tipsindex: {type: [Number, String],default: 0},// 红点显示的数量tipsnums: {type: [Number, String],default: 0},// 红点背景颜色tipbg: {type:String,default: 'red'},// 红点颜色tipcolor: {type:String,default: '#ff'}
v-tabs.vue  直接复制
<template><view class="v-tabs"><scroll-view:id="getDomId":scroll-x="scroll":scroll-left="scroll ? scrollLeft : 0":scroll-with-animation="scroll":style="{ position: fixed ? 'fixed' : 'relative', zIndex, width: '100%' }"><viewclass="v-tabs__container":style="{display: scroll ? 'inline-flex' : 'flex',whiteSpace: scroll ? 'nowrap' : 'normal',background: bgColor,height,padding}"><view:class="['v-tabs__container-item', { disabled: !!v.disabled }, { active: current == i }]"v-for="(v, i) in tabs":key="i":style="{color: current == i ? activeColor : color,fontSize: current == i ? fontSize : fontSize,fontWeight: bold && current == i ? 'bold' : '',justifyContent: !scroll ? 'center' : '',flex: scroll ? '' : 1,padding: paddingItem}"@click="change(v,i)"><slot :row="v" :index="i"><view class="name">{{ field ? limitText( v[field]) : limitText(v) }}</view><view class="tip" v-if="tipsindex===i">{{tipsnums}}</view></slot></view><template v-if="!!tabs.length"><viewv-if="!pills":class="['v-tabs__container-line', { animation: lineAnimation }]":style="{background: lineColor,width: lineWidth + 'px',height: lineHeight,borderRadius: lineRadius,transform: `translate3d(${lineLeft}px, 0, 0)`}" /><viewv-else:class="['v-tabs__container-pills', { animation: lineAnimation }]":style="{background: pillsColor,borderRadius: pillsBorderRadius,width: currentWidth + 'px',transform: `translate3d(${pillsLeft}px, 0, 0)`,height}" /></template></view></scroll-view><!-- fixed 的站位高度 --><view class="v-tabs__placeholder" :style="{ height: fixed ? height : '0', padding }"></view></view>
</template><script>
import { startMicroTask, throttle } from './utils'
import props from './props'
/*** v-tabs* @property {Number} value 选中的下标* @property {Array} tabs tabs 列表* @property {String} bgColor = '#fff' 背景颜色* @property {String} color = '#333' 默认颜色* @property {String} activeColor = '#2979ff' 选中文字颜色* @property {String} fontSize = '28rpx' 默认文字大小* @property {String} activeFontSize = '28rpx' 选中文字大小* @property {Boolean} bold = [true | false] 选中文字是否加粗* @property {Boolean} scroll = [true | false] 是否滚动* @property {String} height = '60rpx' tab 的高度* @property {String} lineHeight = '10rpx' 下划线的高度* @property {String} lineColor = '#2979ff' 下划线的颜色* @property {Number} lineScale = 0.5 下划线的宽度缩放比例* @property {String} lineRadius = '10rpx' 下划线圆角* @property {Boolean} pills = [true | false] 是否胶囊样式* @property {String} pillsColor = '#2979ff' 胶囊背景色* @property {String} pillsBorderRadius = '10rpx' 胶囊圆角大小* @property {String} field 如果是对象,显示的键名* @property {Boolean} fixed = [true | false] 是否固定* @property {String} paddingItem = '0 22rpx' 选项的边距* @property {Boolean} lineAnimation = [true | false] 下划线是否有动画* @property {Number} zIndex = 1993 默认层级* @property {Boolean} isEllipsis  = [true | false] 名字过长是否简写...* @property {Boolean} ellipsisNums  =  名字超过几个* @property {Boolean} tipsindex  =  红点要显示的下标* @property {Boolean} tipsnums  =  红点要显示的数量 * @event {Function(current)} change 改变标签触发*/ 
export default {name: 'VTabs',props,// #ifdef VUE3emits: ['update:modelValue', 'change'],// #endifdata() {return {lineWidth: 30,currentWidth: 0, // 当前选项的宽度lineLeft: 0, // 滑块距离左侧的位置pillsLeft: 0, // 胶囊距离左侧的位置scrollLeft: 0, // 距离左边的位置container: { width: 0, height: 0, left: 0, right: 0 }, // 容器的宽高,左右距离current: 0, // 当前选中项scrollWidth: 0 // 可以滚动的宽度}},computed: {getDomId() {const len = 16const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/const maxPos = $chars.lengthlet pwd = ''for (let i = 0; i < len; i++) {pwd += $chars.charAt(Math.floor(Math.random() * maxPos))}return `xfjpeter_${pwd}`}},watch: {// #ifdef VUE3modelValue: {// #endif// #ifdef VUE2value: {// #endifimmediate: true,handler(newVal) {this.current = newVal > -1 && newVal < this.tabs.length ? newVal : 0this.$nextTick(this.update)}}},methods: {limitText(val) {val += ''if (!val) returnif (!this.isEllipsis) return valreturn val.length > this.ellipsisNums ? `${val.slice(0, this.ellipsisNums)}...` : val},// 切换事件change: throttle(function(item,index) {const isDisabled = !!this.tabs[index].disabledif (this.current !== index && !isDisabled) {this.current = index// #ifdef VUE3this.$emit('update:modelValue', index)// #endif// #ifdef VUE2this.$emit('input', item,index)// #endifthis.$emit('change', item,index)}}, 300),createQueryHandler() {let query// #ifndef MP-ALIPAYquery = uni.createSelectorQuery().in(this)// #endif// #ifdef MP-ALIPAYquery = uni.createSelectorQuery()// #endifreturn query},update() {const _this = thisstartMicroTask(() => {// 没有列表的时候,不执行if (!this.tabs.length) return_this.createQueryHandler().select(`#${this.getDomId}`).boundingClientRect(data => {const { width, height, left, right } = data || {}// 获取容器的相关属性this.container = { width, height, left, right: right - width }_this.calcScrollWidth()_this.setScrollLeft()_this.setLine()}).exec()})},// 计算可以滚动的宽度calcScrollWidth(callback) {const view = this.createQueryHandler().select(`#${this.getDomId}`)view.fields({ scrollOffset: true })view.scrollOffset(res => {if (typeof callback === 'function') {callback(res)} else {// 获取滚动条的宽度this.scrollWidth = res.scrollWidth}}).exec()},// 设置滚动条滚动的进度setScrollLeft() {this.calcScrollWidth(res => {// 动态读取 scrollLeftlet scrollLeft = res.scrollLeftthis.createQueryHandler().select(`#${this.getDomId} .v-tabs__container-item.active`).boundingClientRect(data => {if (!data) return// 除开当前选项外容器的一半宽度let curHalfWidth = (this.container.width - data.width) / 2let scrollDiff = this.scrollWidth - this.container.width// 在原有滚动条的基础上 + (当前元素距离左侧的距离 - 计算的一半宽度) - 容器的外边距之类的scrollLeft += data.left - curHalfWidth - this.container.left// 已经滚动在左侧了if (scrollLeft < 0) scrollLeft = 0// 已经超出右侧了else if (scrollLeft > scrollDiff) scrollLeft = scrollDiffthis.scrollLeft = scrollLeft}).exec()})},setLine() {this.calcScrollWidth(res => {const scrollLeft = res.scrollLeftthis.createQueryHandler().select(`#${this.getDomId} .v-tabs__container-item.active`).boundingClientRect(data => {if (!data) returnif (this.pills) {this.currentWidth = data.widththis.pillsLeft = scrollLeft + data.left - this.container.left} else {this.lineWidth = data.width * this.lineScalethis.lineLeft = scrollLeft + data.left + (data.width - data.width * this.lineScale) / 2 - this.container.left}}).exec()})}}
}
</script><style lang="scss" scoped>
.v-tabs__container-item{position: relative !important;.tip{width: 14px;height: 14px;background: red;position: absolute;top: 0px;right: 0px;text-align: center;line-height: 14px;border-radius: 6px;color: #fff;}
}
.v-tabs {width: 100%;box-sizing: border-box;overflow: hidden;/* #ifdef H5 */::-webkit-scrollbar {display: none;}/* #endif */&__container {min-width: 100%;position: relative;display: inline-flex;align-items: center;white-space: nowrap;overflow: hidden;&-item {flex-shrink: 0;display: flex;align-items: center;height: 100%;position: relative;z-index: 10;transition: all 0.3s;white-space: nowrap;&.disabled {opacity: 0.5;color: #999;}}&-line {position: absolute;left: 0;bottom: 0;}&-pills {position: absolute;z-index: 9;}&-line,&-pills {&.animation {transition: all 0.3s linear;}}}
}</style>

组件中使用 index.vue

<template><view><!-- <son4></son4>--><view class="main"><view class="left"><v-tabs v-model="current" v-model:tipsindex='tipsindex' ellipsisNums='3'  v-model:tipsnums='tipsnums'  isEllipsis :tabs="tabs" @change="changeTab"></v-tabs></view><view class="right">站位</view></view></view>
</template><script setup>
import { ref,provide} from 'vue'
// import son4 from "../../components/son4.vue";
// let toChildValue = ref('传递给所有子集的数据')
// provide( 'toChildValue', toChildValue)let current  = ref(0)
let tipsindex  = ref(2)
let tipsnums  = ref(2)
let tabs  = ref([])// 模拟请求数据
setTimeout(()=>{tabs.value = ['军事', '国内', '新闻新闻新闻新闻新闻新闻新闻新闻', '军事', '国内', '新闻', '军事', '国内', '新闻']
},1500)
const changeTab =(item,index)=>{console.log(item)console.log(index)
}
// 模拟修改红点数量
setTimeout(()=>{tipsnums.value = 6
},6000)</script><style>
.main{width: 100%;height: 40px;background: pink;display: flex;
}
.left{flex: 1;width: 0;height: 40px;
}
.right{width: 100px;height: 40px;background: springgreen;
}
</style>

http://www.ppmy.cn/ops/143821.html

相关文章

STM32内部flash分区

STM32的内部Flash根据型号和容量的不同&#xff0c;分区方式可能有所差异&#xff0c;但通常都包含以下几个主要部分&#xff1a; 主存储器&#xff1a;这是内部Flash的主要部分&#xff0c;用于存放程序代码和数据常量。在STM32F4系列中&#xff0c;主存储器被划分为多个扇区…

Java面试被问到GC相关问题如何回答?

前言 众所周知&#xff0c;Java在运行时将内存划分为五个主要部分&#xff1a;程序计数器、虚拟机栈、本地方法栈、堆以及方法区。值得注意的是&#xff0c;程序计数器、虚拟机栈和本地方法栈这三个区域的内存管理相对简单&#xff0c;它们的生命周期与线程同步&#xff0c;即…

防止私接小路由器

电脑获取到IP地址不是DHCP服务器的IP地址段&#xff0c;导致整个公司网络瘫痪&#xff0c;这些故障现象通常80%原因是私接小路由器导致的&#xff0c;以下防止私接小路由器措施。 一、交换机配置DHCP Sooping DHCP snooping是一种DHCP安全特性&#xff0c;用于防止非法设备获…

计算机网络 八股青春版

什么是HTTP&#xff1f;HTTP和HTTPS的区别 HTTP HTTP是超文本运输协议&#xff0c;是一种无状态&#xff08;每次请求都是独立的&#xff09;的应用层协议。用于在客户端和服务器之间传输超文本数据&#xff08;如HTML文件&#xff09;。默认端口是80数据以明文形式传输&#…

网络直播带货查询系统设计与实现:SSM + JAVA 核心架构与 JSP 支撑

第四章 系统设计 4.1 系统体系结构 网络直播带货网站的结构图4-1所示&#xff1a; 图4-1 系统结构 模块包括主界面&#xff0c;主页、个人中心、用户管理、商品分类管理、商品信息管理、系统管理、订单管理等进行相应的操作。 登录系统结构图&#xff0c;如图4-2所示&#xf…

高效集成金蝶网店管理数据到旺店通·企业奇门的方案解析

拉取金蝶网店管理数据&#xff1a;从金蝶云星空到旺店通企业奇门的高效集成 在企业日常运营中&#xff0c;数据的高效流动和准确对接至关重要。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将金蝶云星空中的网店管理数据无缝集成到旺店通企…

Kubernetes(K8s)学习笔记

一、引言 Kubernetes&#xff08;简称K8s&#xff09;是一个开源的容器编排和管理平台&#xff0c;由Google主导开发&#xff0c;旨在自动化容器化应用程序的部署、扩展和管理。K8s以其强大的功能、高度的可扩展性和广泛的社区支持&#xff0c;已成为现代云原生应用架构的核心…

第N7周:调用Gensim库训练Word2Vec模型

文章目录 一、准备工作1.安装Gensim库2.对原始语料分词 二、训练Word2Vec模型三、模型应用1.计算词汇相似度2.找出不匹配的词汇3.计算词汇的词频 四、总结 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、…