完善添加银行卡功能
This commit is contained in:
@@ -78,3 +78,12 @@ export const getRegion = data => {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 用户积分排行榜 */
|
||||||
|
export const getUserIntegralRank = data => {
|
||||||
|
return http({
|
||||||
|
url: '/api/system/userPoints/list',
|
||||||
|
method: 'get',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,23 +1,90 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { navigateBack } from '@/utils/router'
|
import { navigateBack } from '@/utils/router'
|
||||||
import { useSlots } from 'vue'
|
import { useSlots, computed, ref, onMounted } from 'vue'
|
||||||
|
|
||||||
const slots = useSlots()
|
const slots = useSlots()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: { type: String, default: '' },
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
/** 导航栏颜色 */
|
||||||
|
targetColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#ffffff'
|
||||||
|
},
|
||||||
|
/** 滚动多少 rpx 后完全变为目标色 */
|
||||||
|
maxScroll: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
/** 是否带背景 */
|
/** 是否带背景 */
|
||||||
isTopBg: { type: Boolean, default: false },
|
isTopBg: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
/** 是否有占位符 */
|
/** 是否有占位符 */
|
||||||
isPlaceholder: { type: Boolean, default: false },
|
isPlaceholder: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
/** 是否自定义返回事件 */
|
/** 是否自定义返回事件 */
|
||||||
isCustomBack: { type: Boolean, default: false }
|
isCustomBack: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['onBack'])
|
const emits = defineEmits(['onBack'])
|
||||||
|
|
||||||
// 判断是否传入了名为 "back" 的插槽
|
// 判断是否传入了名为 "back" 的插槽
|
||||||
const hasBackSlot = !!slots.back
|
const hasBackSlot = !!slots.back
|
||||||
|
/** 全局存储当前滚动位置(供 computed 使用) */
|
||||||
|
const currentScrollTop = ref(0)
|
||||||
|
/** 缓存 rpx 转 px 的比例 */
|
||||||
|
const rpxToPxRatio = ref(1)
|
||||||
|
|
||||||
|
/** 将 props.maxScroll (rpx) 转为 px */
|
||||||
|
const maxScrollPx = computed(() => {
|
||||||
|
return props.maxScroll * rpxToPxRatio.value
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 当前背景色(RGBA 动态计算) */
|
||||||
|
const bgColor = computed(() => {
|
||||||
|
const scroll = getCurrentScroll()
|
||||||
|
const maxPx = maxScrollPx.value
|
||||||
|
const startFadeAt = maxPx / 3 // 1/3 处开始渐变
|
||||||
|
|
||||||
|
let alpha = 0
|
||||||
|
if (scroll >= maxPx) {
|
||||||
|
alpha = 1
|
||||||
|
} else if (scroll > startFadeAt) {
|
||||||
|
// 在 [startFadeAt, maxPx] 区间内线性插值
|
||||||
|
alpha = (scroll - startFadeAt) / (maxPx - startFadeAt)
|
||||||
|
alpha = Math.min(Math.max(alpha, 0), 1) // 安全 clamp
|
||||||
|
} else {
|
||||||
|
alpha = 0
|
||||||
|
}
|
||||||
|
// 解析颜色
|
||||||
|
const hex = props.targetColor.replace('#', '')
|
||||||
|
if (hex.length !== 6) {
|
||||||
|
return `rgba(0, 122, 255, ${alpha})`
|
||||||
|
}
|
||||||
|
const r = parseInt(hex.substring(0, 2), 16)
|
||||||
|
const g = parseInt(hex.substring(2, 4), 16)
|
||||||
|
const b = parseInt(hex.substring(4, 6), 16)
|
||||||
|
return `rgba(${r}, ${g}, ${b}, ${alpha})`
|
||||||
|
})
|
||||||
|
|
||||||
|
const getCurrentScroll = () => {
|
||||||
|
return currentScrollTop.value
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 暴露方法:供父页面 onPageScroll 调用 */
|
||||||
|
const updateScroll = scrollTop => {
|
||||||
|
currentScrollTop.value = scrollTop
|
||||||
|
}
|
||||||
|
|
||||||
const onBack = () => {
|
const onBack = () => {
|
||||||
if (props.isCustomBack) {
|
if (props.isCustomBack) {
|
||||||
@@ -26,11 +93,26 @@
|
|||||||
navigateBack()
|
navigateBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const sysInfo = uni.getSystemInfoSync()
|
||||||
|
rpxToPxRatio.value = sysInfo.windowWidth / 750
|
||||||
|
})
|
||||||
|
|
||||||
|
// 向外暴露方法
|
||||||
|
defineExpose({
|
||||||
|
updateScroll
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<view :class="{ 'nav-bar_bg': props.isTopBg }" class="nav-bar">
|
<view
|
||||||
|
:style="{
|
||||||
|
backgroundColor: props.isTopBg ? bgColor : 'transparent'
|
||||||
|
}"
|
||||||
|
class="nav-bar"
|
||||||
|
>
|
||||||
<view class="status_bar">
|
<view class="status_bar">
|
||||||
<!-- 这里是状态栏 -->
|
<!-- 这里是状态栏 -->
|
||||||
</view>
|
</view>
|
||||||
@@ -58,6 +140,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 占位符 -->
|
||||||
<view v-if="props.isPlaceholder" class="nav-bar-placeholder"></view>
|
<view v-if="props.isPlaceholder" class="nav-bar-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -70,10 +153,6 @@
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-bar_bg {
|
|
||||||
background: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top_left-icon {
|
.top_left-icon {
|
||||||
height: 36rpx;
|
height: 36rpx;
|
||||||
}
|
}
|
||||||
|
|||||||
48
pages.json
48
pages.json
@@ -59,6 +59,41 @@
|
|||||||
"backgroundColor": "#f7f7f7"
|
"backgroundColor": "#f7f7f7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my-index/personal-center/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "个人中心",
|
||||||
|
"navigationBarBackgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my-index/wallet/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "钱包",
|
||||||
|
"navigationBarBackgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my-index/wallet/edit-password",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "修改钱包密码",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my-index/wallet/bank-card/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "提现卡",
|
||||||
|
"navigationBarBackgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my-index/wallet/bank-card/card-details",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "卡信息增删改查",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/mall/list",
|
"path": "pages/mall/list",
|
||||||
"style": {
|
"style": {
|
||||||
@@ -128,6 +163,19 @@
|
|||||||
"navigationBarTitleText": "签到",
|
"navigationBarTitleText": "签到",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/discover/dynamic/dynamic",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "朋友圈",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/discover/company",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "公司介绍"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
|
|||||||
55
pages/discover/company.vue
Normal file
55
pages/discover/company.vue
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="company">
|
||||||
|
<view class="top-log">
|
||||||
|
<image
|
||||||
|
src="https://qcloud.dpfile.com/pc/TrdZpLN1zkXDV4oN2FH98LdVnvHj694NKQu0_KA3ul4eYxZWRPQ7CJuw-PqyZBS4.jpg"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="img"
|
||||||
|
></image>
|
||||||
|
<text>名字</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="consten">
|
||||||
|
<view class="item">富文本</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-log {
|
||||||
|
margin: 114rpx 0 96rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.img {
|
||||||
|
width: 192rpx;
|
||||||
|
height: 192rpx;
|
||||||
|
}
|
||||||
|
text {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.consten {
|
||||||
|
padding: 0 24rpx;
|
||||||
|
.item {
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 48rpx 32rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -20,6 +20,14 @@
|
|||||||
navigateTo('/pages/discover/punch')
|
navigateTo('/pages/discover/punch')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (item === 'company') {
|
||||||
|
navigateTo('/pages/discover/company')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (item === 'circle') {
|
||||||
|
navigateTo('/pages/discover/dynamic/dynamic')
|
||||||
|
return
|
||||||
|
}
|
||||||
if (item === 'mall') {
|
if (item === 'mall') {
|
||||||
navigateTo('/pages/mall/list')
|
navigateTo('/pages/mall/list')
|
||||||
return
|
return
|
||||||
|
|||||||
115
pages/discover/dynamic/dynamic.vue
Normal file
115
pages/discover/dynamic/dynamic.vue
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { onPageScroll } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
const MAX_SCROLL = 446
|
||||||
|
|
||||||
|
const cbNavBar = ref({})
|
||||||
|
const topIcon = reactive({
|
||||||
|
leftColor: '#ffffff',
|
||||||
|
rightColor: '#ffffff'
|
||||||
|
})
|
||||||
|
|
||||||
|
onPageScroll(e => {
|
||||||
|
cbNavBar.value?.updateScroll(e.scrollTop)
|
||||||
|
if (e.scrollTop > MAX_SCROLL - 220) {
|
||||||
|
topIcon.leftColor = '#000'
|
||||||
|
topIcon.rightColor = '#000'
|
||||||
|
} else {
|
||||||
|
topIcon.leftColor = '#ffffff'
|
||||||
|
topIcon.rightColor = '#ffffff'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="dynamic">
|
||||||
|
<nav-bar
|
||||||
|
ref="cbNavBar"
|
||||||
|
isTopBg
|
||||||
|
target-color="#f9f9f9"
|
||||||
|
:max-scroll="MAX_SCROLL"
|
||||||
|
>
|
||||||
|
<template #back>
|
||||||
|
<uni-icons
|
||||||
|
:color="topIcon.leftColor"
|
||||||
|
type="left"
|
||||||
|
size="24"
|
||||||
|
></uni-icons>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<uni-icons
|
||||||
|
:color="topIcon.rightColor"
|
||||||
|
type="camera"
|
||||||
|
size="24"
|
||||||
|
></uni-icons>
|
||||||
|
</template>
|
||||||
|
</nav-bar>
|
||||||
|
<view class="top-bg-img">
|
||||||
|
<image
|
||||||
|
src="https://wx4.sinaimg.cn/mw690/006i0nC8ly1hqugav3k6yj31o01o0aod.jpg"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="img"
|
||||||
|
></image>
|
||||||
|
<!-- 用户信息 -->
|
||||||
|
<view class="user-info">
|
||||||
|
<text>名字</text>
|
||||||
|
<image
|
||||||
|
src="https://img2.baidu.com/it/u=3408192385,656358498&fm=253&app=138&f=JPEG?w=760&h=760"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="avatar"
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 动态列表 -->
|
||||||
|
<view class="dynamic-list">
|
||||||
|
<view v-for="item in 4" class="list">
|
||||||
|
<image
|
||||||
|
src="https://img1.baidu.com/it/u=2645961124,1296922095&fm=253&app=138&f=JPEG?w=800&h=1530"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="avatar"
|
||||||
|
></image>
|
||||||
|
<view class="content">
|
||||||
|
<text class="name">名字</text>
|
||||||
|
<text class="text">这是一条朋友圈的标题</text>
|
||||||
|
<view class="img-list">
|
||||||
|
<image
|
||||||
|
src="https://p4.itc.cn/images01/20220619/46660ed163164c14be90e605a73ee5e8.jpeg"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="item-img"
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<!-- 地址 -->
|
||||||
|
<view class="address">
|
||||||
|
<text>19分钟前</text>
|
||||||
|
<text>重庆市渝北xxx寄街道</text>
|
||||||
|
</view>
|
||||||
|
<!-- 点赞评论 -->
|
||||||
|
<view class="like-box">
|
||||||
|
<view class="like">
|
||||||
|
<uni-icons
|
||||||
|
type="hand-up"
|
||||||
|
size="20"
|
||||||
|
color="#747474"
|
||||||
|
></uni-icons>
|
||||||
|
<text>22</text>
|
||||||
|
</view>
|
||||||
|
<uni-icons type="chat" size="20" color="#747474"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<!-- 评论内容 -->
|
||||||
|
<view class="comment">
|
||||||
|
<view v-for="item in 3" :key="item" class="comment-item">
|
||||||
|
<text>Admin:</text>
|
||||||
|
<text>确实的很好,值得推荐的很好</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../styles/dynamic.scss';
|
||||||
|
</style>
|
||||||
@@ -1,4 +1,15 @@
|
|||||||
<script setup></script>
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const indexData = ref([1, 2, 3, 4])
|
||||||
|
|
||||||
|
const onItem = item => {
|
||||||
|
if (indexData.value.includes(item)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
indexData.value.push(item)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="punch">
|
<view class="punch">
|
||||||
@@ -12,20 +23,130 @@
|
|||||||
</template>
|
</template>
|
||||||
</nav-bar>
|
</nav-bar>
|
||||||
<view class="public-header—box">
|
<view class="public-header—box">
|
||||||
<!-- <image
|
<view class="integral-box">
|
||||||
src="/static/images/ranking-list/title-icon.png"
|
<text>我的积分</text>
|
||||||
mode="aspectFit"
|
<text>410</text>
|
||||||
class="left-icon"
|
</view>
|
||||||
></image>
|
|
||||||
<image
|
<image
|
||||||
src="/static/images/ranking-list/hat.png"
|
src="/static/images/discover/calendar.png"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
class="right-icon"
|
class="right-icon"
|
||||||
></image> -->
|
></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="punch-box">
|
||||||
|
<view class="top-title">
|
||||||
|
<text class="title">每日签到领积分</text>
|
||||||
|
<view class="right-box">
|
||||||
|
<text>已连续签到</text>
|
||||||
|
<text>05</text>
|
||||||
|
<text>天</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 签到列表 -->
|
||||||
|
<view class="list-box">
|
||||||
|
<view
|
||||||
|
v-for="item in 30"
|
||||||
|
:key="item"
|
||||||
|
:class="{ active: indexData.includes(item) }"
|
||||||
|
class="item"
|
||||||
|
@click="onItem(item)"
|
||||||
|
>
|
||||||
|
<view class="bg-box">
|
||||||
|
<image
|
||||||
|
src="/static/images/discover/bean.png"
|
||||||
|
mode="heightFix"
|
||||||
|
class="icon"
|
||||||
|
></image>
|
||||||
|
<text>+10</text>
|
||||||
|
</view>
|
||||||
|
<text class="bottom-name">今天</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './styles/index.scss';
|
@import './styles/index.scss';
|
||||||
|
.punch-box {
|
||||||
|
padding: 0 24rpx;
|
||||||
|
.top-title {
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.right-box {
|
||||||
|
margin-left: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
&:nth-child(2) {
|
||||||
|
margin: 0 4rpx;
|
||||||
|
color: #00d993;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-box {
|
||||||
|
margin-top: 38rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, 1fr);
|
||||||
|
grid-gap: 22rpx;
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
.bg-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 80rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
background: #f4f4f4;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
.icon {
|
||||||
|
height: 48rpx;
|
||||||
|
}
|
||||||
|
text {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom-name {
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
.bg-box {
|
||||||
|
background: linear-gradient(0deg, #00d993 0%, #00d9c5 100%);
|
||||||
|
text {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom-name {
|
||||||
|
color: #00d993;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,36 @@
|
|||||||
<script setup></script>
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { onLoad, onPageScroll } from '@dcloudio/uni-app'
|
||||||
|
import { getUserIntegralRank } from '@/api'
|
||||||
|
|
||||||
|
const cbNavBar = ref({})
|
||||||
|
const listData = ref([])
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
const res = await getUserIntegralRank({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 100
|
||||||
|
})
|
||||||
|
listData.value = res.rows
|
||||||
|
}
|
||||||
|
|
||||||
|
onPageScroll(e => {
|
||||||
|
cbNavBar.value?.updateScroll(e.scrollTop)
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="ranking-list">
|
<view class="ranking-list">
|
||||||
<nav-bar>
|
<nav-bar
|
||||||
|
ref="cbNavBar"
|
||||||
|
isTopBg
|
||||||
|
target-color="#f9f9f9"
|
||||||
|
:max-scroll="446"
|
||||||
|
>
|
||||||
<template #back>
|
<template #back>
|
||||||
<image
|
<image
|
||||||
src="/static/images/public/return-icon.png"
|
src="/static/images/public/return-icon.png"
|
||||||
@@ -46,8 +74,8 @@
|
|||||||
</uni-row>
|
</uni-row>
|
||||||
<!-- 列表内容 -->
|
<!-- 列表内容 -->
|
||||||
<uni-row
|
<uni-row
|
||||||
v-for="(item, index) in 19"
|
v-for="(item, index) in listData"
|
||||||
:key="index"
|
:key="item.id"
|
||||||
class="table-content"
|
class="table-content"
|
||||||
>
|
>
|
||||||
<uni-col :span="6">
|
<uni-col :span="6">
|
||||||
@@ -69,14 +97,14 @@
|
|||||||
class="left-icon"
|
class="left-icon"
|
||||||
></image>
|
></image>
|
||||||
<view class="name">
|
<view class="name">
|
||||||
<text>张三</text>
|
<text>名字</text>
|
||||||
<text>158****98874</text>
|
<text>158****98874</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uni-col>
|
</uni-col>
|
||||||
<uni-col :span="6">
|
<uni-col :span="6">
|
||||||
<view class="table-right">
|
<view class="table-right">
|
||||||
<text class="item-text">100</text>
|
<text class="item-text">{{ item.totalPoints }}</text>
|
||||||
</view>
|
</view>
|
||||||
</uni-col>
|
</uni-col>
|
||||||
</uni-row>
|
</uni-row>
|
||||||
|
|||||||
126
pages/discover/styles/dynamic.scss
Normal file
126
pages/discover/styles/dynamic.scss
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
.top-bg-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 544rpx;
|
||||||
|
position: relative;
|
||||||
|
.img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.user-info {
|
||||||
|
position: absolute;
|
||||||
|
right: 24rpx;
|
||||||
|
bottom: -60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
text {
|
||||||
|
margin-top: 30rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-list {
|
||||||
|
padding: 86rpx 26rpx 0 26rpx;
|
||||||
|
.list + .list {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
}
|
||||||
|
.list {
|
||||||
|
display: flex;
|
||||||
|
.avatar {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border-radius: 96rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 32rpx;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.name {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
margin: 16rpx 0;
|
||||||
|
}
|
||||||
|
.img-list {
|
||||||
|
.item-img {
|
||||||
|
width: 410rpx;
|
||||||
|
height: 250rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.address {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 16rpx 0 14rpx;
|
||||||
|
text {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999999;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
&:last-child {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #0c587e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.like-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.like {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 86rpx;
|
||||||
|
text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #747474;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.comment {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
padding: 16rpx 18rpx;
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
.comment-item + .comment-item {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
.comment-item {
|
||||||
|
text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
&:last-child {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,27 @@
|
|||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
border-radius: 32rpx 32rpx 0rpx 0rpx;
|
border-radius: 32rpx 32rpx 0rpx 0rpx;
|
||||||
}
|
}
|
||||||
|
.integral-box {
|
||||||
|
width: 354rpx;
|
||||||
|
height: 166rpx;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 82rpx;
|
||||||
|
left: 48rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
text {
|
||||||
|
font-size: 32rpx;
|
||||||
|
&:last-child {
|
||||||
|
font-size: 100rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.left-icon {
|
.left-icon {
|
||||||
width: 354rpx;
|
width: 354rpx;
|
||||||
height: 166rpx;
|
height: 166rpx;
|
||||||
|
|||||||
72
pages/my-index/components/card-input.vue
Normal file
72
pages/my-index/components/card-input.vue
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<script setup>
|
||||||
|
const name = defineModel({
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
/**
|
||||||
|
* 输入框状态类型
|
||||||
|
* text: 文本
|
||||||
|
* password: 密码
|
||||||
|
* number: 数字
|
||||||
|
* tel: 手机号
|
||||||
|
* email: 邮箱
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'text'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '标题'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '请输入'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const placeholderStyle = `font-family: PingFang SC, PingFang SC; font-weight: 500; color: #D9D9D9; font-size: 28rpx; font-style: normal; text-transform: none;`
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="card-input">
|
||||||
|
<text class="title">{{ props.title }}</text>
|
||||||
|
<input
|
||||||
|
v-model="name"
|
||||||
|
:type="props.type"
|
||||||
|
:placeholder-style="placeholderStyle"
|
||||||
|
:placeholder="props.placeholder"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card-input + .card-input {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
.card-input {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.title {
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
text-align: left;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
width: 340rpx;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,8 +1,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { useAuthUser } from '@/composables/useAuthUser'
|
import { useAuthUser } from '@/composables/useAuthUser'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { navigateTo } from '@/utils/router'
|
||||||
|
|
||||||
const bottomList = [
|
const bottomList = [
|
||||||
{ name: '我的钱包', icon: 'wallet' },
|
{
|
||||||
|
name: '我的钱包',
|
||||||
|
icon: 'wallet',
|
||||||
|
url: '/pages/my-index/wallet/index'
|
||||||
|
},
|
||||||
{ name: '我的团队', icon: 'team' },
|
{ name: '我的团队', icon: 'team' },
|
||||||
{ name: '会议记录', icon: 'meeting' },
|
{ name: '会议记录', icon: 'meeting' },
|
||||||
{ name: '我的朋友圈', icon: 'circle' },
|
{ name: '我的朋友圈', icon: 'circle' },
|
||||||
@@ -11,11 +17,19 @@
|
|||||||
{ name: '系统设置', icon: 'system' }
|
{ name: '系统设置', icon: 'system' }
|
||||||
]
|
]
|
||||||
const { userInfo } = useAuthUser()
|
const { userInfo } = useAuthUser()
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
// 获取用户信息
|
||||||
|
console.log(userInfo.value, '===获取用户信息')
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="my-index">
|
<view class="my-index">
|
||||||
<view class="top-info">
|
<view
|
||||||
|
class="top-info"
|
||||||
|
@click="navigateTo('/pages/my-index/personal-center/index')"
|
||||||
|
>
|
||||||
<view class="left-box">
|
<view class="left-box">
|
||||||
<image
|
<image
|
||||||
src="https://wx1.sinaimg.cn/mw690/92eeb099gy1i29hl0ne80j21jk2bcash.jpg"
|
src="https://wx1.sinaimg.cn/mw690/92eeb099gy1i29hl0ne80j21jk2bcash.jpg"
|
||||||
@@ -38,7 +52,7 @@
|
|||||||
<view class="top-box">
|
<view class="top-box">
|
||||||
<view class="left-name">
|
<view class="left-name">
|
||||||
<text>账户积分</text>
|
<text>账户积分</text>
|
||||||
<text>2933</text>
|
<text>{{ userInfo?.totalPoints }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="right-btn">
|
<view class="right-btn">
|
||||||
<button>充值</button>
|
<button>充值</button>
|
||||||
@@ -50,6 +64,7 @@
|
|||||||
v-for="(item, index) in bottomList"
|
v-for="(item, index) in bottomList"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="item-box"
|
class="item-box"
|
||||||
|
@click="item.url && navigateTo(item.url)"
|
||||||
>
|
>
|
||||||
<view class="item-name">
|
<view class="item-name">
|
||||||
<image
|
<image
|
||||||
@@ -82,7 +97,6 @@
|
|||||||
.top-info {
|
.top-info {
|
||||||
padding: 32rpx 46rpx;
|
padding: 32rpx 46rpx;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
height: 192rpx;
|
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
58
pages/my-index/personal-center/index.vue
Normal file
58
pages/my-index/personal-center/index.vue
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<script setup>
|
||||||
|
import { useAuthUser } from '@/composables/useAuthUser'
|
||||||
|
|
||||||
|
const itemList = [
|
||||||
|
{ title: '我的二维码', key: '1', value: '' },
|
||||||
|
{ title: 'ID', key: '2', value: 'userId' },
|
||||||
|
{ title: '昵称', key: '3', value: 'userName' },
|
||||||
|
{ title: '性别', key: '4', value: '' },
|
||||||
|
{ title: '手机号码', key: '5', value: 'mobile' },
|
||||||
|
{ title: '个性签名', key: '6', value: '' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const { userInfo } = useAuthUser()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="personal-center">
|
||||||
|
<view class="public-card">
|
||||||
|
<view class="left-img">
|
||||||
|
<image
|
||||||
|
src="https://p4.itc.cn/images01/20220619/46660ed163164c14be90e605a73ee5e8.jpeg"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="avatar"
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<view class="right-box">
|
||||||
|
<text class="value">换头像</text>
|
||||||
|
<uni-icons type="right" size="16" color="#999999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in itemList"
|
||||||
|
:key="index"
|
||||||
|
class="public-card"
|
||||||
|
>
|
||||||
|
<view class="left-box">
|
||||||
|
<text>{{ item.title }}</text>
|
||||||
|
<text v-if="item.key === '6'" class="text">
|
||||||
|
这个人很懒,什么也没有
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view class="right-box">
|
||||||
|
<text v-if="!['1', '6'].includes(item.key)" class="value">
|
||||||
|
{{ item.value ? userInfo[item.value] : '' }}
|
||||||
|
</text>
|
||||||
|
<uni-icons type="right" size="16" color="#999999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../styles/index.scss';
|
||||||
|
.personal-center {
|
||||||
|
padding: 32rpx 24rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
70
pages/my-index/styles/index.scss
Normal file
70
pages/my-index/styles/index.scss
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
page {
|
||||||
|
background: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-card + .public-card {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 20rpx 32rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
|
||||||
|
.left-box,
|
||||||
|
.left-img,
|
||||||
|
.right-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.left-img {
|
||||||
|
.avatar {
|
||||||
|
width: 96rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
border-radius: 96rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
text {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
width: 70%;
|
||||||
|
text {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-box {
|
||||||
|
align-items: flex-end;
|
||||||
|
.value {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
pages/my-index/wallet/bank-card/card-details.vue
Normal file
63
pages/my-index/wallet/bank-card/card-details.vue
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
import CardInput from '../../components/card-input.vue'
|
||||||
|
|
||||||
|
const stateData = reactive({
|
||||||
|
title: '',
|
||||||
|
state: '0'
|
||||||
|
})
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
// 银行卡名称
|
||||||
|
name: '',
|
||||||
|
// 开户行名称
|
||||||
|
khName: '',
|
||||||
|
// 银行卡号
|
||||||
|
cardNum: '',
|
||||||
|
// 微信/支付宝号
|
||||||
|
codeName: '',
|
||||||
|
// 图片链接
|
||||||
|
img: ''
|
||||||
|
})
|
||||||
|
onLoad(e => {
|
||||||
|
const titltData = {
|
||||||
|
0: '添加银行卡',
|
||||||
|
101: '添加支付宝账户',
|
||||||
|
102: '添加微信账户'
|
||||||
|
}[e.key]
|
||||||
|
stateData.title = titltData
|
||||||
|
stateData.state = e.key
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<nav-bar isTopBg isPlaceholder :title="stateData.title"></nav-bar>
|
||||||
|
|
||||||
|
<view
|
||||||
|
v-if="!['101', '102'].includes(stateData.state)"
|
||||||
|
class="card-details"
|
||||||
|
>
|
||||||
|
<CardInput v-model="formData.name" title="银行名称"></CardInput>
|
||||||
|
<CardInput v-model="formData.khName" title="开户行"></CardInput>
|
||||||
|
<CardInput v-model="formData.cardNum" title="银行卡号"></CardInput>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else class="card-details">
|
||||||
|
<CardInput
|
||||||
|
v-model="formData.codeName"
|
||||||
|
:title="`${
|
||||||
|
stateData.state === '101' ? '支付宝账号' : '微信账号'
|
||||||
|
}`"
|
||||||
|
></CardInput>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../styles/index.scss';
|
||||||
|
.card-details {
|
||||||
|
padding: 32rpx 24rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
56
pages/my-index/wallet/bank-card/index.vue
Normal file
56
pages/my-index/wallet/bank-card/index.vue
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { navigateTo } from '@/utils/router'
|
||||||
|
|
||||||
|
const itemList = ref([
|
||||||
|
{
|
||||||
|
title: '支付宝',
|
||||||
|
key: '101',
|
||||||
|
icon: '/static/images/my-index/zfb.png'
|
||||||
|
},
|
||||||
|
{ title: '微信', key: '102', icon: '/static/images/my-index/wx.png' }
|
||||||
|
])
|
||||||
|
|
||||||
|
const onAddCard = key => {
|
||||||
|
navigateTo('/pages/my-index/wallet/bank-card/card-details', { key })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="bank-card">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in itemList"
|
||||||
|
:key="index"
|
||||||
|
class="public-card"
|
||||||
|
@click="onAddCard(item.key)"
|
||||||
|
>
|
||||||
|
<view class="left-img">
|
||||||
|
<image
|
||||||
|
:src="
|
||||||
|
item.icon
|
||||||
|
? item.icon
|
||||||
|
: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2024%2F1227%2F842e0e65j00sp543n001fd000i700iim.jpg&thumbnail=660x2147483647&quality=80&type=jpg'
|
||||||
|
"
|
||||||
|
mode="aspectFill"
|
||||||
|
class="card"
|
||||||
|
></image>
|
||||||
|
<text>{{ item.title }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="right-box">
|
||||||
|
<uni-icons type="right" size="16" color="#999999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<bottom-view>
|
||||||
|
<cb-button @click="onAddCard('0')">+添加银行卡</cb-button>
|
||||||
|
</bottom-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../styles/index.scss';
|
||||||
|
.bank-card {
|
||||||
|
padding: 38rpx 24rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
101
pages/my-index/wallet/edit-password.vue
Normal file
101
pages/my-index/wallet/edit-password.vue
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<script setup>
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
import CardInput from '../components/card-input.vue'
|
||||||
|
import { useUI } from '@/utils/use-ui'
|
||||||
|
import { validateTransactionPassword } from '@/utils/validate'
|
||||||
|
|
||||||
|
const { showToast } = useUI()
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
// 旧密码
|
||||||
|
password: '',
|
||||||
|
// 新密码
|
||||||
|
newPassword: '',
|
||||||
|
// 确认密码
|
||||||
|
confirmPassword: ''
|
||||||
|
})
|
||||||
|
const onEdit = () => {
|
||||||
|
const passwordValue = validateTransactionPassword(
|
||||||
|
formData.password,
|
||||||
|
'旧密码'
|
||||||
|
)
|
||||||
|
if (!passwordValue.valid) {
|
||||||
|
showToast(passwordValue.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const newPasswordValue = validateTransactionPassword(
|
||||||
|
formData.newPassword,
|
||||||
|
'新的交易密码'
|
||||||
|
)
|
||||||
|
if (!newPasswordValue.valid) {
|
||||||
|
showToast(newPasswordValue.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmPasswordValue = validateTransactionPassword(
|
||||||
|
formData.confirmPassword,
|
||||||
|
'确认交易密码'
|
||||||
|
)
|
||||||
|
if (!confirmPasswordValue.valid) {
|
||||||
|
showToast(confirmPasswordValue.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.newPassword !== formData.confirmPassword) {
|
||||||
|
showToast('两次密码不一致')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('修改密码:', formData)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="edit-password">
|
||||||
|
<nav-bar isTopBg isPlaceholder title="交易密码">
|
||||||
|
<template #right>
|
||||||
|
<text class="top-right-name" @click="onEdit">确认</text>
|
||||||
|
</template>
|
||||||
|
</nav-bar>
|
||||||
|
|
||||||
|
<view class="input-box">
|
||||||
|
<CardInput
|
||||||
|
v-model="formData.password"
|
||||||
|
title="旧密码"
|
||||||
|
type="password"
|
||||||
|
></CardInput>
|
||||||
|
<CardInput
|
||||||
|
v-model="formData.newPassword"
|
||||||
|
title="设置新的交易密码"
|
||||||
|
type="password"
|
||||||
|
></CardInput>
|
||||||
|
<CardInput
|
||||||
|
v-model="formData.confirmPassword"
|
||||||
|
title="重复新的交易密码"
|
||||||
|
type="password"
|
||||||
|
></CardInput>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../styles/index.scss';
|
||||||
|
|
||||||
|
.top-right-name {
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
background: #00d993;
|
||||||
|
padding: 6rpx 20rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-box {
|
||||||
|
padding: 32rpx 24rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
125
pages/my-index/wallet/index.vue
Normal file
125
pages/my-index/wallet/index.vue
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<script setup>
|
||||||
|
import { navigateTo } from '@/utils/router'
|
||||||
|
|
||||||
|
const itemList = [
|
||||||
|
{
|
||||||
|
title: '提现卡',
|
||||||
|
key: '1',
|
||||||
|
url: '/pages/my-index/wallet/bank-card/index'
|
||||||
|
},
|
||||||
|
{ title: '交易记录', key: '2', url: '' },
|
||||||
|
{
|
||||||
|
title: '修改支付密码',
|
||||||
|
key: '3',
|
||||||
|
url: '/pages/my-index/wallet/edit-password'
|
||||||
|
},
|
||||||
|
{ title: '实名认证', key: '4', url: '' }
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="wallet">
|
||||||
|
<!-- 顶部样式 -->
|
||||||
|
<view class="top-card">
|
||||||
|
<view class="left-box">
|
||||||
|
<text>我的资产</text>
|
||||||
|
<text>2222</text>
|
||||||
|
</view>
|
||||||
|
<view class="right-box">
|
||||||
|
<button>充值</button>
|
||||||
|
<button>提现</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in itemList"
|
||||||
|
:key="index"
|
||||||
|
class="public-card"
|
||||||
|
@click="item.url && navigateTo(item.url)"
|
||||||
|
>
|
||||||
|
<view class="left-box">
|
||||||
|
<text>{{ item.title }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="right-box">
|
||||||
|
<uni-icons type="right" size="16" color="#999999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../styles/index.scss';
|
||||||
|
.wallet {
|
||||||
|
padding: 32rpx 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-card {
|
||||||
|
padding: 36rpx;
|
||||||
|
margin-bottom: 48rpx;
|
||||||
|
background: #ff4c54;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
&::after {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
right: 54rpx;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
background: url('/static/images/my-index/wallet-bg.png');
|
||||||
|
background-size: 30%;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.left-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
&:last-child {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 64rpx;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
button {
|
||||||
|
width: 128rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
border-radius: 100rpx 100rpx 100rpx 100rpx;
|
||||||
|
font-family: PingFang SC, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
font-style: normal;
|
||||||
|
text-transform: none;
|
||||||
|
background: transparent;
|
||||||
|
border: 2rpx solid #ffffff;
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
margin-left: 16rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #eb1c26;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
static/images/discover/bean.png
Normal file
BIN
static/images/discover/bean.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
static/images/discover/calendar.png
Normal file
BIN
static/images/discover/calendar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
BIN
static/images/my-index/wallet-bg.png
Normal file
BIN
static/images/my-index/wallet-bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
static/images/my-index/wx.png
Normal file
BIN
static/images/my-index/wx.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/images/my-index/zfb.png
Normal file
BIN
static/images/my-index/zfb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
102
uni_modules/uni-popup/changelog.md
Normal file
102
uni_modules/uni-popup/changelog.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
## 1.9.11(2025-08-20)
|
||||||
|
- 修复 uni-popup-dialog组件设置 borderRadius 不生效的 Bug
|
||||||
|
## 1.9.10(2025-07-18)
|
||||||
|
- 修复 nvue 下弹窗样式错乱的问题 ,更新依赖 uni-transition 组件
|
||||||
|
- 更新 示例取消 borderRadius 属性 ,如需内容圆角,用户应该直接在内容插槽中实现
|
||||||
|
## 1.9.9(2025-06-11)
|
||||||
|
- 修复 uni-popup-dialog 中 setVal 方法报错的问题
|
||||||
|
- 修复 uni-popup-dialog 数据双向绑定问题。
|
||||||
|
## 1.9.8(2025-04-16)
|
||||||
|
- 修复 更新组件示例 ,解决更新数据或保存项目导致弹窗消失的问题
|
||||||
|
## 1.9.7(2025-04-14)
|
||||||
|
- 修复 uni-popup-dialog 弹出框在vue3中双向绑定问题
|
||||||
|
## 1.9.6(2025-01-08)
|
||||||
|
- 修复 示例中过期图片地址
|
||||||
|
## 1.9.5(2024-10-15)
|
||||||
|
- 修复 微信小程序中的getSystemInfo警告
|
||||||
|
## 1.9.2(2024-09-21)
|
||||||
|
- 修复 uni-popup在android上的重复点击弹出位置不正确的bug
|
||||||
|
## 1.9.1(2024-04-02)
|
||||||
|
- 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
|
||||||
|
## 1.9.0(2024-03-28)
|
||||||
|
- 修复 uni-popup-dialog 双向绑定时初始化逻辑修正
|
||||||
|
## 1.8.9(2024-03-20)
|
||||||
|
- 修复 uni-popup-dialog 数据输入时修正为双向绑定
|
||||||
|
## 1.8.8(2024-02-20)
|
||||||
|
- 修复 uni-popup 在微信小程序下出现文字向上闪动的bug
|
||||||
|
## 1.8.7(2024-02-02)
|
||||||
|
- 新增 uni-popup-dialog 新增属性focus:input模式下,是否自动自动聚焦
|
||||||
|
## 1.8.6(2024-01-30)
|
||||||
|
- 新增 uni-popup-dialog 新增属性maxLength:限制输入框字数
|
||||||
|
## 1.8.5(2024-01-26)
|
||||||
|
- 新增 uni-popup-dialog 新增属性showClose:控制关闭按钮的显示
|
||||||
|
## 1.8.4(2023-11-15)
|
||||||
|
- 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close`
|
||||||
|
## 1.8.3(2023-04-17)
|
||||||
|
- 修复 uni-popup 重复打开时的 bug
|
||||||
|
## 1.8.2(2023-02-02)
|
||||||
|
- uni-popup-dialog 组件新增 inputType 属性
|
||||||
|
## 1.8.1(2022-12-01)
|
||||||
|
- 修复 nvue 下 v-show 报错
|
||||||
|
## 1.8.0(2022-11-29)
|
||||||
|
- 优化 主题样式
|
||||||
|
## 1.7.9(2022-04-02)
|
||||||
|
- 修复 弹出层内部无法滚动的bug
|
||||||
|
## 1.7.8(2022-03-28)
|
||||||
|
- 修复 小程序中高度错误的bug
|
||||||
|
## 1.7.7(2022-03-17)
|
||||||
|
- 修复 快速调用open出现问题的Bug
|
||||||
|
## 1.7.6(2022-02-14)
|
||||||
|
- 修复 safeArea 属性不能设置为false的bug
|
||||||
|
## 1.7.5(2022-01-19)
|
||||||
|
- 修复 isMaskClick 失效的bug
|
||||||
|
## 1.7.4(2022-01-19)
|
||||||
|
- 新增 cancelText \ confirmText 属性 ,可自定义文本
|
||||||
|
- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
|
||||||
|
- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
|
||||||
|
## 1.7.3(2022-01-13)
|
||||||
|
- 修复 设置 safeArea 属性不生效的bug
|
||||||
|
## 1.7.2(2021-11-26)
|
||||||
|
- 优化 组件示例
|
||||||
|
## 1.7.1(2021-11-26)
|
||||||
|
- 修复 vuedoc 文字错误
|
||||||
|
## 1.7.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
|
||||||
|
## 1.6.2(2021-08-24)
|
||||||
|
- 新增 支持国际化
|
||||||
|
## 1.6.1(2021-07-30)
|
||||||
|
- 优化 vue3下事件警告的问题
|
||||||
|
## 1.6.0(2021-07-13)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.5.0(2021-06-23)
|
||||||
|
- 新增 mask-click 遮罩层点击事件
|
||||||
|
## 1.4.5(2021-06-22)
|
||||||
|
- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
|
||||||
|
## 1.4.4(2021-06-18)
|
||||||
|
- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
|
||||||
|
## 1.4.3(2021-06-08)
|
||||||
|
- 修复 错误的 watch 字段
|
||||||
|
- 修复 safeArea 属性不生效的问题
|
||||||
|
- 修复 点击内容,再点击遮罩无法关闭的Bug
|
||||||
|
## 1.4.2(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 1.4.1(2021-04-29)
|
||||||
|
- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
|
||||||
|
## 1.4.0 (2021-04-29)
|
||||||
|
- 新增 type 属性的 left\right 值,支持左右弹出
|
||||||
|
- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
|
||||||
|
- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
|
||||||
|
- 新增 safeArea 属性,是否适配底部安全区
|
||||||
|
- 修复 App\h5\微信小程序底部安全区占位不对的Bug
|
||||||
|
- 修复 App 端弹出等待的Bug
|
||||||
|
- 优化 提升低配设备性能,优化动画卡顿问题
|
||||||
|
- 优化 更简单的组件自定义方式
|
||||||
|
## 1.2.9(2021-02-05)
|
||||||
|
- 优化 组件引用关系,通过uni_modules引用组件
|
||||||
|
## 1.2.8(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
## 1.2.7(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
- 新增 支持 PC 端
|
||||||
|
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// #ifdef H5
|
||||||
|
export default {
|
||||||
|
name: 'Keypress',
|
||||||
|
props: {
|
||||||
|
disable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const keyNames = {
|
||||||
|
esc: ['Esc', 'Escape'],
|
||||||
|
tab: 'Tab',
|
||||||
|
enter: 'Enter',
|
||||||
|
space: [' ', 'Spacebar'],
|
||||||
|
up: ['Up', 'ArrowUp'],
|
||||||
|
left: ['Left', 'ArrowLeft'],
|
||||||
|
right: ['Right', 'ArrowRight'],
|
||||||
|
down: ['Down', 'ArrowDown'],
|
||||||
|
delete: ['Backspace', 'Delete', 'Del']
|
||||||
|
}
|
||||||
|
const listener = ($event) => {
|
||||||
|
if (this.disable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const keyName = Object.keys(keyNames).find(key => {
|
||||||
|
const keyName = $event.key
|
||||||
|
const value = keyNames[key]
|
||||||
|
return value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||||
|
})
|
||||||
|
if (keyName) {
|
||||||
|
// 避免和其他按键事件冲突
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit(keyName, {})
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('keyup', listener)
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
document.removeEventListener('keyup', listener)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
render: () => {}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
@@ -0,0 +1,330 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-popup-dialog" :style="{ borderRadius }">
|
||||||
|
<view class="uni-dialog-title">
|
||||||
|
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="mode === 'base'" class="uni-dialog-content">
|
||||||
|
<slot>
|
||||||
|
<text class="uni-dialog-content-text">{{content}}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view v-else class="uni-dialog-content">
|
||||||
|
<slot>
|
||||||
|
<input class="uni-dialog-input" :maxlength="maxlength" v-model="val" :type="inputType"
|
||||||
|
:placeholder="placeholderText" :focus="focus">
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view class="uni-dialog-button-group">
|
||||||
|
<view class="uni-dialog-button" v-if="showClose" @click="closeDialog">
|
||||||
|
<text class="uni-dialog-button-text">{{closeText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-dialog-button" :class="showClose?'uni-border-left':''" @click="onOk">
|
||||||
|
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import popup from '../uni-popup/popup.js'
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from '../uni-popup/i18n/index.js'
|
||||||
|
const {
|
||||||
|
t
|
||||||
|
} = initVueI18n(messages)
|
||||||
|
/**
|
||||||
|
* PopUp 弹出层-对话框样式
|
||||||
|
* @description 弹出层-对话框样式
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||||
|
* @property {String} value input 模式下的默认值
|
||||||
|
* @property {String} placeholder input 模式下输入提示
|
||||||
|
* @property {Boolean} focus input模式下是否自动聚焦,默认为true
|
||||||
|
* @property {String} type = [success|warning|info|error] 主题样式
|
||||||
|
* @value success 成功
|
||||||
|
* @value warning 提示
|
||||||
|
* @value info 消息
|
||||||
|
* @value error 错误
|
||||||
|
* @property {String} mode = [base|input] 模式、
|
||||||
|
* @value base 基础对话框
|
||||||
|
* @value input 可输入对话框
|
||||||
|
* @showClose {Boolean} 是否显示关闭按钮
|
||||||
|
* @property {String} content 对话框内容
|
||||||
|
* @property {Boolean} beforeClose 是否拦截取消事件
|
||||||
|
* @property {Number} maxlength 输入
|
||||||
|
* @event {Function} confirm 点击确认按钮触发
|
||||||
|
* @event {Function} close 点击取消按钮触发
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "uniPopupDialog",
|
||||||
|
mixins: [popup],
|
||||||
|
emits: ['confirm', 'close', 'update:modelValue', 'input'],
|
||||||
|
props: {
|
||||||
|
inputType: {
|
||||||
|
type: String,
|
||||||
|
default: 'text'
|
||||||
|
},
|
||||||
|
showClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// #ifdef VUE2
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
|
||||||
|
placeholder: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'error'
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'base'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
beforeClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
confirmText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
maxlength: {
|
||||||
|
type: Number,
|
||||||
|
default: -1,
|
||||||
|
},
|
||||||
|
focus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
type: String,
|
||||||
|
default: '11px',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogType: 'error',
|
||||||
|
val: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
okText() {
|
||||||
|
return this.confirmText || t("uni-popup.ok")
|
||||||
|
},
|
||||||
|
closeText() {
|
||||||
|
return this.cancelText || t("uni-popup.cancel")
|
||||||
|
},
|
||||||
|
placeholderText() {
|
||||||
|
return this.placeholder || t("uni-popup.placeholder")
|
||||||
|
},
|
||||||
|
titleText() {
|
||||||
|
return this.title || t("uni-popup.title")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
type(val) {
|
||||||
|
this.dialogType = val
|
||||||
|
},
|
||||||
|
mode(val) {
|
||||||
|
if (val === 'input') {
|
||||||
|
this.dialogType = 'info'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value(val) {
|
||||||
|
this.setVal(val)
|
||||||
|
},
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue(val) {
|
||||||
|
this.setVal(val)
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
val(val) {
|
||||||
|
// #ifdef VUE2
|
||||||
|
// TODO 兼容 vue2
|
||||||
|
this.$emit('input', val);
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
// TODO 兼容 vue3
|
||||||
|
this.$emit('update:modelValue', val);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 对话框遮罩不可点击
|
||||||
|
this.popup.disableMask()
|
||||||
|
// this.popup.closeMask()
|
||||||
|
if (this.mode === 'input') {
|
||||||
|
this.dialogType = 'info'
|
||||||
|
this.val = this.value;
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.val = this.modelValue;
|
||||||
|
// #endif
|
||||||
|
} else {
|
||||||
|
this.dialogType = this.type
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 给val属性赋值
|
||||||
|
*/
|
||||||
|
setVal(val) {
|
||||||
|
if (this.maxlength != -1 && this.mode === 'input') {
|
||||||
|
this.val = val.slice(0, this.maxlength);
|
||||||
|
} else {
|
||||||
|
this.val = val
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 点击确认按钮
|
||||||
|
*/
|
||||||
|
onOk() {
|
||||||
|
if (this.mode === 'input') {
|
||||||
|
this.$emit('confirm', this.val)
|
||||||
|
} else {
|
||||||
|
this.$emit('confirm')
|
||||||
|
}
|
||||||
|
if (this.beforeClose) return
|
||||||
|
this.popup.close()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 点击取消按钮
|
||||||
|
*/
|
||||||
|
closeDialog() {
|
||||||
|
this.$emit('close')
|
||||||
|
if (this.beforeClose) return
|
||||||
|
this.popup.close()
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.uni-popup-dialog {
|
||||||
|
width: 300px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-title {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-title-text {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-content {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-content-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6C6C6C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-button-group {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
border-top-color: #f5f5f5;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-button {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-border-left {
|
||||||
|
border-left-color: #f0f0f0;
|
||||||
|
border-left-style: solid;
|
||||||
|
border-left-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-button-text {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-button-color {
|
||||||
|
color: #007aff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dialog-input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
border: 1px #eee solid;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__success {
|
||||||
|
color: #4cd964;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__warn {
|
||||||
|
color: #f0ad4e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__error {
|
||||||
|
color: #dd524d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__info {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-popup-message">
|
||||||
|
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
|
||||||
|
<slot>
|
||||||
|
<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import popup from '../uni-popup/popup.js'
|
||||||
|
/**
|
||||||
|
* PopUp 弹出层-消息提示
|
||||||
|
* @description 弹出层-消息提示
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||||
|
* @property {String} type = [success|warning|info|error] 主题样式
|
||||||
|
* @value success 成功
|
||||||
|
* @value warning 提示
|
||||||
|
* @value info 消息
|
||||||
|
* @value error 错误
|
||||||
|
* @property {String} message 消息提示文字
|
||||||
|
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'uniPopupMessage',
|
||||||
|
mixins:[popup],
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 主题 success/warning/info/error 默认 success
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'success'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 消息文字
|
||||||
|
*/
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 显示时间,设置为 0 则不会自动关闭
|
||||||
|
*/
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 3000
|
||||||
|
},
|
||||||
|
maskShow:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.popup.maskShow = this.maskShow
|
||||||
|
this.popup.messageChild = this
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
timerClose(){
|
||||||
|
if(this.duration === 0) return
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = setTimeout(()=>{
|
||||||
|
this.popup.close()
|
||||||
|
},this.duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" >
|
||||||
|
.uni-popup-message {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup-message__box {
|
||||||
|
background-color: #e1f3d8;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-color: #eee;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 500px) {
|
||||||
|
.fixforpc-width {
|
||||||
|
margin-top: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
flex: none;
|
||||||
|
min-width: 380px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
max-width: 50%;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
max-width: 500px;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup-message-text {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__success {
|
||||||
|
background-color: #e1f3d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__success-text {
|
||||||
|
color: #67C23A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__warn {
|
||||||
|
background-color: #faecd8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__warn-text {
|
||||||
|
color: #E6A23C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__error {
|
||||||
|
background-color: #fde2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__error-text {
|
||||||
|
color: #F56C6C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__info {
|
||||||
|
background-color: #F2F6FC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__info-text {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-popup-share">
|
||||||
|
<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
|
||||||
|
<view class="uni-share-content">
|
||||||
|
<view class="uni-share-content-box">
|
||||||
|
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
|
||||||
|
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
|
||||||
|
<text class="uni-share-text">{{item.text}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="uni-share-button-box">
|
||||||
|
<button class="uni-share-button" @click="close">{{cancelText}}</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import popup from '../uni-popup/popup.js'
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from '../uni-popup/i18n/index.js'
|
||||||
|
const { t } = initVueI18n(messages)
|
||||||
|
export default {
|
||||||
|
name: 'UniPopupShare',
|
||||||
|
mixins:[popup],
|
||||||
|
emits:['select'],
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
beforeClose: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// TODO 替换为自己的图标
|
||||||
|
bottomData: [{
|
||||||
|
text: '微信',
|
||||||
|
icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
|
||||||
|
name: 'wx'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '支付宝',
|
||||||
|
icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
|
||||||
|
name: 'ali'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'QQ',
|
||||||
|
icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
|
||||||
|
name: 'qq'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '新浪',
|
||||||
|
icon: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
|
||||||
|
name: 'sina'
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// text: '百度',
|
||||||
|
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
|
||||||
|
// name: 'copy'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// text: '其他',
|
||||||
|
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
|
||||||
|
// name: 'more'
|
||||||
|
// }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
computed: {
|
||||||
|
cancelText() {
|
||||||
|
return t("uni-popup.cancel")
|
||||||
|
},
|
||||||
|
shareTitleText() {
|
||||||
|
return this.title || t("uni-popup.shareTitle")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 选择内容
|
||||||
|
*/
|
||||||
|
select(item, index) {
|
||||||
|
this.$emit('select', {
|
||||||
|
item,
|
||||||
|
index
|
||||||
|
})
|
||||||
|
this.close()
|
||||||
|
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 关闭窗口
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
if(this.beforeClose) return
|
||||||
|
this.popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" >
|
||||||
|
.uni-popup-share {
|
||||||
|
background-color: #fff;
|
||||||
|
border-top-left-radius: 11px;
|
||||||
|
border-top-right-radius: 11px;
|
||||||
|
}
|
||||||
|
.uni-share-title {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.uni-share-title-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.uni-share-content {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-item {
|
||||||
|
width: 90px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-content-item:active {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-image {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-text {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #3B4144;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-button-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 10px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-button {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 50px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-share-button::after {
|
||||||
|
border-radius: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
7
uni_modules/uni-popup/components/uni-popup/i18n/en.json
Normal file
7
uni_modules/uni-popup/components/uni-popup/i18n/en.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"uni-popup.cancel": "cancel",
|
||||||
|
"uni-popup.ok": "ok",
|
||||||
|
"uni-popup.placeholder": "pleace enter",
|
||||||
|
"uni-popup.title": "Hint",
|
||||||
|
"uni-popup.shareTitle": "Share to"
|
||||||
|
}
|
||||||
8
uni_modules/uni-popup/components/uni-popup/i18n/index.js
Normal file
8
uni_modules/uni-popup/components/uni-popup/i18n/index.js
Normal file
@@ -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,7 @@
|
|||||||
|
{
|
||||||
|
"uni-popup.cancel": "取消",
|
||||||
|
"uni-popup.ok": "确定",
|
||||||
|
"uni-popup.placeholder": "请输入",
|
||||||
|
"uni-popup.title": "提示",
|
||||||
|
"uni-popup.shareTitle": "分享到"
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"uni-popup.cancel": "取消",
|
||||||
|
"uni-popup.ok": "確定",
|
||||||
|
"uni-popup.placeholder": "請輸入",
|
||||||
|
"uni-popup.title": "提示",
|
||||||
|
"uni-popup.shareTitle": "分享到"
|
||||||
|
}
|
||||||
45
uni_modules/uni-popup/components/uni-popup/keypress.js
Normal file
45
uni_modules/uni-popup/components/uni-popup/keypress.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// #ifdef H5
|
||||||
|
export default {
|
||||||
|
name: 'Keypress',
|
||||||
|
props: {
|
||||||
|
disable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const keyNames = {
|
||||||
|
esc: ['Esc', 'Escape'],
|
||||||
|
tab: 'Tab',
|
||||||
|
enter: 'Enter',
|
||||||
|
space: [' ', 'Spacebar'],
|
||||||
|
up: ['Up', 'ArrowUp'],
|
||||||
|
left: ['Left', 'ArrowLeft'],
|
||||||
|
right: ['Right', 'ArrowRight'],
|
||||||
|
down: ['Down', 'ArrowDown'],
|
||||||
|
delete: ['Backspace', 'Delete', 'Del']
|
||||||
|
}
|
||||||
|
const listener = ($event) => {
|
||||||
|
if (this.disable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const keyName = Object.keys(keyNames).find(key => {
|
||||||
|
const keyName = $event.key
|
||||||
|
const value = keyNames[key]
|
||||||
|
return value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||||
|
})
|
||||||
|
if (keyName) {
|
||||||
|
// 避免和其他按键事件冲突
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit(keyName, {})
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('keyup', listener)
|
||||||
|
// this.$once('hook:beforeDestroy', () => {
|
||||||
|
// document.removeEventListener('keyup', listener)
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
render: () => {}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
26
uni_modules/uni-popup/components/uni-popup/popup.js
Normal file
26
uni_modules/uni-popup/components/uni-popup/popup.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.popup = this.getParent()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
/**
|
||||||
|
* 获取父元素实例
|
||||||
|
*/
|
||||||
|
getParent(name = 'uniPopup') {
|
||||||
|
let parent = this.$parent;
|
||||||
|
let parentName = parent.$options.name;
|
||||||
|
while (parentName !== name) {
|
||||||
|
parent = parent.$parent;
|
||||||
|
if (!parent) return false
|
||||||
|
parentName = parent.$options.name;
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
90
uni_modules/uni-popup/components/uni-popup/uni-popup.uvue
Normal file
90
uni_modules/uni-popup/components/uni-popup/uni-popup.uvue
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<view class="popup-root" v-if="isOpen" v-show="isShow" @click="clickMask">
|
||||||
|
<view @click.stop>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
type CloseCallBack = ()=> void;
|
||||||
|
let closeCallBack:CloseCallBack = () :void => {};
|
||||||
|
export default {
|
||||||
|
emits:["close","clickMask"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShow:false,
|
||||||
|
isOpen:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
maskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 设置show = true 时,如果没有 open 需要设置为 open
|
||||||
|
isShow:{
|
||||||
|
handler(isShow) {
|
||||||
|
// console.log("isShow",isShow)
|
||||||
|
if(isShow && this.isOpen == false){
|
||||||
|
this.isOpen = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate:true
|
||||||
|
},
|
||||||
|
// 设置isOpen = true 时,如果没有 isShow 需要设置为 isShow
|
||||||
|
isOpen:{
|
||||||
|
handler(isOpen) {
|
||||||
|
// console.log("isOpen",isOpen)
|
||||||
|
if(isOpen && this.isShow == false){
|
||||||
|
this.isShow = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate:true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
open(){
|
||||||
|
// ...funs : CloseCallBack[]
|
||||||
|
// if(funs.length > 0){
|
||||||
|
// closeCallBack = funs[0]
|
||||||
|
// }
|
||||||
|
this.isOpen = true;
|
||||||
|
},
|
||||||
|
clickMask(){
|
||||||
|
if(this.maskClick == true){
|
||||||
|
this.$emit('clickMask')
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close(): void{
|
||||||
|
this.isOpen = false;
|
||||||
|
this.$emit('close')
|
||||||
|
closeCallBack()
|
||||||
|
},
|
||||||
|
hiden(){
|
||||||
|
this.isShow = false
|
||||||
|
},
|
||||||
|
show(){
|
||||||
|
this.isShow = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.popup-root {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 750rpx;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
518
uni_modules/uni-popup/components/uni-popup/uni-popup.vue
Normal file
518
uni_modules/uni-popup/components/uni-popup/uni-popup.vue
Normal file
@@ -0,0 +1,518 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']">
|
||||||
|
<view @touchstart="touchstart">
|
||||||
|
<uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
|
||||||
|
:duration="duration" :show="showTrans" @click="onTap" />
|
||||||
|
<uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
|
||||||
|
:show="showTrans" @click="onTap">
|
||||||
|
<view class="uni-popup__wrapper" :style="getStyles" :class="[popupstyle]" @click="clear">
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</uni-transition>
|
||||||
|
</view>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<keypress v-if="maskShow" @esc="onTap" />
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef H5
|
||||||
|
import keypress from './keypress.js'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PopUp 弹出层
|
||||||
|
* @description 弹出层组件,为了解决遮罩弹层的问题
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
|
||||||
|
* @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
|
||||||
|
* @value top 顶部弹出
|
||||||
|
* @value center 中间弹出
|
||||||
|
* @value bottom 底部弹出
|
||||||
|
* @value left 左侧弹出
|
||||||
|
* @value right 右侧弹出
|
||||||
|
* @value message 消息提示
|
||||||
|
* @value dialog 对话框
|
||||||
|
* @value share 底部分享示例
|
||||||
|
* @property {Boolean} animation = [true|false] 是否开启动画
|
||||||
|
* @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
|
||||||
|
* @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
|
||||||
|
* @property {String} backgroundColor 主窗口背景色
|
||||||
|
* @property {String} maskBackgroundColor 蒙版颜色
|
||||||
|
* @property {String} borderRadius 设置圆角(左上、右上、右下和左下) 示例:"10px 10px 10px 10px"
|
||||||
|
* @property {Boolean} safeArea 是否适配底部安全区
|
||||||
|
* @event {Function} change 打开关闭弹窗触发,e={show: false}
|
||||||
|
* @event {Function} maskClick 点击遮罩触发
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'uniPopup',
|
||||||
|
components: {
|
||||||
|
// #ifdef H5
|
||||||
|
keypress
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
emits: ['change', 'maskClick'],
|
||||||
|
props: {
|
||||||
|
// 开启动画
|
||||||
|
animation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||||
|
// message: 消息提示 ; dialog : 对话框
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'center'
|
||||||
|
},
|
||||||
|
// maskClick
|
||||||
|
isMaskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// TODO 2 个版本后废弃属性 ,使用 isMaskClick
|
||||||
|
maskClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
backgroundColor: {
|
||||||
|
type: String,
|
||||||
|
default: 'none'
|
||||||
|
},
|
||||||
|
safeArea: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
maskBackgroundColor: {
|
||||||
|
type: String,
|
||||||
|
default: 'rgba(0, 0, 0, 0.4)'
|
||||||
|
},
|
||||||
|
borderRadius:{
|
||||||
|
type: String,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
/**
|
||||||
|
* 监听type类型
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
handler: function(type) {
|
||||||
|
if (!this.config[type]) return
|
||||||
|
this[this.config[type]](true)
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
isDesktop: {
|
||||||
|
handler: function(newVal) {
|
||||||
|
if (!this.config[newVal]) return
|
||||||
|
this[this.config[this.type]](true)
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 监听遮罩是否可点击
|
||||||
|
* @param {Object} val
|
||||||
|
*/
|
||||||
|
maskClick: {
|
||||||
|
handler: function(val) {
|
||||||
|
this.mkclick = val
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
isMaskClick: {
|
||||||
|
handler: function(val) {
|
||||||
|
this.mkclick = val
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// H5 下禁止底部滚动
|
||||||
|
showPopup(show) {
|
||||||
|
// #ifdef H5
|
||||||
|
// fix by mehaotian 处理 h5 滚动穿透的问题
|
||||||
|
document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
duration: 300,
|
||||||
|
ani: [],
|
||||||
|
showPopup: false,
|
||||||
|
showTrans: false,
|
||||||
|
popupWidth: 0,
|
||||||
|
popupHeight: 0,
|
||||||
|
config: {
|
||||||
|
top: 'top',
|
||||||
|
bottom: 'bottom',
|
||||||
|
center: 'center',
|
||||||
|
left: 'left',
|
||||||
|
right: 'right',
|
||||||
|
message: 'top',
|
||||||
|
dialog: 'center',
|
||||||
|
share: 'bottom'
|
||||||
|
},
|
||||||
|
maskClass: {
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.4)'
|
||||||
|
},
|
||||||
|
transClass: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
borderRadius: this.borderRadius || "0",
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
right: 0
|
||||||
|
},
|
||||||
|
maskShow: true,
|
||||||
|
mkclick: true,
|
||||||
|
popupstyle: 'top'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
getStyles() {
|
||||||
|
let res = { backgroundColor: this.bg };
|
||||||
|
if (this.borderRadius || "0") {
|
||||||
|
res = Object.assign(res, { borderRadius: this.borderRadius })
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
isDesktop() {
|
||||||
|
return this.popupWidth >= 500 && this.popupHeight >= 500
|
||||||
|
},
|
||||||
|
bg() {
|
||||||
|
if (this.backgroundColor === '' || this.backgroundColor === 'none') {
|
||||||
|
return 'transparent'
|
||||||
|
}
|
||||||
|
return this.backgroundColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const fixSize = () => {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const {
|
||||||
|
windowWidth,
|
||||||
|
windowHeight,
|
||||||
|
windowTop,
|
||||||
|
safeArea,
|
||||||
|
screenHeight,
|
||||||
|
safeAreaInsets
|
||||||
|
} = uni.getWindowInfo()
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
const {
|
||||||
|
windowWidth,
|
||||||
|
windowHeight,
|
||||||
|
windowTop,
|
||||||
|
safeArea,
|
||||||
|
screenHeight,
|
||||||
|
safeAreaInsets
|
||||||
|
} = uni.getSystemInfoSync()
|
||||||
|
// #endif
|
||||||
|
this.popupWidth = windowWidth
|
||||||
|
this.popupHeight = windowHeight + (windowTop || 0)
|
||||||
|
// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
|
||||||
|
if (safeArea && this.safeArea) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.safeAreaInsets = screenHeight - safeArea.bottom
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
this.safeAreaInsets = safeAreaInsets.bottom
|
||||||
|
// #endif
|
||||||
|
} else {
|
||||||
|
this.safeAreaInsets = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixSize()
|
||||||
|
// #ifdef H5
|
||||||
|
// window.addEventListener('resize', fixSize)
|
||||||
|
// this.$once('hook:beforeDestroy', () => {
|
||||||
|
// window.removeEventListener('resize', fixSize)
|
||||||
|
// })
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// #ifndef VUE3
|
||||||
|
// TODO vue2
|
||||||
|
destroyed() {
|
||||||
|
this.setH5Visible()
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
// TODO vue3
|
||||||
|
unmounted() {
|
||||||
|
this.setH5Visible()
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
activated() {
|
||||||
|
this.setH5Visible(!this.showPopup);
|
||||||
|
},
|
||||||
|
deactivated() {
|
||||||
|
this.setH5Visible(true);
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// this.mkclick = this.isMaskClick || this.maskClick
|
||||||
|
if (this.isMaskClick === null && this.maskClick === null) {
|
||||||
|
this.mkclick = true
|
||||||
|
} else {
|
||||||
|
this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
|
||||||
|
}
|
||||||
|
if (this.animation) {
|
||||||
|
this.duration = 300
|
||||||
|
} else {
|
||||||
|
this.duration = 0
|
||||||
|
}
|
||||||
|
// TODO 处理 message 组件生命周期异常的问题
|
||||||
|
this.messageChild = null
|
||||||
|
// TODO 解决头条冒泡的问题
|
||||||
|
this.clearPropagation = false
|
||||||
|
this.maskClass.backgroundColor = this.maskBackgroundColor
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setH5Visible(visible = true) {
|
||||||
|
// #ifdef H5
|
||||||
|
// fix by mehaotian 处理 h5 滚动穿透的问题
|
||||||
|
document.getElementsByTagName('body')[0].style.overflow = visible ? "visible" : "hidden";
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 公用方法,不显示遮罩层
|
||||||
|
*/
|
||||||
|
closeMask() {
|
||||||
|
this.maskShow = false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 公用方法,遮罩层禁止点击
|
||||||
|
*/
|
||||||
|
disableMask() {
|
||||||
|
this.mkclick = false
|
||||||
|
},
|
||||||
|
// TODO nvue 取消冒泡
|
||||||
|
clear(e) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
e.stopPropagation()
|
||||||
|
// #endif
|
||||||
|
this.clearPropagation = true
|
||||||
|
},
|
||||||
|
|
||||||
|
open(direction) {
|
||||||
|
// fix by mehaotian 处理快速打开关闭的情况
|
||||||
|
if (this.showPopup) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
|
||||||
|
if (!(direction && innerType.indexOf(direction) !== -1)) {
|
||||||
|
direction = this.type
|
||||||
|
}
|
||||||
|
if (!this.config[direction]) {
|
||||||
|
console.error('缺少类型:', direction)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this[this.config[direction]]()
|
||||||
|
this.$emit('change', {
|
||||||
|
show: true,
|
||||||
|
type: direction
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close(type) {
|
||||||
|
this.showTrans = false
|
||||||
|
this.$emit('change', {
|
||||||
|
show: false,
|
||||||
|
type: this.type
|
||||||
|
})
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
// // 自定义关闭事件
|
||||||
|
// this.customOpen && this.customClose()
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.showPopup = false
|
||||||
|
}, 300)
|
||||||
|
},
|
||||||
|
// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
|
||||||
|
touchstart() {
|
||||||
|
this.clearPropagation = false
|
||||||
|
},
|
||||||
|
|
||||||
|
onTap() {
|
||||||
|
if (this.clearPropagation) {
|
||||||
|
// fix by mehaotian 兼容 nvue
|
||||||
|
this.clearPropagation = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$emit('maskClick')
|
||||||
|
if (!this.mkclick) return
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 顶部弹出样式处理
|
||||||
|
*/
|
||||||
|
top(type) {
|
||||||
|
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
|
||||||
|
this.ani = ['slide-top']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0"
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPopup = true
|
||||||
|
this.showTrans = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.showPoptrans()
|
||||||
|
if (this.messageChild && this.type === 'message') {
|
||||||
|
this.messageChild.timerClose()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 底部弹出样式处理
|
||||||
|
*/
|
||||||
|
bottom(type) {
|
||||||
|
this.popupstyle = 'bottom'
|
||||||
|
this.ani = ['slide-bottom']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
paddingBottom: this.safeAreaInsets + 'px',
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0",
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 中间弹出样式处理
|
||||||
|
*/
|
||||||
|
center(type) {
|
||||||
|
this.popupstyle = 'center'
|
||||||
|
//微信小程序下,组合动画会出现文字向上闪动问题,再此做特殊处理
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.ani = ['fade']
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
this.ani = ['zoom-out', 'fade']
|
||||||
|
// #endif
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
/* #endif */
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
borderRadius:this.borderRadius || "0"
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
left(type) {
|
||||||
|
this.popupstyle = 'left'
|
||||||
|
this.ani = ['slide-left']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
top: 0,
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0",
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
right(type) {
|
||||||
|
this.popupstyle = 'right'
|
||||||
|
this.ani = ['slide-right']
|
||||||
|
this.transClass = {
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
backgroundColor: this.bg,
|
||||||
|
borderRadius:this.borderRadius || "0",
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column'
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
// TODO 兼容 type 属性 ,后续会废弃
|
||||||
|
if (type) return
|
||||||
|
this.showPoptrans()
|
||||||
|
},
|
||||||
|
showPoptrans(){
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.showPopup = true
|
||||||
|
this.showTrans = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.uni-popup {
|
||||||
|
position: fixed;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 99;
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
&.top,
|
||||||
|
&.left,
|
||||||
|
&.right {
|
||||||
|
/* #ifdef H5 */
|
||||||
|
top: var(--window-top);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
top: 0;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popup__wrapper {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
/* iphonex 等安全区设置,底部安全区适配 */
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
// padding-bottom: constant(safe-area-inset-bottom);
|
||||||
|
// padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
/* #endif */
|
||||||
|
&.left,
|
||||||
|
&.right {
|
||||||
|
/* #ifdef H5 */
|
||||||
|
padding-top: var(--window-top);
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef H5 */
|
||||||
|
padding-top: 0;
|
||||||
|
/* #endif */
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixforpc-z-index {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 999;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixforpc-top {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
107
uni_modules/uni-popup/package.json
Normal file
107
uni_modules/uni-popup/package.json
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-popup",
|
||||||
|
"displayName": "uni-popup 弹出层",
|
||||||
|
"version": "1.9.11",
|
||||||
|
"description": " Popup 组件,提供常用的弹层",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"弹出层",
|
||||||
|
"弹窗",
|
||||||
|
"popup",
|
||||||
|
"弹框"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "",
|
||||||
|
"uni-app": "^4.07",
|
||||||
|
"uni-app-x": ""
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
"darkmode": "x",
|
||||||
|
"i18n": "x",
|
||||||
|
"widescreen": "x"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-transition"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "x",
|
||||||
|
"aliyun": "x",
|
||||||
|
"alipay": "x"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"uni-app": {
|
||||||
|
"vue": {
|
||||||
|
"vue2": "√",
|
||||||
|
"vue3": "√"
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"safari": "√",
|
||||||
|
"chrome": "√"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"vue": "√",
|
||||||
|
"nvue": "√",
|
||||||
|
"android": "√",
|
||||||
|
"ios": "√",
|
||||||
|
"harmony": "√"
|
||||||
|
},
|
||||||
|
"mp": {
|
||||||
|
"weixin": "√",
|
||||||
|
"alipay": "√",
|
||||||
|
"toutiao": "√",
|
||||||
|
"baidu": "√",
|
||||||
|
"kuaishou": "-",
|
||||||
|
"jd": "-",
|
||||||
|
"harmony": "-",
|
||||||
|
"qq": "√",
|
||||||
|
"lark": "-"
|
||||||
|
},
|
||||||
|
"quickapp": {
|
||||||
|
"huawei": "-",
|
||||||
|
"union": "-"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uni-app-x": {
|
||||||
|
"web": {
|
||||||
|
"safari": "√",
|
||||||
|
"chrome": "√"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"android": "√",
|
||||||
|
"ios": "√",
|
||||||
|
"harmony": "√"
|
||||||
|
},
|
||||||
|
"mp": {
|
||||||
|
"weixin": "√"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
uni_modules/uni-popup/readme.md
Normal file
17
uni_modules/uni-popup/readme.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Popup 弹出层
|
||||||
|
> **组件名:uni-popup**
|
||||||
|
> 代码块: `uPopup`
|
||||||
|
> 关联组件:`uni-transition`
|
||||||
|
|
||||||
|
|
||||||
|
弹出层组件,在应用中弹出一个消息提示窗口、提示框等
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
31
uni_modules/uni-transition/changelog.md
Normal file
31
uni_modules/uni-transition/changelog.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
## 1.3.6(2025-07-18)
|
||||||
|
- 修复 nvue 页面,样式错误问题
|
||||||
|
## 1.3.5(2025-06-11)
|
||||||
|
- 修复 第一次执行不显示动画的问题
|
||||||
|
## 1.3.4(2025-04-16)
|
||||||
|
- 修复 页面数据更新到底动画复原的问题
|
||||||
|
- 修复 示例页面打开报错的问题
|
||||||
|
## 1.3.3(2024-04-23)
|
||||||
|
- 修复 当元素会受变量影响自动隐藏的bug
|
||||||
|
## 1.3.2(2023-05-04)
|
||||||
|
- 修复 NVUE 平台报错的问题
|
||||||
|
## 1.3.1(2021-11-23)
|
||||||
|
- 修复 init 方法初始化问题
|
||||||
|
## 1.3.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
|
||||||
|
## 1.2.1(2021-09-27)
|
||||||
|
- 修复 init 方法不生效的 Bug
|
||||||
|
## 1.2.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.1.1(2021-05-12)
|
||||||
|
- 新增 示例地址
|
||||||
|
- 修复 示例项目缺少组件的 Bug
|
||||||
|
## 1.1.0(2021-04-22)
|
||||||
|
- 新增 通过方法自定义动画
|
||||||
|
- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
|
||||||
|
- 优化 动画触发逻辑,使动画更流畅
|
||||||
|
- 优化 支持单独的动画类型
|
||||||
|
- 优化 文档示例
|
||||||
|
## 1.0.2(2021-02-05)
|
||||||
|
- 调整为 uni_modules 目录规范
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
// const defaultOption = {
|
||||||
|
// duration: 300,
|
||||||
|
// timingFunction: 'linear',
|
||||||
|
// delay: 0,
|
||||||
|
// transformOrigin: '50% 50% 0'
|
||||||
|
// }
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const nvueAnimation = uni.requireNativePlugin('animation')
|
||||||
|
// #endif
|
||||||
|
class MPAnimation {
|
||||||
|
constructor(options, _this) {
|
||||||
|
this.options = options
|
||||||
|
// 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
|
||||||
|
this.animation = uni.createAnimation({
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
this.currentStepAnimates = {}
|
||||||
|
this.next = 0
|
||||||
|
this.$ = _this
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvuePushAnimates(type, args) {
|
||||||
|
let aniObj = this.currentStepAnimates[this.next]
|
||||||
|
let styles = {}
|
||||||
|
if (!aniObj) {
|
||||||
|
styles = {
|
||||||
|
styles: {},
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
styles = aniObj
|
||||||
|
}
|
||||||
|
if (animateTypes1.includes(type)) {
|
||||||
|
if (!styles.styles.transform) {
|
||||||
|
styles.styles.transform = ''
|
||||||
|
}
|
||||||
|
let unit = ''
|
||||||
|
if(type === 'rotate'){
|
||||||
|
unit = 'deg'
|
||||||
|
}
|
||||||
|
styles.styles.transform += `${type}(${args+unit}) `
|
||||||
|
} else {
|
||||||
|
styles.styles[type] = `${args}`
|
||||||
|
}
|
||||||
|
this.currentStepAnimates[this.next] = styles
|
||||||
|
}
|
||||||
|
_animateRun(styles = {}, config = {}) {
|
||||||
|
let ref = this.$.$refs['ani'].ref
|
||||||
|
if (!ref) return
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
nvueAnimation.transition(ref, {
|
||||||
|
styles,
|
||||||
|
...config
|
||||||
|
}, res => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvueNextAnimate(animates, step = 0, fn) {
|
||||||
|
let obj = animates[step]
|
||||||
|
if (obj) {
|
||||||
|
let {
|
||||||
|
styles,
|
||||||
|
config
|
||||||
|
} = obj
|
||||||
|
this._animateRun(styles, config).then(() => {
|
||||||
|
step += 1
|
||||||
|
this._nvueNextAnimate(animates, step, fn)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.currentStepAnimates = {}
|
||||||
|
typeof fn === 'function' && fn()
|
||||||
|
this.isEnd = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step(config = {}) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.animation.step(config)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
|
||||||
|
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
|
||||||
|
this.next++
|
||||||
|
// #endif
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
run(fn) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.$.animationData = this.animation.export()
|
||||||
|
this.$.timer = setTimeout(() => {
|
||||||
|
typeof fn === 'function' && fn()
|
||||||
|
}, this.$.durationTime)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.isEnd = false
|
||||||
|
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
|
||||||
|
if(!ref) return
|
||||||
|
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
|
||||||
|
this.next = 0
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
|
||||||
|
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
|
||||||
|
'translateZ'
|
||||||
|
]
|
||||||
|
const animateTypes2 = ['opacity', 'backgroundColor']
|
||||||
|
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
||||||
|
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
|
||||||
|
MPAnimation.prototype[type] = function(...args) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.animation[type](...args)
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this._nvuePushAnimates(type, args)
|
||||||
|
// #endif
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export function createAnimation(option, _this) {
|
||||||
|
if(!_this) return
|
||||||
|
clearTimeout(_this.timer)
|
||||||
|
return new MPAnimation(option, _this)
|
||||||
|
}
|
||||||
@@ -0,0 +1,292 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick">
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick">
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { createAnimation } from './createAnimation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transition 过渡动画
|
||||||
|
* @description 简单过渡动画组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
|
||||||
|
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
|
||||||
|
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
|
||||||
|
* @value fade 渐隐渐出过渡
|
||||||
|
* @value slide-top 由上至下过渡
|
||||||
|
* @value slide-right 由右至左过渡
|
||||||
|
* @value slide-bottom 由下至上过渡
|
||||||
|
* @value slide-left 由左至右过渡
|
||||||
|
* @value zoom-in 由小到大过渡
|
||||||
|
* @value zoom-out 由大到小过渡
|
||||||
|
* @property {Number} duration 过渡动画持续时间
|
||||||
|
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTransition',
|
||||||
|
emits: ['click', 'change'],
|
||||||
|
props: {
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
modeClass: {
|
||||||
|
type: [Array, String],
|
||||||
|
default () {
|
||||||
|
return 'fade'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
customClass: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
onceRender: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isShow: false,
|
||||||
|
transform: '',
|
||||||
|
opacity: 0,
|
||||||
|
animationData: {},
|
||||||
|
durationTime: 300,
|
||||||
|
config: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show: {
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.open()
|
||||||
|
} else {
|
||||||
|
// 避免上来就执行 close,导致动画错乱
|
||||||
|
if (this.isShow) {
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 生成样式数据
|
||||||
|
stylesObject() {
|
||||||
|
let styles = {
|
||||||
|
...this.styles,
|
||||||
|
'transition-duration': this.duration / 1000 + 's'
|
||||||
|
}
|
||||||
|
let transform = ''
|
||||||
|
for (let i in styles) {
|
||||||
|
let line = this.toLine(i)
|
||||||
|
transform += line + ':' + styles[i] + ';'
|
||||||
|
}
|
||||||
|
return transform
|
||||||
|
},
|
||||||
|
// 初始化动画条件
|
||||||
|
transformStyles() {
|
||||||
|
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 动画默认配置
|
||||||
|
this.config = {
|
||||||
|
duration: this.duration,
|
||||||
|
timingFunction: 'ease',
|
||||||
|
transformOrigin: '50% 50%',
|
||||||
|
delay: 0
|
||||||
|
}
|
||||||
|
this.durationTime = this.duration
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* ref 触发 初始化动画
|
||||||
|
*/
|
||||||
|
init(obj = {}) {
|
||||||
|
if (obj.duration) {
|
||||||
|
this.durationTime = obj.duration
|
||||||
|
}
|
||||||
|
this.animation = createAnimation(Object.assign(this.config, obj), this)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 点击组件触发回调
|
||||||
|
*/
|
||||||
|
onClick() {
|
||||||
|
this.$emit('click', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ref 触发 动画分组
|
||||||
|
* @param {Object} obj
|
||||||
|
*/
|
||||||
|
step(obj, config = {}) {
|
||||||
|
if (!this.animation) return this
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
if (typeof this.animation[key] === 'function') {
|
||||||
|
Array.isArray(value) ?
|
||||||
|
this.animation[key](...value) :
|
||||||
|
this.animation[key](value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.animation.step(config)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ref 触发 执行动画
|
||||||
|
*/
|
||||||
|
run(fn) {
|
||||||
|
if (!this.animation) return
|
||||||
|
this.animation.run(fn)
|
||||||
|
},
|
||||||
|
// 开始过度动画
|
||||||
|
open() {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.isShow = true
|
||||||
|
// 新增初始状态重置逻辑(关键)
|
||||||
|
this.transform = this.styleInit(false).transform || ''
|
||||||
|
this.opacity = this.styleInit(false).opacity || 0
|
||||||
|
|
||||||
|
// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.animation = createAnimation(this.config, this)
|
||||||
|
this.tranfromInit(false).step()
|
||||||
|
this.animation.run(() => {
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
this.transform = this.styleInit(false).transform || ''
|
||||||
|
this.opacity = this.styleInit(false).opacity || 1
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.transform = ''
|
||||||
|
this.opacity = this.styleInit(false).opacity || 1
|
||||||
|
// #endif
|
||||||
|
this.$emit('change', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, 80)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 关闭过度动画
|
||||||
|
close(type) {
|
||||||
|
if (!this.animation) return
|
||||||
|
this.tranfromInit(true)
|
||||||
|
.step()
|
||||||
|
.run(() => {
|
||||||
|
this.isShow = false
|
||||||
|
this.animationData = null
|
||||||
|
this.animation = null
|
||||||
|
let { opacity, transform } = this.styleInit(false)
|
||||||
|
this.opacity = opacity || 1
|
||||||
|
this.transform = transform
|
||||||
|
this.$emit('change', {
|
||||||
|
detail: this.isShow
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 处理动画开始前的默认样式
|
||||||
|
styleInit(type) {
|
||||||
|
let styles = { transform: '', opacity: 1 }
|
||||||
|
const buildStyle = (type, mode) => {
|
||||||
|
const value = this.animationType(type)[mode] // 直接使用 type 控制状态
|
||||||
|
if (mode.startsWith('fade')) {
|
||||||
|
styles.opacity = value
|
||||||
|
} else {
|
||||||
|
styles.transform += value + ' '
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof this.modeClass === 'string') {
|
||||||
|
buildStyle(type, this.modeClass)
|
||||||
|
} else {
|
||||||
|
this.modeClass.forEach(mode => buildStyle(type, mode))
|
||||||
|
}
|
||||||
|
return styles
|
||||||
|
},
|
||||||
|
// 处理内置组合动画
|
||||||
|
tranfromInit(type) {
|
||||||
|
let buildTranfrom = (type, mode) => {
|
||||||
|
let aniNum = null
|
||||||
|
if (mode === 'fade') {
|
||||||
|
aniNum = type ? 0 : 1
|
||||||
|
} else {
|
||||||
|
aniNum = type ? '-100%' : '0'
|
||||||
|
if (mode === 'zoom-in') {
|
||||||
|
aniNum = type ? 0.8 : 1
|
||||||
|
}
|
||||||
|
if (mode === 'zoom-out') {
|
||||||
|
aniNum = type ? 1.2 : 1
|
||||||
|
}
|
||||||
|
if (mode === 'slide-right') {
|
||||||
|
aniNum = type ? '100%' : '0'
|
||||||
|
}
|
||||||
|
if (mode === 'slide-bottom') {
|
||||||
|
aniNum = type ? '100%' : '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.animation[this.animationMode()[mode]](aniNum)
|
||||||
|
}
|
||||||
|
if (typeof this.modeClass === 'string') {
|
||||||
|
buildTranfrom(type, this.modeClass)
|
||||||
|
} else {
|
||||||
|
this.modeClass.forEach(mode => {
|
||||||
|
buildTranfrom(type, mode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.animation
|
||||||
|
},
|
||||||
|
animationType(type) {
|
||||||
|
return {
|
||||||
|
fade: type ? 1 : 0,
|
||||||
|
'slide-top': `translateY(${type ? '0' : '-100%'})`,
|
||||||
|
'slide-right': `translateX(${type ? '0' : '100%'})`,
|
||||||
|
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
|
||||||
|
'slide-left': `translateX(${type ? '0' : '-100%'})`,
|
||||||
|
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
|
||||||
|
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 内置动画类型与实际动画对应字典
|
||||||
|
animationMode() {
|
||||||
|
return {
|
||||||
|
fade: 'opacity',
|
||||||
|
'slide-top': 'translateY',
|
||||||
|
'slide-right': 'translateX',
|
||||||
|
'slide-bottom': 'translateY',
|
||||||
|
'slide-left': 'translateX',
|
||||||
|
'zoom-in': 'scale',
|
||||||
|
'zoom-out': 'scale'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 驼峰转中横线
|
||||||
|
toLine(name) {
|
||||||
|
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
112
uni_modules/uni-transition/package.json
Normal file
112
uni_modules/uni-transition/package.json
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-transition",
|
||||||
|
"displayName": "uni-transition 过渡动画",
|
||||||
|
"version": "1.3.6",
|
||||||
|
"description": "元素的简单过渡动画",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"动画",
|
||||||
|
"过渡",
|
||||||
|
"过渡动画"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "",
|
||||||
|
"uni-app": "^4.12",
|
||||||
|
"uni-app-x": ""
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
"darkmode": "x",
|
||||||
|
"i18n": "x",
|
||||||
|
"widescreen": "x"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "x",
|
||||||
|
"aliyun": "x",
|
||||||
|
"alipay": "x"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"uni-app": {
|
||||||
|
"vue": {
|
||||||
|
"vue2": "√",
|
||||||
|
"vue3": "√"
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"safari": "√",
|
||||||
|
"chrome": "√"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"vue": "√",
|
||||||
|
"nvue": "√",
|
||||||
|
"android": "√",
|
||||||
|
"ios": "√",
|
||||||
|
"harmony": "√"
|
||||||
|
},
|
||||||
|
"mp": {
|
||||||
|
"weixin": {
|
||||||
|
},
|
||||||
|
"alipay": {
|
||||||
|
},
|
||||||
|
"toutiao": {
|
||||||
|
},
|
||||||
|
"baidu": {
|
||||||
|
},
|
||||||
|
"kuaishou": {
|
||||||
|
},
|
||||||
|
"jd": {
|
||||||
|
},
|
||||||
|
"harmony": "-",
|
||||||
|
"qq": "√",
|
||||||
|
"lark": "-"
|
||||||
|
},
|
||||||
|
"quickapp": {
|
||||||
|
"huawei": "√",
|
||||||
|
"union": "√"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uni-app-x": {
|
||||||
|
"web": {
|
||||||
|
"safari": "-",
|
||||||
|
"chrome": "-"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"android": "-",
|
||||||
|
"ios": "-",
|
||||||
|
"harmony": "-"
|
||||||
|
},
|
||||||
|
"mp": {
|
||||||
|
"weixin": "-"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
uni_modules/uni-transition/readme.md
Normal file
11
uni_modules/uni-transition/readme.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Transition 过渡动画
|
||||||
|
> **组件名:uni-transition**
|
||||||
|
> 代码块: `uTransition`
|
||||||
|
|
||||||
|
|
||||||
|
元素过渡动画
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||||
@@ -12,6 +12,9 @@ const ID_CARD_REGEX = /(^\d{15}$)|(^\d{18}$)|(^\d{17}[\dXx]$)/
|
|||||||
/** 密码强度(至少8位,包含数字和字母) */
|
/** 密码强度(至少8位,包含数字和字母) */
|
||||||
const PASSWORD_REGEX = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/
|
const PASSWORD_REGEX = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/
|
||||||
|
|
||||||
|
/** 交易密码(6–20 位,必须包含数字 + 字母(大小写均可)) */
|
||||||
|
const TRANSACTION_PASSWORD_REGEX = /^(?=.*\d)(?=.*[a-zA-Z]).{6,20}$/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验手机号
|
* 校验手机号
|
||||||
* @param {string} phone - 待校验的手机号
|
* @param {string} phone - 待校验的手机号
|
||||||
@@ -82,3 +85,20 @@ export const validateIdCard = idCard => {
|
|||||||
}
|
}
|
||||||
return { valid: true, message: '' }
|
return { valid: true, message: '' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验交易密码
|
||||||
|
* @param {string} password - 待校验的密码
|
||||||
|
* @returns {{ valid: boolean, message: string }}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const validateTransactionPassword = (password, name = '密码') => {
|
||||||
|
if (!password) return { valid: false, message: `${name}不能为空` }
|
||||||
|
if (password.length < 6) {
|
||||||
|
return { valid: false, message: `${name}长度不能少于6位` }
|
||||||
|
}
|
||||||
|
if (!TRANSACTION_PASSWORD_REGEX.test(password)) {
|
||||||
|
return { valid: false, message: `${name}需包含字母和数字` }
|
||||||
|
}
|
||||||
|
return { valid: true, message: '' }
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user