Candice 2 days ago
parent f2270efc97
commit 25278226b5

@ -15,7 +15,7 @@
<style> <style>
/*每个页面公共css */ /*每个页面公共css */
page{ page{
width: 100%; width: 100% !important;
background: #f5f5f5; background: #f5f5f5;
box-sizing: border-box; box-sizing: border-box;
} }

@ -0,0 +1,72 @@
<template>
<uni-popup ref="popupRef">
<view class="popup-content">
<uni-icons class="closeIcon" @click.stop="close" type="close" color="#86ACFE" size="36"></uni-icons>
<image class="systemBG" src="/static/systemBG.png" mode="aspectFill"></image>
<button class="detailBtn">查看详情</button>
</view>
</uni-popup>
</template>
<script setup>
import { ref, watch, onMounted } from 'vue'
defineOptions({ name: "customizedPopup" })
const props = defineProps({
isOpen: {
type: Boolean,
default: false
}
})
const popupRef = ref(null)
watch(() => props.isOpen, (newVal, oldVal) => {
if (!popupRef.value) { // null
console.warn('弹窗组件尚未初始化完成');
return;
}
if (newVal) { //
popupRef.value.open(); //
} else {
popupRef.value.close(); //
}
},{immediate: true})
onMounted(()=>{
})
const close = ()=>{
popupRef.value.close();
}
</script>
<style lang="scss" scoped>
.popup-content{
width: 640rpx;
height: 844rpx;
position: relative;
}
.systemBG{
width: 640rpx;
height: 844rpx;
}
.closeIcon{
position: absolute;
top: 26rpx;
right: 26rpx;
}
.detailBtn{
position: absolute;
bottom: 46rpx;
left: 50%;
transform: translate(-50%,0);
width: 207rpx;
height: 77rpx;
background: #3A71FF;
border-radius: 45rpx 45rpx 45rpx 45rpx;
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
@include flexBox();
}
</style>

@ -6,7 +6,7 @@
<view class="main1"> <view class="main1">
<view class="titleBox"> <view class="titleBox">
<text>已连续签到0天</text> <text>已连续签到0天</text>
<button class="signBtn">立即签到</button> <button class="signBtn" @click="goSign">{{isSigned?'':''}}</button>
</view> </view>
<view class="tipsText"> <view class="tipsText">
<text>签到立即获得10积分</text> <text>签到立即获得10积分</text>
@ -69,8 +69,16 @@
{ {
immediate: true immediate: true
}) })
const isSigned = ref(false)
const goSign = ()=>{
isSigned.value = true
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.popup-content { .popup-content {
width: 100vw; width: 100vw;

@ -0,0 +1,283 @@
<template>
<view class="indexPage">
<image class="indexBG" src="@/integralMall/static/indexBG.png" mode="widthFix"></image>
<view class="userBox">
<text>积分余额</text>
<view class="">
<text class="number">23980</text>
<text class="jifen">积分</text>
</view>
</view>
<view class="card">
<view class="cardHead">
<image class="miaoshaImg" src="@/integralMall/static/miaoshaImg.png" mode="widthFix"></image>
<text class="shuxian">|</text>
<text>距结束</text>
<uni-countdown class="countdown" :day="1" :hour="2" :minute="30" :second="0" color="#3A71FF" background-color="#FFFFFF" />
</view>
<view class="cardBody">
<view class="list">
<view class="listItem" v-for="item in 5">
<view class="imgBox">
<image src="@/integralMall/static/test/test.png" mode="aspectFill"></image>
<uni-tag text="剩余23件" class="unitag"
custom-style="background-color: rgba(0,0,0,0.3); border: none; color: #fff;">
</uni-tag>
</view>
<view class="itemBody">
<text class="title">iPhone16 pro</text>
<view class="qiangBox">
<image class="qiangtag" src="@/integralMall/static/qiangtag.png" mode="aspectFill"></image>
<text class="number">20000<text class="jifen">积分</text></text>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="headBar">
<view class="barItem" :class="activeIndex === 0?'active':''" @click="changeBar(0)">
<text>全部商品</text>
<view class="rect" v-show="activeIndex === 0"></view>
</view>
<view class="barItem" :class="activeIndex === 1?'active':''" @click="changeBar(1)">
<text>我可兑换</text>
<view class="rect" v-show="activeIndex === 1"></view>
</view>
</view>
<view class="proList">
<view class="proItem" v-for="item in 5" @click="$util.redirectTo('./pro/detail')">
<view class="proLeft">
<image class="proImg" src="@/integralMall/static/test/test2.png" mode="aspectFill"></image>
<uni-tag text="剩余23件" class="unitag"
custom-style="background-color: rgba(0,0,0,0.3); border: none; color: #fff;">
</uni-tag>
</view>
<view class="proRight">
<text class="proName">索尼丨索尼A7M4全画幅微单数码相机套装ILCE-7M4高清旅游摄影拍照</text>
<view class="tagBox">
<uni-tag text="品牌正品" class="unitag"
custom-style="background-color: #000000; border: none; color: #FFCC33;">
</uni-tag>
<uni-tag text="限时限量" class="unitag"
custom-style="background-color: #07C160; border: none; color: #FFF9F9;">
</uni-tag>
</view>
<view class="buyBox">
<text class="number">25000<text class="jifen">积分</text></text>
<image class="qiang" src="@/integralMall/static/qiang.png" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const activeIndex = ref(0)
const changeBar = (index)=>{
if(activeIndex.value === index) return;
activeIndex.value = index
}
</script>
<style lang="scss" >
.indexPage{
position: relative;
padding-bottom: 26rpx;
.indexBG{
width: 100%;
height: auto;
}
}
.userBox{
position: relative;
z-index: 10;
margin: -40rpx 26rpx 26rpx;
background: linear-gradient( 180deg, #D0DDFF 0%, #FFFFFF 100%);
box-shadow: 0rpx 4rpx 7rpx 0rpx rgba(0,0,0,0.08);
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
padding: 40rpx 26rpx;
@include fontStyle(28rpx,#000000,left,500,38rpx);
@include flexBox(between,center);
.number{
@include fontStyle(58rpx,#333333,right,800,68rpx);
padding-right: 10rpx;
}
.jifen{
@include fontStyle(24rpx,#333333,right,400,38rpx);
}
}
.card{
margin: 26rpx;
background: linear-gradient( 360deg, #094EF3 0%, #4B91FE 45%, #D6E4FD 100%);
box-shadow: 0rpx 4rpx 9rpx 0rpx rgba(0,0,0,0.05);
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
padding: 26rpx;
.cardHead{
width: 100%;
@include flexBox(start,center);
padding-bottom: 26rpx;
@include fontStyle(34rpx,#000000,left,500,44rpx);
.miaoshaImg{
width: 142rpx;
height: auto;
}
.shuxian{
padding: 0 26rpx;
}
.countdown{
margin-left: 26rpx;
}
}
.cardBody{
.list{
width: 100%;
@include flexBox(start,center);
overflow-x: auto;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
.listItem{
width: 240rpx;
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
&:not(:last-child){
margin-right: 26rpx;
}
.imgBox{
width: 100%;
position: relative;
image{
width: 240rpx;
height: 240rpx;
border-radius: 18rpx 18rpx 0 0;
}
.unitag{
position: absolute;
top: 180rpx;
left: 10rpx;
}
}
.qiangBox{
position: relative;
}
.qiangtag{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 46rpx;
}
.itemBody{
box-sizing: border-box;
padding: 10rpx;
.title{
@include fontStyle(32rpx,#000000,left,500,44rpx);
@include truncateText(1);
padding-bottom: 26rpx;
}
.number{
position: relative;
z-index: 10;
padding-left: 10rpx;
@include fontStyle(28rpx,#FFFFFF,left,800,44rpx);
.jifen{
@include fontStyle(24rpx,#FFFFFF,left,400,44rpx);
}
}
}
}
}
}
}
.headBar{
width: 60%;
margin: 46rpx auto;
@include flexBox(around,center);
.barItem{
position: relative;
@include fontStyle(34rpx,#3A71FF,left,400,48rpx);
&.active{
@include fontStyle(34rpx,#3A71FF,left,bold,48rpx);
}
.rect{
position: absolute;
bottom: 0;
left: 50%;
z-index: -1;
transform: translate(-50%,0%);
width: 100%;
height: 20rpx;
background: linear-gradient( 180deg, #6694FF 0%, #FFFFFF 100%);
}
}
}
.proList{
.proItem{
margin: 26rpx;
@include flexBox(start,start);
.proLeft{
position: relative;
margin-right: 16rpx;
.proImg{
width: 252rpx;
height: 252rpx;
border-radius: 18rpx;
}
.unitag{
position: absolute;
top: 200rpx;
left: 16rpx;
z-index: 2;
}
}
.proRight{
flex: 1;
min-height: 252rpx;
@include flexBox(between,start,column);
.tagBox{
margin: 10rpx 0;
@include flexBox(start,center);
.unitag{
margin-right: 20rpx;
}
}
.proName{
@include fontStyle(28rpx,#000000,left,500,38rpx);
@include truncateText();
}
.buyBox{
width: 100%;
height: 80rpx;
background: #E6EDFF;
border-radius: 10rpx;
@include fontStyle(40rpx,#3A71FF,left,600,48rpx);
@include flexBox(between,center);
box-sizing: border-box;
padding-left: 26rpx;
.jifen{
@include fontStyle(24rpx,#3A71FF,left,500,38rpx);
padding-left: 10rpx;
}
.qiang{
width: 80rpx;
height: 80rpx;
border-radius: 10rpx;
}
}
}
}
}
</style>

@ -0,0 +1,196 @@
<template>
<view class="detailPage">
<swiper class="swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
<swiper-item>
<view class="swiper-item">
<image class="swiper-img" src="@/integralMall/static/test/test3.png" mode="aspectFill"></image>
</view>
</swiper-item>
</swiper>
<view class="body">
<view class="countBox">
<image class="countBG" src="/integralMall/static/miaoshaBG.png" mode="widthFix"></image>
<view class="countdown">
<text>距结束</text>
<uni-countdown class="countdown1" :day="1" :hour="2" :minute="30" :second="0" color="#3A71FF" splitorColor="#3A71FF" background-color="#FFFFFF" />
</view>
</view>
<view class="detail">
<view class="priceBox">
<view class="new">
<image class="coin" src="@/integralMall/static/coin.png" mode="aspectFill"></image>
<text>20000</text>
<image class="miaoshaImg" src="/integralMall/static/miao.png" mode="widthFix"></image>
</view>
<view class="old">
<text>原价</text>
<text class="oldNum">3200积分</text>
</view>
</view>
<view class="proName">
<text>索尼丨索尼A7M4全画幅微单数码相机套装ILCE-7M4高清旅游摄影拍照</text>
</view>
<view class="specsBox">
<text>规格</text>
<view class="specsItem">
<text>已选</text>
<text>秒杀装黑色单机</text>
</view>
<uni-icons type="right" color="#A4A5A5" size="24"></uni-icons>
</view>
</view>
<view class="proDetail">
<view class="title">
<text>商品详情</text>
</view>
<view class="">
<image src="@/integralMall/static/test/test4.png" mode="widthFix"></image>
<image src="@/integralMall/static/test/test5.png" mode="widthFix"></image>
</view>
</view>
</view>
<view class="bottom">
<view class="" style="height: 180rpx;"></view>
<view class="btnBox">
<button>立即兑换</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
</script>
<style lang="scss" scoped>
.detailPage{
position: relative;
.swiper{
width: 100%;
height: 750rpx;
.swiper-item{
width: 100%;
height: 100%;
.swiper-img{
width: 100%;
height: 100%;
}
}
}
}
.body{
position: relative;
z-index: 3;
margin-top: -50rpx;
.countBox{
width: 100%;
position: relative;
@include flexBox(end,end);
.countBG{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: auto;
z-index: -1;
}
.countdown{
box-sizing: border-box;
padding: 20rpx 26rpx 16rpx;
@include fontStyle(34rpx,#FFFFFF,right,400,44rpx);
@include flexBox(center,center);
.countdown1{
margin-left: 16rpx;
}
}
}
.detail{
width: 100%;
background: rgba(253,253,253,0.9);
border-radius: 46rpx 46rpx 0rpx 0rpx;
box-sizing: border-box;
padding: 26rpx;
.priceBox{
@include flexBox(start,center);
.new{
@include fontStyle(58rpx,#3A71FF,left,800,62rpx);
@include flexBox(start,center);
.coin{
width: 28rpx;
height: 28rpx;
margin-right: 16rpx;
margin-top: 16rpx;
}
.miaoshaImg{
width: 96rpx;
height: auto;
margin-left: 26rpx;
}
}
.old{
margin-left: 26rpx;
@include fontStyle(28rpx,#999999,left,400,38rpx);
.oldNum{
text-decoration: line-through;
padding-left: 16rpx;
}
}
}
.proName{
margin: 32rpx 0;
@include fontStyle(34rpx,#333333,left,bold,46rpx);
}
.specsBox{
width: 100%;
background: #F2FAFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
padding: 26rpx;
@include flexBox(between,ccenter);
@include fontStyle(28rpx,#666666,left,500,38rpx);
.specsItem{
margin-left: 16rpx;
flex: 1;
@include fontStyle(28rpx,#333333,left,500,38rpx);
}
}
}
.proDetail{
width: 100%;
background: #F5F5F5;
.title{
padding: 26rpx;
@include fontStyle(28rpx,#333333,left,500,38rpx);
}
image{
width: 100%;
height: auto;
display: block;
}
}
}
.bottom{
.btnBox{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 168rpx;
z-index: 30;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 9rpx 0rpx rgba(0,0,0,0.08);
button{
width: 544rpx;
height: 80rpx;
background: #3A71FF;
border-radius: 100rpx 100rpx 100rpx 100rpx;
font-weight: 500;
font-size: 34rpx;
color: #FFFFFF;
@include flexBox();
margin-top: 30rpx;
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@ -1,7 +1,6 @@
import App from './App' import App from './App'
// 公共导入Vue2 和 Vue3 共用的模块) // 公共导入Vue2 和 Vue3 共用的模块)
import './uni.promisify.adaptor'
import http from './common/js/http.js' import http from './common/js/http.js'
import util from './common/js/util.js' import util from './common/js/util.js'
import siteConfig from './common/js/siteConfig.js' import siteConfig from './common/js/siteConfig.js'
@ -32,9 +31,8 @@ app.$mount()
// #endif // #endif
// #ifdef VUE3 // #ifdef VUE3
import { import {createSSRApp} from 'vue'
createSSRApp import './uni.promisify.adaptor'
} from 'vue'
import tabbar from './components/tabbar/tabbar.vue' import tabbar from './components/tabbar/tabbar.vue'
import store from './store' import store from './store'

@ -38,6 +38,28 @@
} }
} }
], ],
"subPackages": [
{
"root": "integralMall",
"pages": [{
"path" : "pages/index",
"style" :
{
"navigationBarTitleText" : "",
"navigationStyle": "custom"
}
},
{
"path" : "pages/pro/detail",
"style" :
{
"navigationBarTitleText" : "商品详情"
}
}
]
}
],
"globalStyle": { "globalStyle": {
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "", "navigationBarTitleText": "",

@ -35,7 +35,7 @@
<text>每日签到即可获得积分</text> <text>每日签到即可获得积分</text>
</view> </view>
</view> </view>
<view class="btnItem bg-w"> <view class="btnItem bg-w" @click="goIntegral">
<image class="btnIcon" src="/static/index/goShop.png" mode="aspectFill"></image> <image class="btnIcon" src="/static/index/goShop.png" mode="aspectFill"></image>
<view class="textBox"> <view class="textBox">
<text class="title">积分商城</text> <text class="title">积分商城</text>
@ -314,6 +314,7 @@ import { ref, nextTick, onMounted } from 'vue';
import diamondLine from '../../components/diamondLine/diamondLine.vue'; import diamondLine from '../../components/diamondLine/diamondLine.vue';
import DIYScrollView from '../../components/DIYScrollView/DIYScrollView.vue'; import DIYScrollView from '../../components/DIYScrollView/DIYScrollView.vue';
import signPopup from '../../components/signPopup/signPopup.vue'; import signPopup from '../../components/signPopup/signPopup.vue';
import util from '../../common/js/util.js';
const activeOne = ref(0) const activeOne = ref(0)
const changeBar = (index)=>{ const changeBar = (index)=>{
@ -326,6 +327,20 @@ const handleTouchMove = (e)=> {
e.preventDefault(); // e.preventDefault(); //
return false; // return false; //
} }
const goIntegral = ()=>{
uni.showModal({
title:'温馨提示',
content: '即将打开“力仁GO积分商城”小程序',
success: (res) => {
if(res.confirm){
util.redirectTo('/integralMall/pages/index')
}
}
})
}
const signOpen = ref(false) const signOpen = ref(false)
onMounted(()=>{ onMounted(()=>{
nextTick(()=>{ nextTick(()=>{

@ -148,20 +148,17 @@
</view> </view>
</view> </view>
<customizedPopup :isOpen="popupOpen"></customizedPopup>
<tabbar :tabIndex="1"></tabbar> <tabbar :tabIndex="1"></tabbar>
</view> </view>
</template> </template>
<script setup> <script setup>
import { import {onMounted,nextTick,ref,watch,} from 'vue';
onMounted, import {useIndexStore} from '../../store';
nextTick, import customizedPopup from '../../components/customizedPopup/customizedPopup.vue';
ref,
watch,
} from 'vue';
import {
useIndexStore
} from '../../store';
const indexStore = useIndexStore() const indexStore = useIndexStore()
const searchText = ref('') const searchText = ref('')
@ -315,7 +312,12 @@
await initItemPositions() await initItemPositions()
}) })
const popupOpen = ref(false)
onMounted(()=>{
nextTick(()=>{
popupOpen.value = true
})
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

@ -0,0 +1,30 @@
## 1.2.52025-04-14
- 修复 filterShow 导致的运行报错
## 1.2.42024-09-21
- 新增 支持控制显示位数 默认显示2位
## 1.2.32024-02-20
- 新增 支持控制小时分钟的显隐showHour showMinute
## 1.2.22022-01-19
- 修复 在微信小程序中样式不生效的bug
## 1.2.12022-01-18
- 新增 update 方法 ,在动态更新时间后,刷新组件
## 1.2.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-countdown](https://uniapp.dcloud.io/component/uniui/uni-countdown)
## 1.1.32021-10-18
- 重构
- 新增 font-size 支持自定义字体大小
## 1.1.22021-08-24
- 新增 支持国际化
## 1.1.12021-07-30
- 优化 vue3下小程序事件警告的问题
## 1.1.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.52021-06-18
- 修复 uni-countdown 重复赋值跳两秒的 bug
## 1.0.42021-05-12
- 新增 组件示例地址
## 1.0.32021-05-08
- 修复 uni-countdown 不能控制倒计时的 bug
## 1.0.22021-02-04
- 调整为uni_modules目录规范

@ -0,0 +1,6 @@
{
"uni-countdown.day": "day",
"uni-countdown.h": "h",
"uni-countdown.m": "m",
"uni-countdown.s": "s"
}

@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

@ -0,0 +1,6 @@
{
"uni-countdown.day": "天",
"uni-countdown.h": "时",
"uni-countdown.m": "分",
"uni-countdown.s": "秒"
}

@ -0,0 +1,6 @@
{
"uni-countdown.day": "天",
"uni-countdown.h": "時",
"uni-countdown.m": "分",
"uni-countdown.s": "秒"
}

@ -0,0 +1,278 @@
<template>
<view class="uni-countdown">
<text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text>
<text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text>
<text v-if="showHour" :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>
<text v-if="showHour" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>
<text v-if="showMinute" :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>
<text v-if="showMinute" :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>
<text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text>
<text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* Countdown 倒计时
* @description 倒计时组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=25
* @property {String} backgroundColor 背景色
* @property {String} color 文字颜色
* @property {Number} day 天数
* @property {Number} hour 小时
* @property {Number} minute 分钟
* @property {Number} second
* @property {Number} timestamp 时间戳
* @property {Boolean} showDay = [true|false] 是否显示天数
* @property {Boolean} showHour = [true|false] 是否显示小时
* @property {Boolean} showMinute = [true|false] 是否显示分钟
* @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符
* @property {String} splitorColor 分割符号颜色
* @event {Function} timeup 倒计时时间到触发事件
* @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
*/
export default {
name: 'UniCountdown',
emits: ['timeup'],
props: {
showDay: {
type: Boolean,
default: true
},
showHour: {
type: Boolean,
default: true
},
showMinute: {
type: Boolean,
default: true
},
showColon: {
type: Boolean,
default: true
},
start: {
type: Boolean,
default: true
},
backgroundColor: {
type: String,
default: ''
},
color: {
type: String,
default: '#333'
},
fontSize: {
type: Number,
default: 14
},
splitorColor: {
type: String,
default: '#333'
},
day: {
type: Number,
default: 0
},
hour: {
type: Number,
default: 0
},
minute: {
type: Number,
default: 0
},
second: {
type: Number,
default: 0
},
timestamp: {
type: Number,
default: 0
},
filterShow : {
type:Object,
default () {
return {}
}
}
},
data() {
return {
timer: null,
syncFlag: false,
d: '00',
h: '00',
i: '00',
s: '00',
leftTime: 0,
seconds: 0
}
},
computed: {
dayText() {
return t("uni-countdown.day")
},
hourText(val) {
return t("uni-countdown.h")
},
minuteText(val) {
return t("uni-countdown.m")
},
secondText(val) {
return t("uni-countdown.s")
},
timeStyle() {
const {
color,
backgroundColor,
fontSize
} = this
return {
color,
backgroundColor,
fontSize: `${fontSize}px`,
width: `${fontSize * 22 / 14}px`, // 14px
lineHeight: `${fontSize * 20 / 14}px`,
borderRadius: `${fontSize * 3 / 14}px`,
}
},
splitorStyle() {
const { splitorColor, fontSize, backgroundColor } = this
return {
color: splitorColor,
fontSize: `${fontSize * 12 / 14}px`,
margin: backgroundColor ? `${fontSize * 4 / 14}px` : ''
}
}
},
watch: {
day(val) {
this.changeFlag()
},
hour(val) {
this.changeFlag()
},
minute(val) {
this.changeFlag()
},
second(val) {
this.changeFlag()
},
start: {
immediate: true,
handler(newVal, oldVal) {
if (newVal) {
this.startData();
} else {
if (!oldVal) return
clearInterval(this.timer)
}
}
}
},
created: function(e) {
this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
this.countDown()
},
// #ifndef VUE3
destroyed() {
clearInterval(this.timer)
},
// #endif
// #ifdef VUE3
unmounted() {
clearInterval(this.timer)
},
// #endif
methods: {
toSeconds(timestamp, day, hours, minutes, seconds) {
if (timestamp) {
return timestamp - parseInt(new Date().getTime() / 1000, 10)
}
return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
},
timeUp() {
clearInterval(this.timer)
this.$emit('timeup')
},
countDown() {
let seconds = this.seconds
let [day, hour, minute, second] = [0, 0, 0, 0]
if (seconds > 0) {
day = Math.floor(seconds / (60 * 60 * 24))
hour = Math.floor(seconds / (60 * 60)) - (day * 24)
minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
} else {
this.timeUp()
}
this.d = String(day).padStart(this.validFilterShow(this.filterShow.d), '0')
this.h = String(hour).padStart(this.validFilterShow(this.filterShow.h), '0')
this.i = String(minute).padStart(this.validFilterShow(this.filterShow.m), '0')
this.s = String(second).padStart(this.validFilterShow(this.filterShow.s), '0')
},
validFilterShow(filter){
return (filter && filter > 0) ? filter : 2;
},
startData() {
this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
if (this.seconds <= 0) {
this.seconds = this.toSeconds(0, 0, 0, 0, 0)
this.countDown()
return
}
clearInterval(this.timer)
this.countDown()
this.timer = setInterval(() => {
this.seconds--
if (this.seconds < 0) {
this.timeUp()
return
}
this.countDown()
}, 1000)
},
update(){
this.startData();
},
changeFlag() {
if (!this.syncFlag) {
this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
this.startData();
this.syncFlag = true;
}
}
}
}
</script>
<style lang="scss" scoped>
$font-size: 14px;
.uni-countdown {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
&__splitor {
margin: 0 2px;
font-size: $font-size;
color: #333;
}
&__number {
border-radius: 3px;
text-align: center;
font-size: $font-size;
}
}
</style>

@ -0,0 +1,86 @@
{
"id": "uni-countdown",
"displayName": "uni-countdown 倒计时",
"version": "1.2.5",
"description": "CountDown 倒计时组件",
"keywords": [
"uni-ui",
"uniui",
"countdown",
"倒计时"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-harmony": "u",
"app-uvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

@ -0,0 +1,10 @@
## CountDown 倒计时
> **组件名uni-countdown**
> 代码块: `uCountDown`
倒计时组件。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-countdown)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839
Loading…
Cancel
Save