refactor: 更新u-tabs组件使用方式及样式调整

This commit is contained in:
pikachu1995@126.com
2026-07-01 10:07:55 +08:00
parent dc2bef455a
commit 6654c1de51
16 changed files with 246 additions and 153 deletions

View File

@@ -1,24 +1,26 @@
{ // launch.json 配置了启动调试时相关设置configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
{
// launch.json 配置了启动调试时相关设置configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"app-plus" :
"version" : "0.0",
"configurations" : [
{
"app-plus" : {
"launchtype" : "remote"
},
"default" :
{
"default" : {
"launchtype" : "remote"
},
"h5" :
{
"h5" : {
"launchtype" : "remote"
},
"mp-weixin" :
{
"mp-weixin" : {
"launchtype" : "remote"
},
"type" : "uniCloud"
},
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

View File

@@ -415,8 +415,6 @@ export default {
mounted() {
this.formatSku(this.goodsSpec);
console.log("goodsDetail",this.goodsDetail)
}
};
</script>
@@ -437,9 +435,9 @@ export default {
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
::v-deep.u-icon-plus,
.u-icon-minus,
.u-icon-disabled {
::v-deep .u-icon-plus,
::v-deep .u-icon-minus,
::v-deep .u-icon-disabled {
height: 30rpx !important;
background: #fff !important;
}
@@ -541,7 +539,7 @@ export default {
color: #999;
margin-left: 10rpx;
::v-deep span {
.goods-price-bigshow {
font-size: 30rpx;
}
}

View File

@@ -79,20 +79,15 @@ export default {
this.$emit("input", !this.value);
},
getStatusBar() {
let promise = new Promise((resolve, reject) => {
uni.getSystemInfo({
success: function (e) {
let customBar;
const windowInfo = uni.getWindowInfo();
// #ifdef H5
customBar = e.statusBarHeight + e.windowTop;
return Promise.resolve(
(windowInfo.statusBarHeight || 0) + (windowInfo.windowTop || 0)
);
// #endif
// #ifndef H5
return Promise.resolve(windowInfo.statusBarHeight || 0);
// #endif
resolve(customBar);
},
});
});
return promise;
},
async popupsPosition() {
let statusBar = await this.getStatusBar();
@@ -104,6 +99,10 @@ export default {
size: true,
},
(data) => {
if (!data) {
resolve();
return;
}
let width = data.width;
let height = data.height;
@@ -154,8 +153,7 @@ export default {
return promise;
},
getPlacement(x, y) {
let width = uni.getSystemInfoSync().windowWidth;
let height = uni.getSystemInfoSync().windowHeight;
const { windowWidth: width, windowHeight: height } = uni.getWindowInfo();
if (x > width / 2 && y > height / 2) {
return "bottom-end";
} else if (x < width / 2 && y < height / 2) {
@@ -171,20 +169,21 @@ export default {
}
},
dynamicGetY(y, gap) {
let height = uni.getSystemInfoSync().windowHeight;
const { windowHeight: height } = uni.getWindowInfo();
y = y < gap ? gap : y;
y = height - y < gap ? height - gap : y;
return y;
},
dynamicGetX(x, gap) {
let width = uni.getSystemInfoSync().windowWidth;
const { windowWidth: width } = uni.getWindowInfo();
x = x < gap ? gap : x;
x = width - x < gap ? width - gap : x;
return x;
},
transformRpx(params) {
return (params * uni.getSystemInfoSync().screenWidth) / 375;
const { screenWidth } = uni.getWindowInfo();
return (params * screenWidth) / 375;
},
},
watch: {

12
main.js
View File

@@ -10,9 +10,7 @@ import * as filterUtils from './utils/filters.js'
export function createApp() {
const app = createSSRApp(App)
// #ifdef MP-WEIXIN
// 微信开发者工具部分版本在输出 Vue warn 时会触发
// TypeError: Cannot read property '__global' of null自定义 handler 绕过默认路径
// uview-plus 内部会触发 Vue3 开发态告警(枚举组件实例 keys不影响运行
app.config.warnHandler = (msg, _instance, trace) => {
if (
typeof msg === 'string' &&
@@ -23,10 +21,12 @@ export function createApp() {
try {
console.warn(`[Vue warn]: ${msg}${trace || ''}`)
} catch (e) {
// 忽略开发者工具 console 代理异常
}
}
// #ifdef MP-WEIXIN
// 微信开发者工具部分版本在输出 Vue warn 时会触发
// TypeError: Cannot read property '__global' of null
// #endif
}
}
app.use(store)
app.use(uviewPlus)

View File

@@ -1,15 +1,12 @@
<template>
<div class="wrapper">
<u-tabs
class="coupon-tabs"
:list="list"
:is-scroll="false"
:active-color="lightColor"
:current="current"
@change="
(i) => {
current = i;
}
"
:scrollable="false"
:lineColor="lightColor"
:activeStyle="{ color: lightColor }"
v-model:current="current"
>
</u-tabs>
@@ -160,6 +157,11 @@ export default {
.wrapper {
background: #f9f9f9;
overflow: hidden;
.coupon-tabs {
width: 100%;
background: #fff;
}
}
.coupon-item {
display: flex;

View File

@@ -2,10 +2,10 @@
<view class="wrapper">
<u-tabs
:list="list"
:is-scroll="false"
:current="current"
@change="change"
:active-color="$lightColor"
:scrollable="false"
v-model:current="current"
:lineColor="lightColor"
:activeStyle="{ color: lightColor }"
></u-tabs>
@@ -53,6 +53,7 @@ export default {
data() {
return {
current:0,
lightColor: this.$lightColor,
list: [
{
name: "推广人资料",

View File

@@ -10,12 +10,12 @@
<template #center>
<view class="slot-wrap">
<u-tabs
:active-color="lightColor"
:lineColor="lightColor"
:activeStyle="{ color: lightColor }"
class="collect-tabs"
:list="navList"
:is-scroll="true"
:current="tabCurrentIndex"
@change="tabClick"
:scrollable="true"
v-model:current="tabCurrentIndex"
></u-tabs>
</view>
</template>
@@ -206,13 +206,6 @@
});
},
/**
* 顶部tab点击
*/
tabClick(index) {
this.tabCurrentIndex = index;
},
/**
* 查看商品详情
*/

View File

@@ -2,12 +2,12 @@
<view class="content">
<view class="u-tabs-box">
<u-tabs
bg-color="#fff"
:list="list"
:is-scroll="false"
:current="current"
:scrollable="false"
v-model:current="current"
@change="change"
:active-color="$lightColor"
:lineColor="$lightColor"
:activeStyle="{ color: $lightColor }"
></u-tabs>
</view>
<div class="u-tabs-search">
@@ -272,7 +272,8 @@ export default {
/**
* 切换tab页时初始化数据
*/
change(index) {
change(e) {
const index = typeof e === 'object' && e != null ? e.index : e;
this.current = index;
this.params = {
pageNumber: 1,

View File

@@ -2,8 +2,15 @@
<view>
<view class="wrap">
<view class="u-tabs-box">
<u-tabs :list="list" :is-scroll="false" inactive-color="#333" :current="current" class="utabs"
:active-color="$lightColor" @change="changeTab"></u-tabs>
<u-tabs
:list="list"
:scrollable="false"
:inactiveStyle="{ color: '#333' }"
v-model:current="current"
class="utabs"
:lineColor="$lightColor"
:activeStyle="{ color: $lightColor }"
></u-tabs>
</view>
<swiper class="swiper-box" :current="current" @change="changeSwiper" duration="500">
<swiper-item v-for="(item, listIndex) in list" :key="listIndex">
@@ -183,13 +190,6 @@ export default {
});
},
/**
* 点击tab触发
*/
changeTab(index) {
this.current = index;
},
/**
* 点击swiper
*/

View File

@@ -219,14 +219,14 @@
</u-col>
</u-row>
<u-row>
<u-col :offset="0" :span="4" class="tl" style="text-align: left"
>备注信息</u-col
>
<u-col :span="8" textAlign="right">
<u-col :offset="0" :span="4" class="tl">备注信息</u-col>
<u-col :span="8" textAlign="right" class="remark-col">
<u-input
style="text-align: right"
class="uinput"
v-model="remarkVal[index].remark"
border="none"
input-align="right"
placeholder="请输入备注信息"
/>
</u-col>
</u-row>
@@ -239,12 +239,15 @@
@callbackInvoice="callbackInvoice"
v-if="invoiceFlag"
/>
<u-select
@confirm="confirmDistribution"
<u-picker
v-model:show="shippingFlag"
v-if="shippingMethod.length != 0"
:list="shippingMethod"
></u-select>
:columns="[shippingMethod]"
keyName="label"
valueName="value"
title="配送方式"
@confirm="confirmDistribution"
></u-picker>
<div class="box box5" v-if="orderMessage.priceDetailDTO">
<div>
@@ -284,9 +287,9 @@
orderMessage.priceDetailDTO.goodsPrice != null
"
>
<u-col :offset="0" :span="9" @click="GET_Discount()">优惠券</u-col>
<u-col :offset="0" :span="8" @click="GET_Discount()">优惠券</u-col>
<u-col
:span="3"
:span="4"
v-if="
orderMessage.priceDetailDTO &&
orderMessage.priceDetailDTO.couponPrice
@@ -299,9 +302,11 @@
>
</u-col>
<!--unitPrice(orderMessage.priceDetailDTO.couponPrice) -->
<u-col :span="3" v-else textAlign="right" @click="GET_Discount()">
{{ orderMessage.canUseCoupons.length || "0" }} 张可用
<u-icon name="arrow-right"></u-icon>
<u-col :span="4" v-else textAlign="right" class="coupon-col" @click="GET_Discount()">
<view class="coupon-col__content">
<text>{{ orderMessage.canUseCoupons.length || "0" }} 张可用</text>
<u-icon name="arrow-right" size="14" color="#909399"></u-icon>
</view>
</u-col>
</u-row>
<div>
@@ -759,12 +764,16 @@ export default {
// 选择配送
async confirmDistribution(val) {
const selected = val?.value?.[0] || val?.[0];
if (!selected?.value) {
return;
}
let res = await API_Trade.setShipMethod({
shippingMethod: val[0].value,
shippingMethod: selected.value,
way: this.routerVal.way,
});
this.shippingText = val[0].value;
this.shippingText = selected.value;
if (res.data.success) {
this.getOrderList();
}
@@ -868,9 +877,21 @@ page {
}
.uinput {
::v-deep input {
text-align: right;
width: 100%;
::v-deep .u-input {
width: 100%;
}
::v-deep .u-input__content__field-wrapper__field {
text-align: right;
font-size: 28rpx;
}
}
.remark-col {
display: flex;
justify-content: flex-end;
}
.promotionNotice {
@@ -967,6 +988,15 @@ page {
text-align: right;
}
.coupon-col__content {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: nowrap;
gap: 4rpx;
white-space: nowrap;
}
.bar {
height: 4rpx;
overflow: hidden;

View File

@@ -461,34 +461,7 @@ export default {
},
},
mounted () {
const { windowHeight } = uni.getSystemInfoSync();
let bottomHeight = 0;
let topHeight = 0;
uni.getSystemInfo({
success: function (res) {
// res - 各种参数
let bottom = uni.createSelectorQuery().select(".page-bottom");
bottom
.boundingClientRect(function (data) {
if (data && data.height) {
//data - 各种参数
bottomHeight = data.height; // 获取元素宽度
}
})
.exec();
let top = uni.createSelectorQuery().select(".header");
top
.boundingClientRect(function (data) {
if (data && data.height) {
//data - 各种参数
topHeight = data.height; // 获取元素宽度
}
})
.exec();
},
});
this.productRefHeight = windowHeight - bottomHeight + "px";
this.calcProductHeight();
},
async onLoad (options) {
this.routerVal = options;
@@ -516,6 +489,19 @@ export default {
},
methods: {
calcProductHeight () {
this.$nextTick(() => {
const { windowHeight } = uni.getWindowInfo();
uni.createSelectorQuery()
.in(this)
.select('#pageBottom')
.boundingClientRect((data) => {
const bottomHeight = data && data.height ? data.height : 0;
this.productRefHeight = `${windowHeight - bottomHeight}px`;
})
.exec();
});
},
// 重新打开下架
reStartTakeDownSale(){
this.$refs.takeDownSale.show = true

View File

@@ -82,7 +82,13 @@
<!-- 基础店铺模式 -->
<div v-if="basePageData">
<u-tabs :list="tabs" :active-color="mainColor" :is-scroll="false" :current="current" @change="changeTab"></u-tabs>
<u-tabs
:list="tabs"
:lineColor="mainColor"
:activeStyle="{ color: mainColor }"
:scrollable="false"
v-model:current="current"
></u-tabs>
<div class="content" v-if="current == 0">
<u-empty style='margin-top:100rpx' v-if="goodsList.length == 0" class="empty" text='暂无商品信息'></u-empty>
<goodsTemplate style="width:100%;" v-else :res="goodsList" :storeName="false" />
@@ -396,11 +402,6 @@ export default {
});
},
/** 点击tab */
changeTab(index) {
this.current = index;
},
/**
* 店铺信息
*/

View File

@@ -9,7 +9,16 @@
<u-swiper @click="clickSwiper" class="swiper" keyName="image" :list="swiperImg">
</u-swiper>
<u-tabs :is-scroll="false" @change="changeTabs" :current="current" :active-color="activeColor" inactive-color="#606266" ref="tabs" :list="tabs"></u-tabs>
<u-tabs
:scrollable="false"
v-model:current="current"
@change="changeTabs"
:lineColor="activeColor"
:activeStyle="{ color: activeColor }"
:inactiveStyle="{ color: '#606266' }"
ref="tabs"
:list="tabs"
></u-tabs>
<div class="wrapper">
<!-- 直播中 全部 直播回放 -->
@@ -114,8 +123,7 @@ export default {
/**
* 点击标签栏切换
*/
changeTabs(index) {
this.current = index;
changeTabs() {
this.init();
},

View File

@@ -17,7 +17,7 @@
<image src="/static/emptyCart.png" mode="aspectFit"></image>
<view class="empty-tips">
空空如也
<navigator class="navigator" url="/pages/tabbar/home/index" open-type="switchTab">随便逛逛></navigator>
<navigator class="navigator" url="/pages/tabbar/home/index" open-type="switchTab">随便逛逛</navigator>
</view>
</view>
<!-- 店铺商品信息 -->

View File

@@ -1,7 +1,12 @@
<template>
<view>
<view>
<u-tabs :list="list" :is-scroll="false" :current="current" @change="change"></u-tabs>
<u-tabs
:list="list"
:scrollable="false"
v-model:current="current"
@change="change"
></u-tabs>
<view v-if="showLoading" style="width:500rpx;margin:0 auto;text-align: center;height:800rpx;line-height: 800rpx;">
<u-loading mode="flower" ></u-loading>
<text>正在加载中</text>
@@ -136,13 +141,13 @@
}
},
change(e) {
const index = typeof e === 'object' && e != null ? e.index : e;
this.showLoading = true;
console.log(e)
this.current = e;
if (e == 0) {
this.current = index;
if (index == 0) {
this.params.status = "UN_READY"
this.params.pageNumber = 1;
} else if (e == 1) {
} else if (index == 1) {
this.params.status = "ALREADY_READY"
this.params.pageNumber = 1;
}

View File

@@ -263,18 +263,85 @@ index 1ca7595..b1e4a3e 100644
+ * 原有 page/body 标签选择器与 [data-up-theme] 属性选择器,
+ * 在微信小程序组件级 wxss 中不被允许,会触发编译告警,故移除。 */
diff --git a/node_modules/uview-plus/components/u-tabs/u-tabs.vue b/node_modules/uview-plus/components/u-tabs/u-tabs.vue
index 46caac2..5736483 100644
index 46caac2..0989e2e 100644
--- a/node_modules/uview-plus/components/u-tabs/u-tabs.vue
+++ b/node_modules/uview-plus/components/u-tabs/u-tabs.vue
@@ -3,7 +3,7 @@
@@ -1,11 +1,11 @@
<template>
- <view class="u-tabs" :class="[customClass, shapeModeClass]">
+ <view class="u-tabs" :class="[customClass, shapeModeClass, scrollable ? '' : 'u-tabs--fixed']">
<view class="u-tabs__wrapper">
<slot name="left" />
<view class="u-tabs__wrapper__scroll-view-wrapper">
- <scroll-view :scroll-x="scrollable" :scroll-left="scrollLeft" scroll-with-animation
+ <scroll-view :scroll-x="scrollable" :scroll-left="scrollLeft" scroll-with-animation :enable-flex="true"
class="u-tabs__wrapper__scroll-view" :show-scrollbar="false" ref="u-tabs__wrapper__scroll-view">
<view class="u-tabs__wrapper__nav" ref="u-tabs__wrapper__nav">
- <view class="u-tabs__wrapper__nav" ref="u-tabs__wrapper__nav">
+ <view class="u-tabs__wrapper__nav" ref="u-tabs__wrapper__nav" :style="[!scrollable && { width: '100%' }]">
<view class="u-tabs__wrapper__nav__item" v-for="(item, index) in tabList" :key="index"
@tap="clickHandler(item, index)" @longpress="longPressHandler(item,index)"
:ref="`u-tabs__wrapper__nav__item-${index}`"
@@ -236,7 +236,7 @@
addUnit,
setLineLeft() {
const tabItem = this.tabList[this.innerCurrent];
- if (!tabItem) {
+ if (!tabItem || !tabItem.rect) {
return;
}
// 获取滑块该移动的位置
@@ -300,16 +300,22 @@
})
},
setScrollLeft() {
+ if (!this.scrollable) {
+ return;
+ }
// 当前活动tab的布局信息有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息
if (this.innerCurrent < 0) {
this.innerCurrent = 0;
}
const tabRect = this.tabList[this.innerCurrent]
+ if (!tabRect || !tabRect.rect) {
+ return;
+ }
// 累加得到当前item到左边的距离
const offsetLeft = this.tabList
.slice(0, this.innerCurrent)
.reduce((total, curr) => {
- return total + curr.rect.width
+ return total + (curr.rect ? curr.rect.width : 0)
}, 0)
// 此处为屏幕宽度
const windowWidth = getWindowInfo().windowWidth
@@ -550,5 +556,27 @@
background-color: #2a6bf6;
}
}
+
+ &--fixed {
+ width: 100%;
+
+ .u-tabs__wrapper {
+ width: 100%;
+ }
+
+ .u-tabs__wrapper__scroll-view-wrapper,
+ .u-tabs__wrapper__scroll-view {
+ width: 100%;
+ }
+
+ .u-tabs__wrapper__nav {
+ width: 100%;
+ }
+
+ .u-tabs__wrapper__nav__item {
+ flex: 1 !important;
+ min-width: 0;
+ }
+ }
}
</style>
diff --git a/node_modules/uview-plus/components/u-tag/theme-vars.scss b/node_modules/uview-plus/components/u-tag/theme-vars.scss
index bf38484..b1e4a3e 100644
--- a/node_modules/uview-plus/components/u-tag/theme-vars.scss