时间倒计时
![](https://i-blog.csdnimg.cn/blog_migrate/a9bc8e205a1293340ca7e15adb557c6f.png)
<!-- 时间倒计时 -->
<template>
<view class="container">
<view class="flex-row time-box">
<view class="time-item">{{ laveTimeList[0] }}</view>
<text>天</text>
<view class="time-item">{{ laveTimeList[1] }}</view>
<text>时</text>
<view class="time-item">{{ laveTimeList[2] }}</view>
<text>分</text>
<view class="time-item">{{ laveTimeList[3] }}</view>
<text>秒</text>
</view>
<view class="flex-row time-box">
<view class="flex-row">
<block v-for="(item, i) in laveTimeDateList[0]" :key="i">
<view class="time-item date-item">{{ item }}</view>
</block>
<text>天</text>
</view>
<view class="flex-row">
<block v-for="(item, i) in laveTimeDateList[1]" :key="i">
<view class="time-item date-item">{{ item }}</view>
</block>
<text>时</text>
</view>
<view class="flex-row">
<block v-for="(item, i) in laveTimeDateList[2]" :key="i">
<view class="time-item date-item">{{ item }}</view>
</block>
<text>分</text>
</view>
<view class="flex-row">
<block v-for="(item, i) in laveTimeDateList[3]" :key="i">
<view class="time-item date-item">{{ item }}</view>
</block>
<text>秒</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
laveTimeList: [], // 剩余时间(天-时-分-秒)
laveTimeDateList: [], // 在拆分
timer: "" // 定时器
};
},
onLoad() {
this.getLeftTime("2023/10/25 14:52:00");
},
onUnload() {
if (this.timer) clearInterval(this.timer);
},
methods: {
/* 计算剩余时间 */
getLeftTime(e) {
let timeLeft = this.getTimestap(e); // 获取时间戳
this.initDate(timeLeft); // 初始化数据
this.timer = setInterval(() => {
this.initDate(timeLeft); // 初始化数据
if (timeLeft-- === 0) clearInterval(this.timer); // 清除定时
}, 1000);
},
/* 初始化数据 */
initDate(e) {
const period = this.formateSeconds(e); // 天-时-分-秒
this.laveTimeList = period; // 剩余时间(天-时-分-秒)
this.laveTimeDateList = this.formatDate(JSON.stringify(period)); // 格式化日期
},
/* 天-时-分-秒 */
formateSeconds(e) {
const time = [],
day = parseInt(e / 86400),
hour = parseInt((e % 86400) / 3600),
min = parseInt(((e % 86400) % 3600) / 60),
sec = parseInt(((e % 86400) % 3600) % 60);
time[0] = day > 0 ? this.addZero(day) : this.addZero(0);
time[1] = hour > 0 ? this.addZero(hour) : this.addZero(0);
time[2] = min > 0 ? this.addZero(min) : this.addZero(0);
time[3] = sec > 0 ? this.addZero(sec) : this.addZero(0);
return time;
},
/* 数字前面补零 */
addZero(num) {
return num < 10 ? "0" + num : num;
},
/* 获取时间戳 */
getTimestap(e) {
const curTime = parseInt(new Date().getTime() / 1000); // 当前时间
const futureTime = parseInt(new Date(e.replace(/-/g, "/")).getTime() / 1000); // 指定时间
return futureTime <= curTime ? 0 : futureTime - curTime;
},
/* 格式化日期 */
formatDate(e) {
const list = JSON.parse(e);
for (let i = 0; i < list.length; i++) {
list[i] = list[i].toString().split("");
}
return list;
}
}
};
</script>
<style lang="scss" scoped>
.container {
.flex-row {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
}
.time-box {
color: #eaa81b;
font-size: 26rpx;
margin: 20rpx;
padding: 40rpx 20rpx;
background: #fff;
border-radius: 20rpx;
}
.time-item {
width: 60rpx;
text-align: center;
height: 40rpx;
line-height: 40rpx;
font-size: 24rpx;
margin: 0 20rpx;
background: linear-gradient(90deg, #ffebb1 0%, #ffdb8f 100%);
border-radius: 4rpx;
}
.date-item {
width: 30rpx;
margin: 0 10rpx;
}
}
</style>
canvas 图形验证码
![](https://i-blog.csdnimg.cn/blog_migrate/f4d7e934fdbcc66ff4a87407f71eeb80.png)
<!-- canvas 图形验证码 -->
<template>
<view class="container">
<view class="canvas-box"><canvas type="2d" id="canvasCode" @click="drawPic" /></view>
<view class="text-tip">验证码:{{ curCode }}</view>
</view>
</template>
<script>
export default {
data() {
return {
width: 100, // 宽度
height: 50, // 高度
fontSize: 25, // 字体大小
fontFamily: "SimHei", // 字体
count: 4, // 验证码位数
curCode: "", // 当前验证码
jamPointNum: 40, // 干扰点数
jamLineNum: 10 // 干扰线数
};
},
onLoad() {
this.drawPic(); // 绘制验证码图片
},
methods: {
/* 绘制验证码图片 */
drawPic() {
uni
.createSelectorQuery()
.select("#canvasCode")
.fields({ node: true, size: true })
.exec(res => {
const canvasObj = res[0].node;
const ctx = canvasObj.getContext("2d");
// 清除画布
ctx.fillStyle = "rgb(255, 255, 255)";
ctx.fillRect(0, 0, 91, 36);
// 绘制背景色
ctx.fillStyle = this.randomColor(180, 240); // 颜色若太深可能导致看不清
ctx.fillRect(0, 0, this.width, this.height);
// 绘制文字
const str = "ABCEFGHJKLMNPQRSTWXY123456789";
let codeTemp = "";
for (let i = 0; i < this.count; i++) {
const txt = str[this.randomNum(0, str.length)];
codeTemp += txt;
ctx.fillStyle = this.randomColor(50, 160); // 随机生成字体颜色
ctx.font = this.randomNum(this.fontSize, this.fontSize + 6) + "px " + this.fontFamily; // 随机生成字体大小
const x = 10 + i * 20;
const y = this.randomNum(25, 30);
const deg = this.randomNum(-30, 30);
// 修改坐标原点和旋转角度
ctx.translate(x, y);
ctx.rotate((deg * Math.PI) / 180);
ctx.fillText(txt, 5, 0);
// 恢复坐标原点和旋转角度
ctx.rotate((-deg * Math.PI) / 180);
ctx.translate(-x, -y);
}
this.curCode = codeTemp;
// 绘制干扰线
for (let i = 0; i < this.jamLineNum; i++) {
ctx.strokeStyle = this.randomColor(40, 180);
ctx.beginPath();
ctx.moveTo(this.randomNum(0, this.width), this.randomNum(0, this.height));
ctx.lineTo(this.randomNum(0, this.width), this.randomNum(0, this.height));
ctx.stroke();
}
// 绘制干扰点
for (let i = 0; i < this.jamPointNum; i++) {
ctx.fillStyle = this.randomColor(0, 255);
ctx.beginPath();
ctx.arc(this.randomNum(0, this.width), this.randomNum(0, this.height), 1, 0, 2 * Math.PI);
ctx.fill();
}
});
},
randomNum(min, max) {
// 生成一个随机数
return Math.floor(Math.random() * (max - min) + min);
},
randomColor(min, max) {
// 生成一个随机色
const red = this.randomNum(min, max); // 红色
const green = this.randomNum(min, max); // 绿色
const blue = this.randomNum(min, max); // 蓝色
return `rgb(${red}, ${green}, ${blue})`;
}
}
};
</script>
<style lang="scss" scoped>
.container {
.canvas-box {
width: 200rpx;
height: 100rpx;
margin: 200rpx auto;
}
.text-tip {
width: 80%;
text-align: center;
color: #333;
font-size: 28rpx;
margin: 80rpx auto;
}
}
</style>
圆角灯笼
![](https://i-blog.csdnimg.cn/blog_migrate/0372e961b4e8a7ef2111f0044a476630.png)
<!-- 圆角灯笼 -->
<template>
<view class="container">
<!-- 灯笼-内 -->
<view class="cont-box">
<view class="lantern-box">
<view class="line-tip"></view>
<view class="outer-bg">
<view class="inner-bg"><view class="text-tip">福</view></view>
</view>
<view class="spike-box">
<view class="spike-tip"></view>
<view class="dots-tip"></view>
</view>
</view>
</view>
<!-- 灯笼-外 -->
<view class="cont-box cont-outer-box">
<view class="lantern-box">
<view class="line-tip"></view>
<view class="outer-bg">
<view class="inner-bg"><view class="text-tip">幸</view></view>
</view>
<view class="spike-box">
<view class="spike-tip"></view>
<view class="dots-tip"></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
onLoad() {},
methods: {}
};
</script>
<style lang="scss" scoped>
.container {
.cont-box {
position: fixed;
top: -80rpx;
right: -40rpx;
z-index: 999;
.lantern-box {
position: relative;
width: 240rpx;
height: 180rpx;
background: rgba(216, 0, 15, 0.8);
margin: 100rpx;
transform-origin: 50% -200rpx;
-webkit-transform-origin: 50% -200rpx;
animation: swing 3s infinite ease-in-out;
-webkit-animation: swing 3s infinite ease-in-out;
box-shadow: -10rpx 10rpx 100rpx 8rpx rgba(250, 108, 0, 1);
border-radius: 50% 50%;
}
.lantern-box::before {
content: " ";
position: absolute;
top: -14rpx;
left: 58rpx;
display: block;
width: 120rpx;
height: 24rpx;
background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
border: solid 2rpx #dc8f03;
border-radius: 10rpx 10rpx 0 0;
z-index: 999;
}
.lantern-box::after {
content: " ";
position: absolute;
bottom: -14rpx;
left: 20rpx;
display: block;
width: 120rpx;
height: 24rpx;
margin-left: 40rpx;
background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
border: solid 2rpx #dc8f03;
border-radius: 0 0 10rpx 10rpx;
}
.line-tip {
position: absolute;
top: -40rpx;
left: 120rpx;
width: 4rpx;
height: 40rpx;
background: #dc8f03;
}
.outer-bg {
width: 200rpx;
height: 180rpx;
background: rgba(216, 0, 15, 0.1);
margin: 24rpx 16rpx 16rpx 16rpx;
border: 4rpx solid #dc8f03;
border-radius: 50% 50%;
.inner-bg {
width: 90rpx;
height: 180rpx;
background: rgba(216, 0, 15, 0.1);
margin: -8rpx 16rpx 16rpx 52rpx;
border: 4rpx solid #dc8f03;
border-radius: 50% 50%;
.text-tip {
text-align: center;
line-height: 170rpx;
color: #dc8f03;
font-size: 3.1rem;
font-family: 华文行楷, Arial, Lucida Grande, Tahoma, sans-serif;
font-weight: bold;
}
}
}
.spike-box {
position: relative;
width: 10rpx;
height: 40rpx;
background: #ffa500;
margin: -10rpx 0 0 118rpx;
transform-origin: 50% -90rpx;
-webkit-transform-origin: 50% -90rpx;
animation: swing 4s infinite ease-in-out;
-webkit-animation: swing 4s infinite ease-in-out;
border-radius: 0 0 10rpx 10rpx;
.dots-tip {
position: absolute;
top: 28rpx;
left: -4rpx;
width: 20rpx;
height: 20rpx;
background: #dc8f03;
border-radius: 50%;
}
.spike-tip {
position: absolute;
top: 36rpx;
left: -4rpx;
width: 20rpx;
height: 70rpx;
background: #ffa500;
border-radius: 0 0 0 10rpx;
}
}
}
.cont-outer-box {
top: -60rpx;
right: 20rpx;
.lantern-box {
animation: swing 5s infinite ease-in-out;
-webkit-animation: swing 5s infinite ease-in-out;
box-shadow: -10rpx 10rpx 60rpx 8rpx rgba(252, 144, 61, 1);
}
}
@keyframes swing {
0% {
-webkit-transform: rotate(-10deg);
}
50% {
-webkit-transform: rotate(10deg);
}
100% {
-webkit-transform: rotate(-10deg);
}
}
@-webkit-keyframes swing {
0% {
-webkit-transform: rotate(-10deg);
}
50% {
-webkit-transform: rotate(10deg);
}
100% {
-webkit-transform: rotate(-10deg);
}
}
}
</style>
<style>
page {
background-color: #222;
}
</style>
自定义顶部导航栏
![](https://i-blog.csdnimg.cn/blog_migrate/21f95dec25e74fdf29c43033e14c8da8.png)
<!-- 自定义顶部导航栏 -->
<template>
<view class="container" :style="'padding-top: ' + navHeight + 'rpx'">
<view class="head-back">
<image src="/static/return.png" mode="aspectFill" @click="toBack" />
<image src="/static/home.png" mode="aspectFill" @click="toHome" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
statusBarHeight: 0, // 状态导航栏高度
navigationBarHeight: 0, // 导航栏高度(标题栏高度)
navHeight: 0 // 总体高度
};
},
onLoad() {
/** 状态栏高度 */
this.statusBarHeight = wx.getSystemInfoSync().statusBarHeight;
/** 获取微信胶囊的位置信息 width,height,top,right,left,bottom */
const custom = wx.getMenuButtonBoundingClientRect();
/** 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2 */
this.navigationBarHeight = custom.height + (custom.top - this.statusBarHeight) * 2;
/** 总体高度 = 状态栏高度 + 导航栏高度 */
this.navHeight = this.navigationBarHeight + this.statusBarHeight;
},
methods: {
/* 返回 */
toBack() {
console.log("返回");
},
/* 回到首页 */
toHome() {
console.log("回到首页");
}
}
};
</script>
<style lang="scss" scoped>
.container {
padding-bottom: 25rpx;
background-color: rgba(0, 0, 0, 0.7);
.head-back {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
width: 180rpx;
height: 60rpx;
padding: 0 20rpx;
margin-left: 25rpx;
border: 1rpx solid rgba(204, 204, 204, 0.6);
box-sizing: border-box;
border-radius: 50rpx;
image {
width: 40rpx;
height: 40rpx;
}
}
.head-back::after {
content: "";
position: absolute;
top: 10%;
left: calc(50% - 1rpx);
width: 2rpx;
height: 80%;
background: #fff;
}
}
</style>
滚动自动吸顶
![](https://i-blog.csdnimg.cn/blog_migrate/0b36fbaac4f467ab67a71838cf40028d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3749a80859535cd1d926146100b798cd.png)
<!-- 滚动自动吸顶 -->
<template>
<view class="container">
<view class="head-box">头部内容区域</view>
<view class="nav-box" :class="isFixed ? 'fix-tip' : ''" id="navBox">
<view class="nav-item" :class="{ 'active-tip': curNav === i }" v-for="(item, i) in navList" :key="i" @click="navToggle(i)">
{{ item }}
</view>
</view>
<view :class="isFixed ? 'p-t-nav' : ''" id="contBox">
<view class="cont-item" v-for="(item, i) in curNav * 10 + 5" :key="i">{{ item }}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isFixed: false, // 是否吸顶
navTop: 0, // 导航栏到顶部的距离
curNav: 0, // 当前导航栏
navList: ["未开始", "进行中", "已结束"]
};
},
onReady() {
// 获取节点距离顶部的距离
uni
.createSelectorQuery()
.select("#navBox")
.boundingClientRect(rect => {
if (rect && rect.top) this.navTop = parseInt(rect.top);
})
.exec();
},
/* 监听页面滚动事件 */
onPageScroll(e) {
this.isFixed = parseInt(e.scrollTop) >= this.navTop;
},
methods: {
/* 导航栏切换 */
navToggle(i) {
if (this.curNav == i) return;
this.curNav = i;
if (this.isFixed) uni.pageScrollTo({ selector: "#contBox", duration: 0.5 }); // duration.滚动到指定位置需要的时间
}
}
};
</script>
<style lang="scss" scoped>
.container {
$navHeight: 88rpx; // nav导航栏高度
.head-box {
width: 100%;
height: 300rpx;
color: #fff;
font-size: 26rpx;
padding: 30rpx;
background: linear-gradient(90deg, #f54ea2, #ff7676);
box-sizing: border-box;
}
.nav-box {
position: relative;
display: flex;
width: 100%;
height: $navHeight;
line-height: $navHeight;
background: #fff;
box-shadow: 0 5rpx 5rpx #ccc;
.nav-item {
position: relative;
flex: 1;
text-align: center;
color: #333;
font-size: 28rpx;
}
.nav-item::after {
content: "";
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 4rpx;
width: 0;
height: 6rpx;
background: linear-gradient(90deg, #f54ea2, #ff7676);
transition: 0.3s width linear;
border-radius: 3rpx;
}
.active-tip {
color: transparent;
font-size: 30rpx;
background-clip: text;
-webkit-background-clip: text;
background-image: linear-gradient(90deg, #f54ea2, #ff7676);
transition: 0.3s all linear;
transition-delay: 0.1s;
font-weight: 900;
}
.active-tip::after {
width: 40%;
}
}
.fix-tip {
position: fixed;
top: 0;
left: 0;
z-index: 99;
}
.p-t-nav {
padding-top: $navHeight;
}
.cont-item {
text-align: center;
height: 50rpx;
line-height: 50rpx;
color: #999;
padding: 20rpx;
background: #fff;
border-bottom: 1rpx solid #eaeef1;
}
}
</style>
swiper 消息滚动
![](https://i-blog.csdnimg.cn/blog_migrate/381d26f1ff258f7c52ea80d90e22b701.png)
<!-- swiper 消息滚动 -->
<template>
<view>
<!-- 展示一条数据 -->
<template>
<view class="tit-box">
<view class="tit-tip">展示一条数据</view>
</view>
<view class="scroll-notice">
<image class="horn-tip" src="https://img1.baidu.com/it/u=3874629958,3395061015&fm=253" />
<swiper
class="notice-box"
vertical
autoplay
circular
interval="4000"
duration="1500"
display-multiple-items="1"
easing-function="easeInOutCubic"
>
<swiper-item v-for="(item, i) in swiperList" :key="i">
<view class="item-box">
<view>{{ item.bonusTime }}</view>
<view class="name-tip">抽中了 {{ item.awardName }}</view>
</view>
</swiper-item>
</swiper>
<image class="arrow-tip" src="https://img0.baidu.com/it/u=1153718811,3800194060&fm=253" />
</view>
</template>
<!-- 展示两条数据 -->
<template>
<view class="tit-box">
<view class="tit-tip">展示两条数据</view>
</view>
<view class="fix-two-box">
<view class="title-box">
<view class="line-tip"></view>
<view class="title-tip">展示两条数据</view>
<view class="line-tip"></view>
</view>
<swiper class="fix-swiper" vertical autoplay circular interval="3000" display-multiple-items="2">
<swiper-item v-for="(item, i) in dataList" :key="i">
<view class="item-box">
<view>{{ item.bonusTime }}</view>
<view class="name-tip">抽中了 {{ item.awardName }}</view>
</view>
</swiper-item>
</swiper>
</view>
</template>
<!-- 高度随数据长度而变化 -->
<template>
<view class="tit-box">
<view class="tit-tip">高度随数据长度而变化</view>
<view class="btn-tip" :class="{ 'is-sel': curLen === 3 }" @click="toSwitchLen(3)">3条</view>
<view class="btn-tip" :class="{ 'is-sel': curLen === 6 }" @click="toSwitchLen(6)">6条</view>
<view class="btn-tip" :class="{ 'is-sel': curLen === 'all' }" @click="toSwitchLen('all')">全部</view>
</view>
<view class="vary-swiper">
<swiper
vertical
autoplay
circular
interval="3000"
:style="'height: ' + (swiperList.length > 6 ? 460 : swiperList.length * 60) + 'rpx'"
:display-multiple-items="swiperList.length > 6 ? 7 : swiperList.length"
>
<swiper-item v-for="(item, i) in swiperList" :key="i">
<view class="item-box">
<view>{{ item.bonusTime }}</view>
<view class="name-tip">抽中了 {{ item.awardName }}</view>
</view>
</swiper-item>
</swiper>
</view>
</template>
</view>
</template>
<script>
export default {
data() {
return {
dataList: [
{ bonusTime: "2023/11/01 10:10", awardName: "iPhone 12 Pro Max" },
{ bonusTime: "2023/11/02 11:15", awardName: "华为Mate 40 Pro" },
{ bonusTime: "2023/11/03 12:20", awardName: "三星Galaxy S21 Ultra" },
{ bonusTime: "2023/11/04 13:25", awardName: "小米11 Ultra" },
{ bonusTime: "2023/11/05 14:30", awardName: "OPPO Find X3 Pro" },
{ bonusTime: "2023/11/06 15:35", awardName: "vivo X60 Pro+" },
{ bonusTime: "2023/11/07 16:40", awardName: "谷歌Pixel 6 Pro" },
{ bonusTime: "2023/11/08 17:45", awardName: "荣耀V40" }
], // 数据源
/* 高度随数据长度而变化 */
curLen: "",
swiperList: []
};
},
onLoad() {
this.toSwitchLen("all"); // 切换数据长度
},
methods: {
/* 切换数据长度 */
toSwitchLen(e) {
if (this.curLen === e) return;
this.curLen = e;
const rowData = JSON.parse(JSON.stringify(this.dataList));
if (e === "all") e = rowData.length;
this.swiperList = rowData.slice(0, e);
}
}
};
</script>
<style lang="scss" scoped>
.tit-box {
display: flex;
align-items: center;
justify-content: space-between;
margin: 60rpx 30rpx 30rpx;
.tit-tip {
font-weight: 900;
}
.btn-tip {
font-size: 24rpx;
color: #ff6348;
padding: 5rpx 20rpx;
border: 1px solid #ff7f50;
border-radius: 15rpx;
}
.is-sel {
color: #fff;
background: #ff6348;
}
}
/* 展示一条数据 */
.scroll-notice {
$noticeHeight: 66rpx;
display: flex;
align-items: center;
flex-direction: row;
height: $noticeHeight;
line-height: $noticeHeight;
padding: 0 24rpx;
margin: 30rpx;
background: #fdf6ec;
border-radius: 12rpx;
// 小喇叭
.horn-tip {
flex-shrink: 0;
width: 34rpx;
height: 28rpx;
margin-right: 10rpx;
}
.notice-box {
flex: 1;
height: $noticeHeight;
.item-box {
display: flex;
align-items: center;
font-size: 26rpx;
.name-tip {
color: #ff9900;
margin-left: 6rpx;
}
}
}
// 向右箭头
.arrow-tip {
flex-shrink: 0;
width: 22rpx;
height: 22rpx;
}
}
/* 展示两条数据 */
.fix-two-box {
margin: 30rpx;
border: 1px solid #2979ff;
border-radius: 30rpx;
.title-box {
$bgColor: #2979ff; // 字体、线条颜色
$lineWidth: 140; // 线条长度
display: flex;
align-items: center;
justify-content: center;
margin-top: 30rpx;
.line-tip {
position: relative;
width: $lineWidth + rpx;
height: 1rpx;
background: $bgColor;
}
.line-tip::before {
content: "";
position: absolute;
bottom: -7rpx;
width: $lineWidth / 3 + 10 + rpx;
height: 1rpx;
background: $bgColor;
}
.line-tip:nth-child(1)::before {
right: 0;
}
.title-tip {
color: $bgColor;
font-size: 36rpx;
margin: 0 20rpx;
font-weight: 900;
}
}
.fix-swiper {
height: 150rpx;
font-size: 28rpx;
margin-top: 30rpx;
.item-box {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 26rpx;
padding: 10rpx 30rpx;
.name-tip {
color: #2979ff;
}
}
}
}
/* 高度随数据长度而变化 */
.vary-swiper {
margin: 30rpx;
box-sizing: border-box;
border-radius: 30rpx;
border: 1px solid #ff7f50;
.item-box {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 26rpx;
padding: 10rpx 30rpx;
.name-tip {
color: #ff6348;
}
}
}
</style>
swiper 商品滑动
![](https://i-blog.csdnimg.cn/blog_migrate/74787a2c7db9e09d2360c097c6251a01.png)
<!-- swiper 商品滑动 -->
<template>
<view>
<!-- 一次滑动三条 -->
<view class="container">
<view class="tit_box">
<view class="tit-tip">精选商品</view>
</view>
<view class="cont-box">
<swiper class="swiper-box" :indicator-dots="false" autoplay interval="5000" duration="1000" circular>
<swiper-item v-for="(row, i) in goodsList" :key="i">
<view class="item-box" v-for="(item, j) in row.list" :key="j">
<image class="img-tip" :src="item.img" mode="aspectFill" />
<view class="name-tip">商品{{ j }}</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
<!-- 一次滑动一条 -->
<view class="container">
<view class="tit_box">
<view class="tit-tip">精选商品</view>
</view>
<view class="cont-box">
<swiper
class="swiper-box"
:indicator-dots="false"
autoplay
interval="1500"
duration="1000"
circular
:display-multiple-items="recordList.length > 2 ? 3 : recordList.length"
>
<swiper-item v-for="(item, i) in recordList" :key="i">
<view class="item-box" style="width: 100%">
<image class="img-tip" :src="item.img" mode="aspectFill" />
<view class="name-tip">商品{{ i }}</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
goodsList: [
{
list: [
{ img: "https://images.pexels.com/photos/1660030/pexels-photo-1660030.jpeg" },
{ img: "https://images.pexels.com/photos/1640774/pexels-photo-1640774.jpeg" },
{ img: "https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg" }
]
},
{
list: [
{ img: "https://images.pexels.com/photos/70497/pexels-photo-70497.jpeg" },
{ img: "https://images.pexels.com/photos/7441761/pexels-photo-7441761.jpeg" },
{ img: "https://images.pexels.com/photos/842571/pexels-photo-842571.jpeg" }
]
},
{
list: [
{ img: "https://images.pexels.com/photos/17216084/pexels-photo-17216084.jpeg" },
{ img: "https://images.pexels.com/photos/8969237/pexels-photo-8969237.jpeg" },
{ img: "https://images.pexels.com/photos/1099680/pexels-photo-1099680.jpeg" }
]
}
],
recordList: [
{ img: "https://images.pexels.com/photos/1660030/pexels-photo-1660030.jpeg" },
{ img: "https://images.pexels.com/photos/1640774/pexels-photo-1640774.jpeg" },
{ img: "https://images.pexels.com/photos/699953/pexels-photo-699953.jpeg" },
{ img: "https://images.pexels.com/photos/70497/pexels-photo-70497.jpeg" },
{ img: "https://images.pexels.com/photos/7441761/pexels-photo-7441761.jpeg" },
{ img: "https://images.pexels.com/photos/842571/pexels-photo-842571.jpeg" },
{ img: "https://images.pexels.com/photos/17216084/pexels-photo-17216084.jpeg" }
]
};
},
onLoad() {},
methods: {}
};
</script>
<style lang="scss" scoped>
.container {
position: relative;
height: 228rpx;
margin: 20rpx;
background: #ff4757;
border-radius: 20rpx;
overflow: hidden;
.tit_box {
width: 110rpx;
text-align: center;
height: 100%;
background: #ff6b81;
.tit-tip {
display: inline-block;
color: #fff;
width: 50rpx;
text-align: center;
vertical-align: middle;
font-size: 30rpx;
white-space: pre-wrap;
font-weight: 900;
}
}
.tit_box::after {
content: "";
display: inline-block;
height: 100%;
vertical-align: middle;
}
.cont-box {
position: absolute;
top: 20rpx;
left: 108rpx;
width: 84%;
white-space: nowrap;
overflow-y: auto;
box-sizing: border-box;
.swiper-box {
height: 192rpx;
overflow: hidden;
.item-box {
float: left;
width: calc(100% / 3);
height: 192rpx;
text-align: center;
.img-tip {
display: block;
width: 145rpx;
height: 154rpx;
margin: 0 auto 9rpx;
border-radius: 16rpx;
}
.name-tip {
text-align: center;
height: 30rpx;
line-height: 30rpx;
color: #fff;
font-size: 22rpx;
}
}
}
}
}
</style>