six_uniapp_0001
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
<style lang="scss" scoped>
|
||||
|
||||
|
||||
.phoneCom {
|
||||
position: fixed;
|
||||
width: 750rpx;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: transparent;
|
||||
z-index: v-bind(zIndex);
|
||||
|
||||
.phone-wifi {
|
||||
height: v-bind(wifi_px);
|
||||
}
|
||||
|
||||
.phone-nav {
|
||||
height: v-bind(nav_px_height);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.meun-height {
|
||||
height: v-bind(meun_px_height);
|
||||
width: 750rpx;
|
||||
display: flex;
|
||||
|
||||
.uniui-left {
|
||||
width: v-bind(rpxLeftWidth);
|
||||
display: flex;
|
||||
height: v-bind(meun_px_height);;
|
||||
}
|
||||
|
||||
.meun-widht-left {
|
||||
width: v-bind(divMeunWidht);
|
||||
height: v-bind(meun_px_height);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
:deep(.customClass-icon) {
|
||||
height: v-bind(meun_px_height);
|
||||
|
||||
text-align: center;
|
||||
line-height: v-bind(meun_px_height);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%); /* 关键:自身偏移回中心 */
|
||||
}
|
||||
|
||||
.meun-widht-rightimage_item {
|
||||
height: v-bind(imgWidthHeight);
|
||||
width: v-bind(imgWidthHeight);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%); /* 关键:自身偏移回中心 */
|
||||
}
|
||||
}
|
||||
|
||||
.meun-widht-middle {
|
||||
width: v-bind(divMeunWidhtMiddle);
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
align-self: center;
|
||||
height: calc(v-bind(flexMeunHeight) * 0.8);
|
||||
|
||||
&.light-background {
|
||||
background-color: #555555;
|
||||
height: calc(v-bind(flexMeunHeight) * 0.8);
|
||||
align-self: center;
|
||||
width: v-bind(divMeunWidhtMiddle);
|
||||
}
|
||||
}
|
||||
|
||||
.meun-widht-right {
|
||||
width: v-bind(divMeunWidht);
|
||||
height: v-bind(meun_px_height);;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
:deep(.customClass-icon) {
|
||||
height: v-bind(meun_px_height);
|
||||
text-align: center;
|
||||
line-height: v-bind(meun_px_height);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%); /* 关键:自身偏移回中心 */
|
||||
}
|
||||
|
||||
.meun-widht-rightimage_item {
|
||||
height: v-bind(imgWidthHeight);
|
||||
width: v-bind(imgWidthHeight);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%); /* 关键:自身偏移回中心 */
|
||||
}
|
||||
}
|
||||
|
||||
.FlexTitleWidth {
|
||||
width: v-bind(rpxFlexTitleWidth);
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: v-bind(meun_px_height);
|
||||
|
||||
.flex-title-text {
|
||||
width: v-bind(rpxFlexTitleWidth);
|
||||
height: v-bind(meun_px_height);
|
||||
line-height: v-bind(meun_px_height);
|
||||
}
|
||||
|
||||
.flex-title-slot {
|
||||
width: v-bind(rpxFlexTitleWidth);
|
||||
height: v-bind(meun_px_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<template>
|
||||
<view class="phoneCom">
|
||||
<view class="phone-wifi">
|
||||
<view class="status-wifi"></view>
|
||||
</view>
|
||||
<view v-if="navShow" class="phone-nav">
|
||||
<view class="meun-height">
|
||||
<view class="uniui-left"></view>
|
||||
<view class="meun-widht-left" @click="emit('homeLeft')">
|
||||
<wd-icon v-if="modelValue?.isShowLeft.showCom==='icon'"
|
||||
:classPrefix="modelValue?.isShowLeft.iconTextLeft.classPrefix"
|
||||
:name="modelValue?.isShowLeft.iconTextLeft.name"
|
||||
:size="modelValue?.isShowLeft.iconTextLeft.size"
|
||||
custom-class="customClass-icon"
|
||||
></wd-icon>
|
||||
<image v-if="modelValue?.isShowLeft.showCom==='img'" :src="modelValue.isShowLeft.img.imgLeft"
|
||||
class="meun-widht-rightimage_item"
|
||||
mode="scaleToFill" webp></image>
|
||||
</view>
|
||||
<view class="meun-widht-middle" :class="{'light-background':theme==='light'}"></view>
|
||||
<view class="meun-widht-right" @click="emit('homeRight')">
|
||||
<!-- <wd-icon custom-class="customClass-icon" name="thin-arrow-left" size="18px"></wd-icon>-->
|
||||
<wd-icon v-if="modelValue?.isShowRight.showCom==='icon'"
|
||||
:classPrefix="modelValue?.isShowRight.iconTextRight.classPrefix"
|
||||
:name="modelValue?.isShowRight.iconTextRight.name"
|
||||
:size="modelValue?.isShowRight.iconTextRight.size"
|
||||
custom-class="customClass-icon"
|
||||
></wd-icon>
|
||||
<image v-if="modelValue?.isShowRight.showCom==='img'" :src="modelValue.isShowRight.img.imgRight"
|
||||
class="meun-widht-rightimage_item"
|
||||
mode="scaleToFill" webp></image>
|
||||
</view>
|
||||
<view class="FlexTitleWidth">
|
||||
<view v-if="titleViewShow" class="flex-title-text">{{ modelValue?.title_text }}</view>
|
||||
<view v-if="slotViewShow" class="flex-title-slot">
|
||||
<slot name="default"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {computed, ref, watchEffect} from "vue";
|
||||
import {onShow} from "@dcloudio/uni-app";
|
||||
import type {GlobelsChildPropsType} from "@/types/通用类型";
|
||||
|
||||
let theme = ref(uni.getAppBaseInfo().theme); // 返回值为 dark or linght
|
||||
defineOptions({
|
||||
options: {
|
||||
styleIsolation: "shared",
|
||||
virtualHost: true,
|
||||
},
|
||||
});
|
||||
const emit = defineEmits<{
|
||||
(eventName: "update:pxWindowHeight", value: string): void
|
||||
(eventName: "update:pxScrollHeight", value: string): void
|
||||
(eventName: "update:pxScreenHeight", value: string): void
|
||||
(eventName: "update:pxWifiNavHeight", value: string): void
|
||||
(eventName: "update:statusHeight", value: string): void
|
||||
(eventName: "update:meunHeight", value: string): void
|
||||
(eventName: "homeRight"): void
|
||||
(eventName: "homeLeft"): void
|
||||
}>();
|
||||
|
||||
|
||||
//
|
||||
interface definePropsType {
|
||||
modelValue?: GlobelsChildPropsType, //跟v-model=值没有关系
|
||||
zIndex?: number
|
||||
}
|
||||
|
||||
|
||||
const props = withDefaults(defineProps<definePropsType>(), {
|
||||
zIndex: () => (100),
|
||||
});
|
||||
const info_window = uni.getWindowInfo();
|
||||
let pxToRpxScale = 750 / info_window.windowWidth;
|
||||
let meun = uni.getMenuButtonBoundingClientRect();
|
||||
let meun_px_height = computed(() => {
|
||||
return meun.height - 2 + "px";
|
||||
});
|
||||
// 计算当前 wifi的高度
|
||||
let wifiHeing = computed(() => {
|
||||
// 当前wifi的高度 也是分为两种情况下 为负数的时候 小于0 的时候我们就需要减少 wifi的高度,这样才能正确留空
|
||||
if (meun.top - info_window.statusBarHeight < 0) {
|
||||
let num = meun.top - info_window.statusBarHeight;
|
||||
return info_window.statusBarHeight - Math.abs(num) * 2;
|
||||
}
|
||||
return info_window.statusBarHeight;
|
||||
});
|
||||
// 默认的一些宽度
|
||||
let rpxLeftWidth = computed(() => {
|
||||
return (info_window.windowWidth - meun.right) * pxToRpxScale + "rpx";
|
||||
});
|
||||
|
||||
let pxMeunHeight = computed(() => {
|
||||
return meun.height + "px";
|
||||
});
|
||||
let rpxFlexTitleWidth = computed(() => {
|
||||
return (meun.left - meun.width - (info_window.windowWidth - meun.right)) * pxToRpxScale + "rpx";
|
||||
});
|
||||
let divMeunWidht = computed(() => {
|
||||
// 胶囊的一半宽度
|
||||
const halfWidth = Math.ceil(meun.width / 2) - 1;
|
||||
return halfWidth * pxToRpxScale + "rpx";
|
||||
});
|
||||
|
||||
let flexMeunHeight = computed(() => {
|
||||
return Math.ceil(meun.height) * 0.6 + "px";
|
||||
});
|
||||
let divMeunWidhtMiddle = computed(() => {
|
||||
return "1px";
|
||||
// return 2 * pxToRpxScale + "rpx";
|
||||
});
|
||||
let imgWidthHeight = computed(() => {
|
||||
return Math.ceil(meun.height * 0.7 * pxToRpxScale) + "rpx";
|
||||
});
|
||||
let wifi_px = computed(() => {
|
||||
return wifiHeing.value + "px";
|
||||
});
|
||||
// 计算当前导航栏的高度
|
||||
let navHeight = computed(() => {
|
||||
// 导航栏高度 = 胶囊高度 + (胶囊顶部距离 - wifi高度)*2
|
||||
// 这里逻辑也得分二种情况第一情况,减下来值小0 和大于0
|
||||
if (meun.top - info_window.statusBarHeight > 0) {
|
||||
return meun.height + (meun.top - info_window.statusBarHeight) * 2;
|
||||
}
|
||||
if (meun.top - info_window.statusBarHeight <= 0) {
|
||||
return meun.height + Math.abs(meun.top - info_window.statusBarHeight) * 2;
|
||||
}
|
||||
return meun.height + (meun.top - info_window.statusBarHeight) * 2;
|
||||
});
|
||||
let nav_px_height = computed(() => {
|
||||
return navHeight.value + "px";
|
||||
});
|
||||
// 计算可视区域的高度
|
||||
let windowHeight = computed(() => {
|
||||
// 可视区高度 = 屏幕高度 - 可视区域的高度 还需要判断 二 种情况, 一种是有tab, 一种是没有tab的情况
|
||||
// 没有tab栏的情况
|
||||
if (info_window.screenHeight - info_window.windowHeight === 0) {
|
||||
if (info_window.safeAreaInsets.bottom > 0) {
|
||||
// 这是苹果手机的状态(直接返回高度就可以了)
|
||||
return info_window.screenHeight - info_window.safeAreaInsets.bottom;
|
||||
}
|
||||
if (info_window.safeAreaInsets.bottom === 0) {
|
||||
// 这是没有底部安全栏高度时的(华为手机,苹果5678o)
|
||||
return info_window.screenHeight - 34;
|
||||
}
|
||||
}
|
||||
if (info_window.screenHeight - info_window.windowHeight > 0) {
|
||||
return info_window.windowHeight;
|
||||
}
|
||||
return info_window.windowHeight;
|
||||
});
|
||||
// 实时给出高度
|
||||
let wifiShow = ref(true);
|
||||
let navShow = ref(true);
|
||||
let titleViewShow = ref(true);
|
||||
let slotViewShow = ref(false);
|
||||
onShow(() => {
|
||||
emit("update:meunHeight", pxMeunHeight.value);
|
||||
});
|
||||
watchEffect(() => {
|
||||
emit("update:pxScreenHeight", info_window.screenHeight + "px");
|
||||
|
||||
if (props.modelValue?.navIsShow === "default") {
|
||||
// 此时的导航栏高度 = wifi+nav的高度
|
||||
let staus = computed(() => {
|
||||
return (wifiHeing.value + navHeight.value) + "px";
|
||||
});
|
||||
let pxScrollHeight = computed(() => {
|
||||
return windowHeight.value + "px";
|
||||
});
|
||||
emit("update:statusHeight", staus.value);
|
||||
emit("update:pxWindowHeight", staus.value);
|
||||
emit("update:pxScrollHeight", pxScrollHeight.value);
|
||||
emit("update:pxWindowHeight", pxScrollHeight.value);
|
||||
}
|
||||
if (props.modelValue?.navIsShow === "wifi") {
|
||||
// 此时的导航栏高度 = wifi+nav的高度
|
||||
navShow.value = false;
|
||||
let staus = computed(() => {
|
||||
return (wifiHeing.value) + "px";
|
||||
});
|
||||
let pxScrollHeight = computed(() => {
|
||||
// 当值为wifi时,则表明,只想显示一个wifi的状态, 不想显示na的状态
|
||||
return windowHeight.value + "px";
|
||||
});
|
||||
emit("update:statusHeight", staus.value);
|
||||
emit("update:pxWindowHeight", staus.value);
|
||||
emit("update:pxScrollHeight", pxScrollHeight.value);
|
||||
emit("update:pxWindowHeight", pxScrollHeight.value);
|
||||
}
|
||||
if (props.modelValue?.navIsShow === "none") {
|
||||
navShow.value = true;
|
||||
wifiShow.value = false;
|
||||
// 此时的导航栏高度 = wifi+nav的高度
|
||||
let staus = computed(() => {
|
||||
return "0px";
|
||||
});
|
||||
let pxScrollHeight = computed(() => {
|
||||
// 当值为wifi时,则表明,只想显示一个wifi的状态, 不想显示na的状态
|
||||
return windowHeight.value + "px";
|
||||
});
|
||||
emit("update:statusHeight", staus.value);
|
||||
emit("update:pxWindowHeight", staus.value);
|
||||
emit("update:pxScrollHeight", pxScrollHeight.value);
|
||||
emit("update:pxWindowHeight", pxScrollHeight.value);
|
||||
}
|
||||
if (props.modelValue?.navIsShow === "slot") {
|
||||
slotViewShow.value = true;
|
||||
titleViewShow.value = false;
|
||||
// 此时的导航栏高度 = wifi+nav的高度
|
||||
let staus = computed(() => {
|
||||
return (wifiHeing.value + navHeight.value) + "px";
|
||||
});
|
||||
|
||||
let pxScrollHeight = computed(() => {
|
||||
// 当值为wifi时,则表明,只想显示一个wifi的状态, 不想显示na的状态
|
||||
return windowHeight.value + "px";
|
||||
});
|
||||
emit("update:statusHeight", staus.value);
|
||||
emit("update:pxWindowHeight", staus.value);
|
||||
emit("update:pxScrollHeight", pxScrollHeight.value);
|
||||
emit("update:pxWindowHeight", pxScrollHeight.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,33 @@
|
||||
<style scoped lang="scss">
|
||||
.root-demo {
|
||||
height: 90%;
|
||||
display: flex;
|
||||
box-shadow: inset 0 0 0 1px red;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<view class=root-demo>
|
||||
<view class="xiaozizi-demo">
|
||||
<nut-empty :description="description">
|
||||
<template #image>
|
||||
<image src="https://hudie.xiao.band/%E6%9C%AA%E5%91%BD%E5%90%8D.png"></image>
|
||||
</template>
|
||||
<nut-button icon="refresh" type="warning" @click="去商城逛逛">去商城逛逛</nut-button>
|
||||
</nut-empty>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// 页面功能注释区域
|
||||
import {ref} from "vue";
|
||||
|
||||
defineOptions({options: {styleIsolation: "shared"}, name: "tong-yong-com-empty"});
|
||||
let description = ref("默认文字");
|
||||
const 去商城逛逛 = async (): Promise<void> => {
|
||||
wx.vibrateShort({type: "light"});
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,165 @@
|
||||
<style scoped lang="scss">
|
||||
.root-demo {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 36rpx;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-auto-rows: 48rpx;
|
||||
justify-items: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
border: red solid 1px;
|
||||
|
||||
.items-1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.items-text {
|
||||
//width: 112rpx;
|
||||
height: 40rpx;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
line-height: 40rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.items-image {
|
||||
height: 44rpx;
|
||||
width: 44rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
border-radius: 50%;
|
||||
|
||||
&.theme-white {
|
||||
border: #6e6d6d solid 1px; // 主题是亮色的时候
|
||||
}
|
||||
|
||||
&.theme-dark {
|
||||
border: #b9b9b9 solid 1px; // 主题是暗色的时候
|
||||
}
|
||||
|
||||
&.select-statu {
|
||||
//border: #b9b9b9 solid 1px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
transition: all 1s;
|
||||
|
||||
:deep(.custom-class-img) {
|
||||
height: 44rpx;
|
||||
width: 44rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.custom-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<view class=root-demo>
|
||||
<view class="items-1" @click="选择配送方式事件('全国物流')">
|
||||
<view class="items-image"
|
||||
:class="{'theme-white':theme==='light','theme-dark':theme==='dark','select-statu':选中时的状态==='全国物流'}">
|
||||
<wd-img custom-class="custom-class-img" v-if="选中时的状态==='全国物流'" custom-image="custom-image"
|
||||
src="/static/正确.svg">
|
||||
<template #error>
|
||||
<view class="error-wrap">加载失败</view>
|
||||
</template>
|
||||
<template #loading>
|
||||
<view class="loading-wrap">
|
||||
<wd-loading/>
|
||||
</view>
|
||||
</template>
|
||||
</wd-img>
|
||||
|
||||
</view>
|
||||
<view class="line-widht-number" style="width: 10rpx"></view>
|
||||
<view class="items-text">全国物流</view>
|
||||
</view>
|
||||
<view class="items-1" @click="选择配送方式事件('跑腿配送')">
|
||||
<view class="items-image"
|
||||
:class="{'theme-white':theme==='light','theme-dark':theme==='dark','select-statu':选中时的状态==='跑腿配送'}">
|
||||
<wd-img custom-class="custom-class-img" v-if="选中时的状态==='跑腿配送'" custom-image="custom-image"
|
||||
src="/static/正确.svg">
|
||||
<template #error>
|
||||
<view class="error-wrap">加载失败</view>
|
||||
</template>
|
||||
<template #loading>
|
||||
<view class="loading-wrap">
|
||||
<wd-loading/>
|
||||
</view>
|
||||
</template>
|
||||
</wd-img>
|
||||
</view>
|
||||
<view class="line-widht-number" style="width: 10rpx"></view>
|
||||
<view class="items-text">跑腿配送</view>
|
||||
</view>
|
||||
|
||||
<view class="items-1" @click="选择配送方式事件('门店核销')">
|
||||
|
||||
<view class="items-image"
|
||||
:class="{'theme-white':theme==='light','theme-dark':theme==='dark','select-statu':选中时的状态==='门店核销'}">
|
||||
<wd-img custom-class="custom-class-img" v-if="选中时的状态==='门店核销'" custom-image="custom-image"
|
||||
src="/static/正确.svg">
|
||||
<template #error>
|
||||
<view class="error-wrap">加载失败</view>
|
||||
</template>
|
||||
<template #loading>
|
||||
<view class="loading-wrap">
|
||||
<wd-loading/>
|
||||
</view>
|
||||
</template>
|
||||
</wd-img>
|
||||
|
||||
</view>
|
||||
<view class="line-widht-number" style="width: 10rpx"></view>
|
||||
<view class="items-text">门店核销</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// 页面功能注释区域
|
||||
import {ref} from "vue";
|
||||
import {useVModels} from "@vueuse/core";
|
||||
|
||||
interface definePropsType {
|
||||
modelValue: number;// 对象类型的 prop
|
||||
}
|
||||
|
||||
type 选中的类型 = "全国物流" | "跑腿配送" | "门店核销"
|
||||
const 选中时的状态 = ref<选中的类型>("全国物流");
|
||||
// 2. 使用 withDefaults 定义默认值
|
||||
const props = withDefaults(defineProps<definePropsType>(), {});
|
||||
const emit = defineEmits<{
|
||||
(eventName: "update:modelValue", value: string): void
|
||||
}>();
|
||||
|
||||
const {modelValue,} = useVModels(props, emit);
|
||||
let theme = ref(uni.getAppBaseInfo().theme); // 返回值为 dark or linght
|
||||
// defineOptions({options: {styleIsolation: "shared",}, name: "ExpressDelivery"}); // 组件使用
|
||||
defineOptions({options: {styleIsolation: "shared",}, name: "tong-yong-com-express-delivery"}); // 组件使用
|
||||
const buttonClick = async (): Promise<void> => {
|
||||
console.log("子组件触发的事件");
|
||||
};
|
||||
const 选择配送方式事件 = async (item: "全国物流" | "跑腿配送" | "门店核销"): Promise<void> => {
|
||||
选中时的状态.value = item;
|
||||
wx.vibrateShort({type: "light"});
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,31 @@
|
||||
<style scoped lang="scss">
|
||||
.root-demo {
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<view class=root-demo>
|
||||
<wd-button type="primary" icon="phone" :block="true"
|
||||
@click="throttledFn" custom-class="custom-shadow">
|
||||
信息按钮
|
||||
</wd-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// 页面功能注释区域
|
||||
import {ref} from "vue";
|
||||
import {useThrottleFn} from "@vueuse/shared";
|
||||
import {usePage, useQuery} from "@uni-helper/uni-use";
|
||||
|
||||
let theme = ref(uni.getAppBaseInfo().theme); // 返回值为 dark or linght
|
||||
defineOptions({options: {styleIsolation: "shared"}}); // 组件使用
|
||||
const {value: userName} = useQuery("name");// 一定需要在生命函数中才获取到值
|
||||
let page_path = usePage().value.route;
|
||||
let reg = new RegExp(/(\d{3})(\d{4})(\d{4})/, "g");// 手机号正则的规则
|
||||
|
||||
const throttledFn = useThrottleFn(async () => {
|
||||
// do something, it will be called at most 1 time per second
|
||||
console.log("🍎 🍏 🍎 🍏 🍎 🍏 🍎 🍏 防抖函数 ", "13382551360".replace(reg, "$1****$3"));
|
||||
}, 10);
|
||||
</script>
|
||||
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<view class="guochang-container">
|
||||
<!-- 左侧浮动小球 -->
|
||||
<view class="balls balls-left">
|
||||
<view class="ball ball-1"></view>
|
||||
<view class="ball ball-2"></view>
|
||||
<view class="ball ball-3"></view>
|
||||
</view>
|
||||
|
||||
<!-- 中间祝福语 -->
|
||||
<view class="message-wrapper">
|
||||
<text class="message">{{ 当前祝福语 }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 右侧浮动小球 -->
|
||||
<view class="balls balls-right">
|
||||
<view class="ball ball-4"></view>
|
||||
<view class="ball ball-5"></view>
|
||||
<view class="ball ball-6"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, onMounted, computed, onUnmounted} from "vue";
|
||||
|
||||
const 祝福语列表 = [
|
||||
"愿你生活如糖,甜而不腻 ✨",
|
||||
"心想事成,万事胜意 🌟",
|
||||
"所有美好如期而至 🎈"
|
||||
];
|
||||
|
||||
const 当前索引 = ref(0);
|
||||
const 当前祝福语 = computed(() => 祝福语列表[当前索引.value]);
|
||||
|
||||
let 定时器: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
const 开始轮播 = () => {
|
||||
定时器 = setInterval(() => {
|
||||
当前索引.value = (当前索引.value + 1) % 祝福语列表.length;
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
const 停止轮播 = () => {
|
||||
if (定时器) {
|
||||
clearInterval(定时器);
|
||||
定时器 = null;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
开始轮播();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
停止轮播();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.guochang-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 120rpx;
|
||||
padding: 0 40rpx;
|
||||
margin: 20rpx 30rpx;
|
||||
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
|
||||
border-radius: 60rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.4),
|
||||
inset 0 1rpx 0 rgba(255, 255, 255, 0.1);
|
||||
|
||||
// 背景微光扫光效果
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 200%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.05),
|
||||
transparent
|
||||
);
|
||||
animation: shimmer 4s infinite linear;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 小球容器
|
||||
.balls {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
|
||||
&.balls-left {
|
||||
left: 30rpx;
|
||||
}
|
||||
|
||||
&.balls-right {
|
||||
right: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 小球基础样式
|
||||
.ball {
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 50%;
|
||||
animation: float 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
// 左侧三个球
|
||||
.ball-1 {
|
||||
background: #FF6B6B;
|
||||
box-shadow: 0 0 12rpx #FF6B6B;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.ball-2 {
|
||||
background: #FFD700;
|
||||
box-shadow: 0 0 12rpx #FFD700;
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
.ball-3 {
|
||||
background: #4ECDC4;
|
||||
box-shadow: 0 0 12rpx #4ECDC4;
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
// 右侧三个球
|
||||
.ball-4 {
|
||||
background: #FF9F43;
|
||||
box-shadow: 0 0 12rpx #FF9F43;
|
||||
animation-delay: 0.15s;
|
||||
}
|
||||
|
||||
.ball-5 {
|
||||
background: #54A0FF;
|
||||
box-shadow: 0 0 12rpx #54A0FF;
|
||||
animation-delay: 0.45s;
|
||||
}
|
||||
|
||||
.ball-6 {
|
||||
background: #A29BFE;
|
||||
box-shadow: 0 0 12rpx #A29BFE;
|
||||
animation-delay: 0.75s;
|
||||
}
|
||||
|
||||
// 中间文字容器
|
||||
.message-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-size: 28rpx;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
text-shadow: 0 2rpx 8rpx rgba(255, 215, 0, 0.6),
|
||||
0 0 16rpx rgba(255, 215, 0, 0.3);
|
||||
letter-spacing: 1rpx;
|
||||
background: linear-gradient(90deg, #FFD700, #FFA500);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
// 动画定义
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
transform: translateY(0) scale(1);
|
||||
opacity: 0.85;
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-14rpx) scale(1.1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(50%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user