miroir de
https://github.com/ialley-workshop-open/uni-halo.git
synchronisé 2026-06-12 13:19:31 +08:00
v1.0.0-beta 源码正式开源
Cette révision appartient à :
@@ -0,0 +1,341 @@
|
||||
// 轮播图
|
||||
|
||||
.Swiper-mfw-index-box {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
view {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Swiper-mfw-index {
|
||||
// 轮播图
|
||||
width: 100%;
|
||||
.Swiper-mfw {
|
||||
width: inherit;
|
||||
height: 450rpx;
|
||||
border-radius: 12rpx;
|
||||
.swiper-mfw-item {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: 12rpx;
|
||||
.Image,
|
||||
.ImageVideo {
|
||||
border-radius: 12rpx;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 指示器
|
||||
.Swiper-indicator-box {
|
||||
width: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
// Top顶部 [今日首推-盒子]
|
||||
.Top-date-hot {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
.left-date-ri {
|
||||
justify-content: center;
|
||||
.date-ri-text {
|
||||
color: #ffffff;
|
||||
font-size: 60rpx;
|
||||
font-weight: 700;
|
||||
margin-top: -4rpx;
|
||||
}
|
||||
}
|
||||
.conter-date-nianyue {
|
||||
margin: 0 14rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
.left-width-bgcolor {
|
||||
width: 8rpx;
|
||||
height: 45rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #fafafa;
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
.right-date-nianyue {
|
||||
flex-direction: column;
|
||||
.Top-yue-usa,
|
||||
.Bottom-nian,
|
||||
.text {
|
||||
color: #ffffff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
.text {
|
||||
margin-top: -4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-hot-ttf {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin-left: 6rpx;
|
||||
.hot-text {
|
||||
color: #ffffff;
|
||||
font-size: 52rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 指示器 [轮播信息 -> 标题,用户,头像,所在地]
|
||||
.Swiper-indicator-Top {
|
||||
position: absolute;
|
||||
left: 0rpx;
|
||||
bottom: 110rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx 24rpx;
|
||||
&.no-dot {
|
||||
bottom: 0;
|
||||
}
|
||||
.Top-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// 如果有视频,则显示“视频预览”
|
||||
.Top-ImageVideo {
|
||||
width: 150rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 2rpx 6rpx;
|
||||
margin-bottom: 10rpx;
|
||||
background-color: #f0ad4e;
|
||||
border-radius: 20rpx;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
.Icons {
|
||||
color: #242629;
|
||||
font-size: 26rpx;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
.ImageVideo-text {
|
||||
color: #242629;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 标题
|
||||
.Top-Title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
.title-text {
|
||||
width: 100%;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
// 用户信息盒子
|
||||
.Bottom-UserInfo {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
margin-top: 16rpx;
|
||||
align-items: center;
|
||||
.UserImage-box {
|
||||
width: 40rpx;
|
||||
border-radius: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
.Image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.textbox {
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
.wo-text,
|
||||
.UserInfo {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.wo-text {
|
||||
color: #f1f2f6;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
.UserInfo {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.jiange-box {
|
||||
margin: 0 8rpx;
|
||||
.jiange-text {
|
||||
color: #f1f2f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 指示器 [左边图片列表+右边按钮]
|
||||
.Swiper-indicator-Bottom {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-radius: 12rpx;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
box-sizing: border-box;
|
||||
padding: 14rpx;
|
||||
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.4), rgba(101, 101, 101, 0.7));
|
||||
// 左边[图片列表]
|
||||
.Bottom-left-Imagelist {
|
||||
// width: 560rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
// 指示图(小图模式)
|
||||
.Bottom-item {
|
||||
width: 98rpx;
|
||||
height: 78rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.Image {
|
||||
width: 98rpx;
|
||||
height: 78rpx;
|
||||
border-radius: 8rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
&.current {
|
||||
.Image {
|
||||
// border: 4rpx solid #ffda02;
|
||||
border: 4rpx solid rgb(110, 186, 247);
|
||||
}
|
||||
}
|
||||
}
|
||||
.Bottom-item + .Bottom-item {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
// 右边 [历历在目-按钮]
|
||||
.Bottom-right-lili-btn {
|
||||
width: 145rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10rpx;
|
||||
// background-image: linear-gradient(45deg, rgb(110, 186, 247), rgb(13, 141, 242));
|
||||
.Bottom-item {
|
||||
width: 145rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
.indicator-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
font-size: 26rpx;
|
||||
.iconfont {
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
// font-weight: normal;
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.Swiper-box {
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden !important;
|
||||
transform: translateY(0) !important;
|
||||
transform: translateX(0) !important;
|
||||
&.right {
|
||||
.indicator-Top-box {
|
||||
position: absolute;
|
||||
}
|
||||
.Swiper-indicator-Top {
|
||||
bottom: 0;
|
||||
.Top-item .Top-Title .title-text {
|
||||
width: 540rpx;
|
||||
}
|
||||
}
|
||||
.Swiper-indicator-Bottom {
|
||||
width: 120rpx;
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
left: initial;
|
||||
right: 0rpx;
|
||||
flex-direction: column;
|
||||
background-image: none;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
// border-radius: 0rpx 12rpx 12rpx 0;
|
||||
border-radius: 12rpx;
|
||||
.Bottom-left-Imagelist {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.Bottom-item {
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
.Bottom-item + .Bottom-item {
|
||||
margin-left: 0rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
.Bottom-right-lili-btn {
|
||||
width: 100rpx;
|
||||
margin-left: -4rpx;
|
||||
.Bottom-item {
|
||||
width: initial;
|
||||
margin-top: 6rpx;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.text {
|
||||
letter-spacing: 0;
|
||||
font-size: 24rpx;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Swiper-mfw {
|
||||
position: relative;
|
||||
}
|
||||
.indicator-Top-box {
|
||||
position: absolute;
|
||||
}
|
||||
.indicator-Btoom-box {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<!-- 轮播图 -->
|
||||
<view class="Swiper-mfw-index-box">
|
||||
<view class="Swiper-mfw-index Swiper-box" :class="[dotPosition]">
|
||||
<swiper
|
||||
class="Swiper-mfw"
|
||||
:style="{ height: height }"
|
||||
:circular="true"
|
||||
:indicator-dots="false"
|
||||
:autoplay="autoplay"
|
||||
:interval="3000"
|
||||
:duration="1000"
|
||||
:current="currentIndex"
|
||||
:disable-touch="disable_touch"
|
||||
@change="change"
|
||||
>
|
||||
<!-- 只需要前5条数据 -->
|
||||
<swiper-item class="swiper-mfw-item" v-if="index <= (dotPosition == 'right' ? 3 : 4)" v-for="(item, index) in list" :key="index">
|
||||
<!-- /*
|
||||
1. 这里不需要用api控制暂停视频
|
||||
2. 因为video标签上加了v-if="current==index"
|
||||
3. 当current == index时才会创建视频组件
|
||||
4. 否current != index则就销毁视频
|
||||
*/ -->
|
||||
<!-- 如果有视频,则显示视频-->
|
||||
<template v-if="item.mp4 && current == index">
|
||||
<video
|
||||
class="ImageVideo"
|
||||
:id="'ImageVideo' + index"
|
||||
:ref="'ImageVideo' + index"
|
||||
:src="item.mp4"
|
||||
:loop="true"
|
||||
:muted="false"
|
||||
:autoplay="current == index ? true : false"
|
||||
:controls="false"
|
||||
:show-fullscreen-btn="false"
|
||||
:show-play-btn="false"
|
||||
:enable-progress-gesture="false"
|
||||
:play-strategy="0"
|
||||
:poster="item.image || item.src"
|
||||
></video>
|
||||
</template>
|
||||
<!-- 否则显示图片 -->
|
||||
<image v-else :src="item.image || item.src" class="Image" mode="aspectFill" @click.stop="$emit('on-click', item)"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- 指示器 [Top] -->
|
||||
<view v-if="useTop" class="Swiper-indicator-box indicator-Top-box">
|
||||
<!-- Top顶部 [今日首推-盒子] -->
|
||||
<view class="Top-date-hot">
|
||||
<view class="left-date-ri">
|
||||
<text class="date-ri-text text">{{ date.month }}</text>
|
||||
</view>
|
||||
<view class="conter-date-nianyue">
|
||||
<view class="left-width-bgcolor"></view>
|
||||
<view class="right-date-nianyue">
|
||||
<text class="Top-yue-usa text">{{ date.monthEn }}</text>
|
||||
<text class="Bottom-nian text">{{ date.year }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right-hot-ttf">
|
||||
<text class="text hot-text">{{ title }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 指示器 标题区域 -->
|
||||
<view v-if="useTitle" class="Swiper-indicator-Top" :class="{ 'no-dot': !useDot }">
|
||||
<block v-for="(item, index) in list" :key="index">
|
||||
<view v-if="currentIndex == index" class="Top-item" :class="current == index ? 'current' : 'no'">
|
||||
<!-- 如果存在视频,则显示“视频预览”提示 -->
|
||||
<view v-if="item.mp4" class="Top-ImageVideo">
|
||||
<!-- icon图标 -->
|
||||
<view class="Icons">
|
||||
<!-- 播放按钮图标 -->
|
||||
<text class="iconfont icon-caret-right"></text>
|
||||
</view>
|
||||
<text class="text ImageVideo-text app-ttf">视频预览</text>
|
||||
</view>
|
||||
<!-- 标题 -->
|
||||
<view class="Top-Title">
|
||||
<text class="text title-text">{{ item.title }}</text>
|
||||
</view>
|
||||
<!-- 用户信息 -->
|
||||
<view class="Bottom-UserInfo">
|
||||
<!-- 头像 -->
|
||||
<view class="UserImage-box"><image :src="item.avatar" class="Image" mode="aspectFill"></image></view>
|
||||
<!-- 用户名 -->
|
||||
<view class="textbox UserName-box">
|
||||
<text class="text UserInfo">{{ item.nickname }}</text>
|
||||
</view>
|
||||
<view v-if="item.createTime" class="jiange-box"><text class="text jiange-text"></text></view>
|
||||
<view v-if="item.createTime" class="textbox UserGPS-box">
|
||||
<text class="text UserInfo">发布于 {{ item.createTime }}</text>
|
||||
</view>
|
||||
<view v-if="item.address" class="jiange-box"><text class="text jiange-text">·</text></view>
|
||||
<view v-if="item.address" class="textbox UserGPS-box">
|
||||
<text class="text UserInfo">{{ item.address }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<!-- 指示器 [左边图片列表+右边按钮] -->
|
||||
<view v-if="useDot" class="Swiper-indicator-Bottom">
|
||||
<!-- 左边 -->
|
||||
<view class="Bottom-left-Imagelist">
|
||||
<block v-for="(item, index) in list" :key="index">
|
||||
<view
|
||||
class="Bottom-item"
|
||||
v-if="Number(index) <= (dotPosition == 'right' ? 3 : 4)"
|
||||
:class="currentIndex == index ? 'current' : 'no'"
|
||||
@click="SwiperIndTap(index)"
|
||||
>
|
||||
<image :src="item.image || item.src" class="Image" mode="aspectFill"></image>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<!-- 右边 -->
|
||||
<view class="Bottom-right-lili-btn">
|
||||
<view class="Bottom-item is-more">
|
||||
<view class="more" @click.stop="$emit('on-more')">
|
||||
MORE
|
||||
<text class="iconfont icon-caret-right"></text>
|
||||
</view>
|
||||
<text class="left text indicator-text">更多推荐</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'e-swiper',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '450rpx'
|
||||
},
|
||||
dotPosition: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
useTop: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
useDot: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
useTitle: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
useUser: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 轮播图 数据列表
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// 当前选中的项(指示器坐标位置)
|
||||
current: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 是否自动轮播
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 是否禁止用户 touch 操作
|
||||
currentIndex: 0,
|
||||
disable_touch: false, //touch 用户划动引起swiper变化。
|
||||
date: {
|
||||
year: '-',
|
||||
monthEn: '-',
|
||||
month: '-'
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.currentIndex = this.current;
|
||||
const date = new Date();
|
||||
//将月份名称存储在数组中
|
||||
const monthArray = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
|
||||
|
||||
this.date.year = date.getFullYear();
|
||||
let month = date.getMonth() + 1;
|
||||
this.date.month = month < 10 ? '0' + month : month;
|
||||
this.date.monthEn = monthArray[date.getMonth()].toUpperCase();
|
||||
},
|
||||
methods: {
|
||||
// current 改变时会触发 change 事件,event.detail = {current: current, source: source}
|
||||
change(e) {
|
||||
let { current, source } = e.detail;
|
||||
//只有页面自动切换,手动切换时才轮播,其他不允许
|
||||
if (source === 'autoplay' || source === 'touch') {
|
||||
let event = {
|
||||
current: current
|
||||
};
|
||||
this.currentIndex = current;
|
||||
this.$emit('change', event);
|
||||
}
|
||||
},
|
||||
// 手动点击了指示器[小图模式]
|
||||
SwiperIndTap(e) {
|
||||
let index = e;
|
||||
let event = {
|
||||
current: index
|
||||
};
|
||||
this.currentIndex = index;
|
||||
this.$emit('change', event);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './e-swiper.scss';
|
||||
</style>
|
||||
Référencer dans un nouveau ticket
Bloquer un utilisateur