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

news/2024/12/23 9:25:40/

根据自己的需求都可以改

这里写自定义目录标题

    • 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/news/1557429.html

相关文章

【蓝桥杯每日一题】扫雷——暴力搜索

扫雷 蓝桥杯每日一题 2024-12-20 扫雷 暴力搜索 题目大意 在一个 n 行 m 列的方格图上有一些位置有地雷&#xff0c;另外一些位置为空。 请为每个空位置标一个整数&#xff0c;表示周围八个相邻的方格中有多少个地雷。 解题思路 今天算是水了一道暴力搜索题&#xff0c;还是接着…

计算机毕业设计Python+Vue.js游戏推荐系统 Steam游戏推荐系统 Django Flask 游 戏可视化 游戏数据分析 游戏大数据 爬虫 机

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

PHP与AJAX:实现动态网页的完美结合

PHP与AJAX&#xff1a;实现动态网页的完美结合 在现代Web开发中&#xff0c;用户体验至关重要。为了提升用户交互性&#xff0c;开发者常常需要实现动态网页&#xff0c;而AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;技术与PHP的结合为此提供了强有力的支持…

混合开发环境---使用编程AI辅助开发Qt

文章目录 [toc]1、说明2、演示视频 1、说明 新时代的浪潮早就已经来临&#xff0c;上不了船的人终将被抛弃&#xff0c;合理使用AI辅助开发、提升效率是大趋势 注意&#xff1a;不要被AI奴隶 合理使用AI辅助编程&#xff0c;十倍提升效率。 大部分的编程AI都有vs code插件&…

Yolo11改进策略:主干网络改进|FastVit与Yolo11完美融合,重参数重构Yolo11网络(全网首发)

文章目录 摘要FastViT:一种使用结构重新参数化的快速混合视觉变换器1、简介2、相关工作3、体系结构3.1、概述3.2、FastViT3.2.1、重新参数化跳过连接3.2.2、线性训练时间过参数化3.2.3、大核卷积4、实验4.1、图像分类4.2、鲁棒性评价4.3、3D Hand网格估计4.4、语义分割和目标检…

微信小程序实现二维码海报保存分享功能

首先在写这个二维码分享海报的时候试过很多方法&#xff0c;比如&#xff1a;canvas中的这个createCanvasContext创建上下文的方法&#xff0c;去网上一搜就是一大堆&#xff0c;但其实这个方法已经被废弃了。Canvas 实例&#xff0c;可通过 SelectorQuery 获取。这是绘制背景图…

自动生成元启发式算法:大语言模型在优化领域的新应用

近年来&#xff0c;随着大语言模型&#xff08;LLM&#xff09;技术的快速发展&#xff0c;这些模型在算法自动化设计中的潜力引起了广泛关注。特别是在元启发式算法设计领域&#xff0c;研究人员开始利用LLM生成新型优化算法&#xff0c;为复杂问题求解提供了更多可能性。 元…

STM32-笔记7-继电器定时开闭

1、复制02项目&#xff0c;重命名08-继电器定时开闭 打开项目工程 在\Drivers\BSP\该路径下&#xff0c;新建alarm文件夹&#xff0c;该文件夹下里面包含alarm.c和alarm.h文件 加载进该项目中 为什么这里使用的是 这个单词&#xff0c;而不是继电器&#xff08;relay&#…