uview组件和uniapp组件冲突问题、视频评论
9个文件已修改
47个文件已添加
1 文件已重命名
| | |
| | | @font-face { |
| | | font-family: 'iconfont'; /* Project id 4921691 */ |
| | | src: |
| | | url('//at.alicdn.com/t/c/font_4921691_ds91dsf3lgc.woff2?t=1747375499357') format('woff2'), |
| | | url('//at.alicdn.com/t/c/font_4921691_ds91dsf3lgc.woff?t=1747375499357') format('woff'), |
| | | url('//at.alicdn.com/t/c/font_4921691_ds91dsf3lgc.ttf?t=1747375499357') format('truetype'); |
| | | url('//at.alicdn.com/t/c/font_4921691_1hkd3qibo87.woff2?t=1748343163548') format('woff2'), |
| | | url('//at.alicdn.com/t/c/font_4921691_1hkd3qibo87.woff?t=1748343163548') format('woff'), |
| | | url('//at.alicdn.com/t/c/font_4921691_1hkd3qibo87.ttf?t=1748343163548') format('truetype'); |
| | | } |
| | | .iconfont { |
| | | /* font-family需要和自定义的相同 */ |
| | |
| | | needToken: true |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 获取视频评论 |
| | | * |
| | | * @param params |
| | | */ |
| | | export function getVideoComments(params) { |
| | | return http.request({ |
| | | url: "/lmk/video-comment/wx/page", |
| | | method: Method.GET, |
| | | needToken: true, |
| | | params: params |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 发布视频评论 |
| | | * |
| | | * @param params |
| | | */ |
| | | export function addVideoComment(data) { |
| | | return http.request({ |
| | | url: "/lmk/video-comment/comment", |
| | | method: Method.POST, |
| | | needToken: true, |
| | | data: data |
| | | }); |
| | | } |
| | |
| | | |
| | | import * as API_trade from '@/api/trade.js'; |
| | | import setup from './popup'; |
| | | import uniNumberBox from '@/components/uni-number-box' |
| | | // import uniNumberBox from '@/components/uni-number-box' |
| | | export default { |
| | | components: { |
| | | uniNumberBox |
| | | // uniNumberBox |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | "versionName" : "4.5.3", |
| | | "versionCode" : 4000503, |
| | | "transformPx" : false, |
| | | "sassImplementationName" : "node-sass", |
| | | "app-plus" : { |
| | | "compatible" : { |
| | | "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持 |
| | |
| | | "easycom": { |
| | | "autoscan": true, |
| | | "custom": { |
| | | "^u-(.*)": "@/uview-components/uview-ui/components/u-$1/u-$1.vue"//uview |
| | | "^u-(.*)": "@/uview-components/uview-ui/components/u-$1/u-$1.vue",//uview, |
| | | "^uni-(.*)": "@/uni_modules/uni-$1/components/uni-$1/uni-$1.vue" // uniapp组件 |
| | | } |
| | | }, |
| | | "preloadRule": { |
| | |
| | | "u-image": "view", |
| | | "u-loading": "view", |
| | | "u-tag": "view", |
| | | "u-icon": "view" |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | "path": "components/popups/popups", |
| | | "style": { |
| | | "navigationBarTitleText": "", |
| | | "navigationStyle": "custom", |
| | | "componentPlaceholder": { |
| | | "u-icon": "view" |
| | | } |
| | | } |
| | |
| | | import ULoadmore from '@/uview-components/uview-ui/components/u-loadmore/u-loadmore.vue'; |
| | | import UModal from '@/uview-components/uview-ui/components/u-modal/u-modal.vue'; |
| | | |
| | | import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue"; |
| | | import { getAfterSaleList, cancelAfterSale } from "@/api/after-sale.js"; |
| | | import { getOrderList } from "@/api/order.js"; |
| | | import storage from "@/utils/storage"; |
| | | |
| | | export default { |
| | | components: { |
| | | uniLoadMore,UTabs,USearch,UImage,UIcon,ULoadmore |
| | | UTabs,USearch,UImage,UIcon,ULoadmore |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | import UButton from '@/uview-components/uview-ui/components/u-button/u-button.vue'; |
| | | import UToast from '@/uview-components/uview-ui/components/u-toast/u-toast.vue'; |
| | | import UModal from '@/uview-components/uview-ui/components/u-modal/u-modal.vue'; |
| | | import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue"; |
| | | import { getOrderList, cancelOrder, confirmReceipt } from "@/api/order.js"; |
| | | import { getClearReason } from "@/api/after-sale.js"; |
| | | import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js"; |
| | | export default { |
| | | components: { |
| | | uniLoadMore,UEmpty,UImage,UPopup,URadioGroup,URadio,UButton,UToast,UModal |
| | | UEmpty,UImage,UPopup,URadioGroup,URadio,UButton,UToast,UModal |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | import UToast from '@/uview-components/uview-ui/components/u-toast/u-toast.vue'; |
| | | import * as API_Trade from "@/api/trade"; |
| | | import { debounce } from "@/utils/tools.js"; |
| | | import uniNumberBox from '@/components/uni-number-box' |
| | | // import uniNumberBox from '@/components/uni-number-box' |
| | | export default { |
| | | components:{uniNumberBox,UNavbar,UCheckboxGroup,UCheckbox,USwipeAction,UImage,UIcon,UPopup,UCountDown,UModal,UToast}, // 数量加减组件 |
| | | components:{UNavbar,UCheckboxGroup,UCheckbox,USwipeAction,UImage,UIcon,UPopup,UCountDown,UModal,UToast}, // 数量加减组件 |
| | | data() { |
| | | return { |
| | | loading:false, |
| | |
| | | <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | </swiper-item> |
| | | </swiper> |
| | | |
| | | <!-- 评论弹窗 --> |
| | | <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup"> |
| | | <view class="comment-popup"> |
| | | <view class="popup-header"> |
| | | <text class="popup-title">评论({{comments.length}})</text> |
| | | <text class="iconfont close-icon" @click="closeCommentPopup"></text> |
| | | </view> |
| | | |
| | | <scroll-view class="comment-list" scroll-y> |
| | | <view v-if="commentLoading" class="loading"> |
| | | <uni-load-more status="loading"></uni-load-more> |
| | | </view> |
| | | |
| | | <view v-else-if="comments.length === 0" class="empty"> |
| | | 暂无评论,快来发表第一条评论吧~ |
| | | </view> |
| | | |
| | | <view v-else class="comment-item" v-for="comment in comments" :key="comment.id"> |
| | | <image class="avatar" :src="comment.user.avatar || '/static/default-avatar.png'"></image> |
| | | <view class="comment-content"> |
| | | <text class="nickname">{{comment.user.nickname}}</text> |
| | | <text class="content">{{comment.content}}</text> |
| | | <text class="time">{{formatTime(comment.createTime)}}</text> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <view class="comment-input-area"> |
| | | <input |
| | | class="comment-input" |
| | | v-model="commentForm.commentContent" |
| | | placeholder="写下你的评论..." |
| | | placeholder-class="placeholder" |
| | | /> |
| | | <button class="submit-btn" @click="submitComment">发送</button> |
| | | </view> |
| | | </view> |
| | | </uni-popup> |
| | | |
| | | |
| | | <custom-tabbar bgColor="#333333" selected="index" selectedTextColor="#ffffff"></custom-tabbar> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getRecommendVideos, savePlayRecord, subscribe } from "@/api/video.js"; |
| | | import { getRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment } from "@/api/video.js"; |
| | | import { changeCollect } from "@/api/collect.js"; |
| | | export default { |
| | | data() { |
| | | return { |
| | | commentQuery: { |
| | | pageNumber: 1, |
| | | pageSize: 5, |
| | | videoId: '', |
| | | masterCommentId: '' |
| | | }, |
| | | commentForm: { // 评论表单数据 |
| | | id: null, |
| | | videoId: null, |
| | | commentContent: '', |
| | | replyId: null |
| | | }, |
| | | comments: [], // 评论列表 |
| | | commentLoading: false, // 评论加载状态 |
| | | startHidenTime: 0, // 记录切换至其它页面的时间,用于计算视频观看时间减去的部分 |
| | | totalHidenTime: 0, // 总共隐藏页面的时间 |
| | | startPauseTime: 0, // 开始暂停的时间 |
| | |
| | | this.initVideoContexts(); |
| | | }, |
| | | methods: { |
| | | // 格式化时间 |
| | | formatTime(time) { |
| | | const date = new Date(time); |
| | | const now = new Date(); |
| | | const diff = Math.floor((now - date) / 1000); // 秒 |
| | | |
| | | if (diff < 60) return '刚刚'; |
| | | if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`; |
| | | if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`; |
| | | |
| | | return `${date.getMonth() + 1}月${date.getDate()}日`; |
| | | }, |
| | | // 提交评论 |
| | | async submitComment() { |
| | | if (!this.commentForm.commentContent.trim()) { |
| | | uni.showToast({ |
| | | title: '评论内容不能为空', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | // 发表评论 |
| | | addVideoComment(this.commentForm).then(res => { |
| | | if(res.data.code === 200) { |
| | | this.commentForm = { |
| | | id: null, |
| | | videoId: null, |
| | | commentContent: '', |
| | | replyId: null |
| | | } |
| | | this.comments.unshift(res.data.data); |
| | | uni.showToast({ |
| | | title: '评论成功' |
| | | }); |
| | | // 当前视频评论数加一 |
| | | this.videoList[this.currentIndex].commentNum += 1; |
| | | } else { |
| | | uni.showToast({ |
| | | title: res.data.msg, |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }).catch(() => { |
| | | uni.showToast({ |
| | | title: '评论失败', |
| | | icon: 'none' |
| | | }); |
| | | }) |
| | | }, |
| | | // 关闭评论弹窗 |
| | | closeCommentPopup() { |
| | | console.log("触发了"); |
| | | this.$refs.commentPopup.close() |
| | | this.showCommentPopup = false; |
| | | this.comments = []; |
| | | this.commentForm = { |
| | | id: null, |
| | | videoId: null, |
| | | commentContent: '', |
| | | replyId: null |
| | | } |
| | | }, |
| | | // 显示评论弹窗 |
| | | async showComments(item) { |
| | | this.commentForm.videoId = item.id; |
| | | this.$refs.commentPopup.open(); |
| | | this.commentLoading = true; |
| | | this.commentQuery.videoId = item.id |
| | | getVideoComments(this.commentQuery).then(res => { |
| | | this.comments = res.data.data |
| | | }).catch(() => { |
| | | uni.showToast({ |
| | | title: '获取评论失败', |
| | | icon: 'none' |
| | | }); |
| | | }).finally(() => { |
| | | this.commentLoading = false; |
| | | }) |
| | | }, |
| | | // 关注作者 |
| | | subscribeAuth(index, authorId) { |
| | | this.videoList.forEach(video => { |
| | |
| | | font-size: 26rpx; |
| | | font-weight: bold; |
| | | } |
| | | /* 评论弹窗样式 */ |
| | | .comment-popup { |
| | | background-color: #fff; |
| | | border-radius: 20rpx 20rpx 0 0; |
| | | padding-bottom: env(safe-area-inset-bottom); |
| | | height: 50vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .popup-header { |
| | | padding: 30rpx; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .close-icon { |
| | | /* font-size: 36rpx; */ |
| | | color: #999; |
| | | } |
| | | |
| | | .comment-list { |
| | | flex: 1; |
| | | padding: 20rpx; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .comment-item { |
| | | display: flex; |
| | | padding: 20rpx 0; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | } |
| | | |
| | | .avatar { |
| | | width: 80rpx; |
| | | height: 80rpx; |
| | | border-radius: 50%; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .comment-content { |
| | | flex: 1; |
| | | } |
| | | |
| | | .nickname { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | display: block; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .content { |
| | | font-size: 30rpx; |
| | | color: #333; |
| | | display: block; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .time { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | } |
| | | |
| | | .comment-input-area { |
| | | display: flex; |
| | | padding: 20rpx 30rpx; |
| | | align-items: center; |
| | | } |
| | | |
| | | .comment-input { |
| | | flex: 1; |
| | | background-color: #fff; |
| | | height: 80rpx; |
| | | border: 1px solid #dcdcdc; |
| | | border-radius: 40rpx; |
| | | padding: 0 30rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #ccc; |
| | | } |
| | | |
| | | .submit-btn { |
| | | margin-left: 20rpx; |
| | | background-color: #07c160; |
| | | color: #fff; |
| | | border-radius: 40rpx; |
| | | padding: 0 30rpx; |
| | | height: 80rpx; |
| | | line-height: 80rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .loading, .empty { |
| | | padding: 40rpx 0; |
| | | text-align: center; |
| | | color: #999; |
| | | } |
| | | </style> |
New file |
| | |
| | | ## 1.3.6(2024-10-15) |
| | | - 修复 微信小程序中的getSystemInfo警告 |
| | | ## 1.3.5(2024-10-12) |
| | | - 修复 微信小程序中的getSystemInfo警告 |
| | | ## 1.3.4(2024-10-12) |
| | | - 修复 微信小程序中的getSystemInfo警告 |
| | | ## 1.3.3(2022-01-20) |
| | | - 新增 showText属性 ,是否显示文本 |
| | | ## 1.3.2(2022-01-19) |
| | | - 修复 nvue 平台下不显示文本的bug |
| | | ## 1.3.1(2022-01-19) |
| | | - 修复 微信小程序平台样式选择器报警告的问题 |
| | | ## 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-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more) |
| | | ## 1.2.1(2021-08-24) |
| | | - 新增 支持国际化 |
| | | ## 1.2.0(2021-07-30) |
| | | - 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
| | | ## 1.1.8(2021-05-12) |
| | | - 新增 组件示例地址 |
| | | ## 1.1.7(2021-03-30) |
| | | - 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug |
| | | ## 1.1.6(2021-02-05) |
| | | - 调整为uni_modules目录规范 |
New file |
| | |
| | | { |
| | | "uni-load-more.contentdown": "Pull up to show more", |
| | | "uni-load-more.contentrefresh": "loading...", |
| | | "uni-load-more.contentnomore": "No more data" |
| | | } |
New file |
| | |
| | | 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 |
| | | } |
New file |
| | |
| | | { |
| | | "uni-load-more.contentdown": "上拉显示更多", |
| | | "uni-load-more.contentrefresh": "正在加载...", |
| | | "uni-load-more.contentnomore": "没有更多数据了" |
| | | } |
New file |
| | |
| | | { |
| | | "uni-load-more.contentdown": "上拉顯示更多", |
| | | "uni-load-more.contentrefresh": "正在加載...", |
| | | "uni-load-more.contentnomore": "沒有更多數據了" |
| | | } |
New file |
| | |
| | | <template> |
| | | <view class="uni-load-more" @click="onClick"> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <loading-indicator v-if="!webviewHide && status === 'loading' && showIcon" |
| | | :style="{color: color,width:iconSize+'px',height:iconSize+'px'}" :animating="true" |
| | | class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator> |
| | | <!-- #endif --> |
| | | <!-- #ifdef H5 --> |
| | | <svg width="24" height="24" viewBox="25 25 50 50" |
| | | v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon" |
| | | :style="{width:iconSize+'px',height:iconSize+'px'}" |
| | | class="uni-load-more__img uni-load-more__img--android-H5"> |
| | | <circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle> |
| | | </svg> |
| | | <!-- #endif --> |
| | | <!-- #ifndef APP-NVUE || H5 --> |
| | | <view |
| | | v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon" |
| | | :style="{width:iconSize+'px',height:iconSize+'px'}" |
| | | class="uni-load-more__img uni-load-more__img--android-MP"> |
| | | <view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view> |
| | | <view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view> |
| | | <view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view> |
| | | </view> |
| | | <!-- #endif --> |
| | | <!-- #ifndef APP-NVUE --> |
| | | <view v-else-if="!webviewHide && status === 'loading' && showIcon" |
| | | :style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5"> |
| | | <image :src="imgBase64" mode="widthFix"></image> |
| | | </view> |
| | | <!-- #endif --> |
| | | <text v-if="showText" class="uni-load-more__text" |
| | | :style="{color: color}">{{ status === 'more' ? contentdownText : status === 'loading' ? contentrefreshText : contentnomoreText }}</text> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | let platform |
| | | setTimeout(() => { |
| | | // #ifdef MP-WEIXIN |
| | | platform = uni.getDeviceInfo().platform |
| | | // #endif |
| | | // #ifndef MP-WEIXIN |
| | | platform = uni.getSystemInfoSync().platform |
| | | // #endif |
| | | }, 16) |
| | | |
| | | import { |
| | | initVueI18n |
| | | } from '@dcloudio/uni-i18n' |
| | | import messages from './i18n/index.js' |
| | | const { |
| | | t |
| | | } = initVueI18n(messages) |
| | | |
| | | /** |
| | | * LoadMore 加载更多 |
| | | * @description 用于列表中,做滚动加载使用,展示 loading 的各种状态 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=29 |
| | | * @property {String} status = [more|loading|noMore] loading 的状态 |
| | | * @value more loading前 |
| | | * @value loading loading中 |
| | | * @value noMore 没有更多了 |
| | | * @property {Number} iconSize 指定图标大小 |
| | | * @property {Boolean} iconSize = [true|false] 是否显示 loading 图标 |
| | | * @property {String} iconType = [snow|circle|auto] 指定图标样式 |
| | | * @value snow ios雪花加载样式 |
| | | * @value circle 安卓唤醒加载样式 |
| | | * @value auto 根据平台自动选择加载样式 |
| | | * @property {String} color 图标和文字颜色 |
| | | * @property {Object} contentText 各状态文字说明,值为:{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"} |
| | | * @event {Function} clickLoadMore 点击加载更多时触发 |
| | | */ |
| | | export default { |
| | | name: 'UniLoadMore', |
| | | emits: ['clickLoadMore'], |
| | | props: { |
| | | status: { |
| | | // 上拉的状态:more-loading前;loading-loading中;noMore-没有更多了 |
| | | type: String, |
| | | default: 'more' |
| | | }, |
| | | showIcon: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | iconType: { |
| | | type: String, |
| | | default: 'auto' |
| | | }, |
| | | iconSize: { |
| | | type: Number, |
| | | default: 24 |
| | | }, |
| | | color: { |
| | | type: String, |
| | | default: '#777777' |
| | | }, |
| | | contentText: { |
| | | type: Object, |
| | | default () { |
| | | return { |
| | | contentdown: '', |
| | | contentrefresh: '', |
| | | contentnomore: '' |
| | | } |
| | | } |
| | | }, |
| | | showText: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | webviewHide: false, |
| | | platform: platform, |
| | | imgBase64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZV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' |
| | | } |
| | | }, |
| | | computed: { |
| | | iconSnowWidth() { |
| | | return (Math.floor(this.iconSize / 24) || 1) * 2 |
| | | }, |
| | | contentdownText() { |
| | | return this.contentText.contentdown || t("uni-load-more.contentdown") |
| | | }, |
| | | contentrefreshText() { |
| | | return this.contentText.contentrefresh || t("uni-load-more.contentrefresh") |
| | | }, |
| | | contentnomoreText() { |
| | | return this.contentText.contentnomore || t("uni-load-more.contentnomore") |
| | | } |
| | | }, |
| | | mounted() { |
| | | // #ifdef APP-PLUS |
| | | var pages = getCurrentPages(); |
| | | var page = pages[pages.length - 1]; |
| | | var currentWebview = page.$getAppWebview(); |
| | | currentWebview.addEventListener('hide', () => { |
| | | this.webviewHide = true |
| | | }) |
| | | currentWebview.addEventListener('show', () => { |
| | | this.webviewHide = false |
| | | }) |
| | | // #endif |
| | | }, |
| | | methods: { |
| | | onClick() { |
| | | this.$emit('clickLoadMore', { |
| | | detail: { |
| | | status: this.status, |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" > |
| | | .uni-load-more { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | height: 40px; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .uni-load-more__text { |
| | | font-size: 14px; |
| | | margin-left: 8px; |
| | | } |
| | | |
| | | .uni-load-more__img { |
| | | width: 24px; |
| | | height: 24px; |
| | | // margin-right: 8px; |
| | | } |
| | | |
| | | .uni-load-more__img--nvue { |
| | | color: #666666; |
| | | } |
| | | |
| | | .uni-load-more__img--android, |
| | | .uni-load-more__img--ios { |
| | | width: 24px; |
| | | height: 24px; |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | /* #ifndef APP-NVUE */ |
| | | .uni-load-more__img--android { |
| | | animation: loading-ios 1s 0s linear infinite; |
| | | } |
| | | |
| | | @keyframes loading-android { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | .uni-load-more__img--ios-H5 { |
| | | position: relative; |
| | | animation: loading-ios-H5 1s 0s step-end infinite; |
| | | } |
| | | |
| | | .uni-load-more__img--ios-H5 image { |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | left: 0; |
| | | top: 0; |
| | | } |
| | | |
| | | @keyframes loading-ios-H5 { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 8% { |
| | | transform: rotate(30deg); |
| | | } |
| | | |
| | | 16% { |
| | | transform: rotate(60deg); |
| | | } |
| | | |
| | | 24% { |
| | | transform: rotate(90deg); |
| | | } |
| | | |
| | | 32% { |
| | | transform: rotate(120deg); |
| | | } |
| | | |
| | | 40% { |
| | | transform: rotate(150deg); |
| | | } |
| | | |
| | | 48% { |
| | | transform: rotate(180deg); |
| | | } |
| | | |
| | | 56% { |
| | | transform: rotate(210deg); |
| | | } |
| | | |
| | | 64% { |
| | | transform: rotate(240deg); |
| | | } |
| | | |
| | | 73% { |
| | | transform: rotate(270deg); |
| | | } |
| | | |
| | | 82% { |
| | | transform: rotate(300deg); |
| | | } |
| | | |
| | | 91% { |
| | | transform: rotate(330deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | /* #endif */ |
| | | |
| | | /* #ifdef H5 */ |
| | | .uni-load-more__img--android-H5 { |
| | | animation: loading-android-H5-rotate 2s linear infinite; |
| | | transform-origin: center center; |
| | | } |
| | | |
| | | .uni-load-more__img--android-H5 circle { |
| | | display: inline-block; |
| | | animation: loading-android-H5-dash 1.5s ease-in-out infinite; |
| | | stroke: currentColor; |
| | | stroke-linecap: round; |
| | | } |
| | | |
| | | @keyframes loading-android-H5-rotate { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes loading-android-H5-dash { |
| | | 0% { |
| | | stroke-dasharray: 1, 200; |
| | | stroke-dashoffset: 0; |
| | | } |
| | | |
| | | 50% { |
| | | stroke-dasharray: 90, 150; |
| | | stroke-dashoffset: -40; |
| | | } |
| | | |
| | | 100% { |
| | | stroke-dasharray: 90, 150; |
| | | stroke-dashoffset: -120; |
| | | } |
| | | } |
| | | |
| | | /* #endif */ |
| | | |
| | | /* #ifndef APP-NVUE || H5 */ |
| | | .uni-load-more__img--android-MP { |
| | | position: relative; |
| | | width: 24px; |
| | | height: 24px; |
| | | transform: rotate(0deg); |
| | | animation: loading-ios 1s 0s ease infinite; |
| | | } |
| | | |
| | | .uni-load-more__img--android-MP .uni-load-more__img-icon { |
| | | position: absolute; |
| | | box-sizing: border-box; |
| | | width: 100%; |
| | | height: 100%; |
| | | border-radius: 50%; |
| | | border: solid 2px transparent; |
| | | border-top: solid 2px #777777; |
| | | transform-origin: center; |
| | | } |
| | | |
| | | .uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(1) { |
| | | animation: loading-android-MP-1 1s 0s linear infinite; |
| | | } |
| | | |
| | | .uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(2) { |
| | | animation: loading-android-MP-2 1s 0s linear infinite; |
| | | } |
| | | |
| | | .uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(3) { |
| | | animation: loading-android-MP-3 1s 0s linear infinite; |
| | | } |
| | | |
| | | @keyframes loading-android { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes loading-android-MP-1 { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 50% { |
| | | transform: rotate(90deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes loading-android-MP-2 { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 50% { |
| | | transform: rotate(180deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes loading-android-MP-3 { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 50% { |
| | | transform: rotate(270deg); |
| | | } |
| | | |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | /* #endif */ |
| | | </style> |
New file |
| | |
| | | { |
| | | "id": "uni-load-more", |
| | | "displayName": "uni-load-more 加载更多", |
| | | "version": "1.3.6", |
| | | "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。", |
| | | "keywords": [ |
| | | "uni-ui", |
| | | "uniui", |
| | | "加载更多", |
| | | "load-more" |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "" |
| | | }, |
| | | "directories": { |
| | | "example": "../../temps/example_temps" |
| | | }, |
| | | "dcloudext": { |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "无", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
| | | "type": "component-vue" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": ["uni-scss"], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y", |
| | | "alipay": "n" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | |
| | | ### LoadMore 加载更多 |
| | | > **组件名:uni-load-more** |
| | | > 代码块: `uLoadMore` |
| | | |
| | | |
| | | 用于列表中,做滚动加载使用,展示 loading 的各种状态。 |
| | | |
| | | |
| | | ### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more) |
| | | #### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
| | | |
| | | |
New file |
| | |
| | | ## 1.2.8(2024-04-26) |
| | | - 修复 在vue2下H5黑边的bug |
| | | ## 1.2.7(2024-04-26) |
| | | - 修复 在vue2手动输入后失焦导致清空数值的严重bug |
| | | ## 1.2.6(2024-02-22) |
| | | - 新增 设置宽度属性width(单位:px) |
| | | ## 1.2.5(2024-02-21) |
| | | - 修复 step步长小于1时,键盘类型为number的bug |
| | | ## 1.2.4(2024-02-02) |
| | | - 修复 加减号垂直位置偏移样式问题 |
| | | ## 1.2.3(2023-05-23) |
| | | - 更新示例工程 |
| | | ## 1.2.2(2023-05-08) |
| | | - 修复 change 事件执行顺序错误的问题 |
| | | ## 1.2.1(2021-11-22) |
| | | - 修复 vue3中某些scss变量无法找到的问题 |
| | | ## 1.2.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-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box) |
| | | ## 1.1.2(2021-11-09) |
| | | - 新增 提供组件设计资源,组件样式调整 |
| | | ## 1.1.1(2021-07-30) |
| | | - 优化 vue3下事件警告的问题 |
| | | ## 1.1.0(2021-07-13) |
| | | - 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
| | | ## 1.0.7(2021-05-12) |
| | | - 新增 组件示例地址 |
| | | ## 1.0.6(2021-04-20) |
| | | - 修复 uni-number-box 浮点数运算不精确的 bug |
| | | - 修复 uni-number-box change 事件触发不正确的 bug |
| | | - 新增 uni-number-box v-model 双向绑定 |
| | | ## 1.0.5(2021-02-05) |
| | | - 调整为uni_modules目录规范 |
| | | |
| | | ## 1.0.7(2021-02-05) |
| | | - 调整为uni_modules目录规范 |
| | | - 新增 支持 v-model |
| | | - 新增 支持 focus、blur 事件 |
| | | - 新增 支持 PC 端 |
New file |
| | |
| | | <template> |
| | | <view class="uni-numbox"> |
| | | <view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}"> |
| | | <text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }" |
| | | :style="{color}">-</text> |
| | | </view> |
| | | <input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value" |
| | | :type="step<1?'digit':'number'" v-model="inputValue" :style="{background, color, width:widthWithPx}" /> |
| | | <view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}"> |
| | | <text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }" |
| | | :style="{color}">+</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <script> |
| | | /** |
| | | * NumberBox 数字输入框 |
| | | * @description 带加减按钮的数字输入框 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=31 |
| | | * @property {Number} value 输入框当前值 |
| | | * @property {Number} min 最小值 |
| | | * @property {Number} max 最大值 |
| | | * @property {Number} step 每次点击改变的间隔大小 |
| | | * @property {String} background 背景色 |
| | | * @property {String} color 字体颜色(前景色) |
| | | * @property {Number} width 输入框宽度(单位:px) |
| | | * @property {Boolean} disabled = [true|false] 是否为禁用状态 |
| | | * @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value |
| | | * @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象 |
| | | * @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象 |
| | | */ |
| | | |
| | | export default { |
| | | name: "UniNumberBox", |
| | | emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'], |
| | | props: { |
| | | value: { |
| | | type: [Number, String], |
| | | default: 1 |
| | | }, |
| | | modelValue: { |
| | | type: [Number, String], |
| | | default: 1 |
| | | }, |
| | | min: { |
| | | type: Number, |
| | | default: 0 |
| | | }, |
| | | max: { |
| | | type: Number, |
| | | default: 100 |
| | | }, |
| | | step: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | background: { |
| | | type: String, |
| | | default: '#f5f5f5' |
| | | }, |
| | | color: { |
| | | type: String, |
| | | default: '#333' |
| | | }, |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | width: { |
| | | type: Number, |
| | | default: 40, |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | inputValue: 0 |
| | | }; |
| | | }, |
| | | watch: { |
| | | value(val) { |
| | | this.inputValue = +val; |
| | | }, |
| | | modelValue(val) { |
| | | this.inputValue = +val; |
| | | } |
| | | }, |
| | | computed: { |
| | | widthWithPx() { |
| | | return this.width + 'px'; |
| | | } |
| | | }, |
| | | created() { |
| | | if (this.value === 1) { |
| | | this.inputValue = +this.modelValue; |
| | | } |
| | | if (this.modelValue === 1) { |
| | | this.inputValue = +this.value; |
| | | } |
| | | }, |
| | | methods: { |
| | | _calcValue(type) { |
| | | if (this.disabled) { |
| | | return; |
| | | } |
| | | const scale = this._getDecimalScale(); |
| | | let value = this.inputValue * scale; |
| | | let step = this.step * scale; |
| | | if (type === "minus") { |
| | | value -= step; |
| | | if (value < (this.min * scale)) { |
| | | return; |
| | | } |
| | | if (value > (this.max * scale)) { |
| | | value = this.max * scale |
| | | } |
| | | } |
| | | |
| | | if (type === "plus") { |
| | | value += step; |
| | | if (value > (this.max * scale)) { |
| | | return; |
| | | } |
| | | if (value < (this.min * scale)) { |
| | | value = this.min * scale |
| | | } |
| | | } |
| | | |
| | | this.inputValue = (value / scale).toFixed(String(scale).length - 1); |
| | | // TODO vue2 兼容 |
| | | this.$emit("input", +this.inputValue); |
| | | // TODO vue3 兼容 |
| | | this.$emit("update:modelValue", +this.inputValue); |
| | | this.$emit("change", +this.inputValue); |
| | | }, |
| | | _getDecimalScale() { |
| | | |
| | | let scale = 1; |
| | | // 浮点型 |
| | | if (~~this.step !== this.step) { |
| | | scale = Math.pow(10, String(this.step).split(".")[1].length); |
| | | } |
| | | return scale; |
| | | }, |
| | | _onBlur(event) { |
| | | this.$emit('blur', event) |
| | | let value = event.detail.value; |
| | | if (isNaN(value)) { |
| | | this.inputValue = this.value; |
| | | return; |
| | | } |
| | | value = +value; |
| | | if (value > this.max) { |
| | | value = this.max; |
| | | } else if (value < this.min) { |
| | | value = this.min; |
| | | } |
| | | const scale = this._getDecimalScale(); |
| | | this.inputValue = value.toFixed(String(scale).length - 1); |
| | | this.$emit("input", +this.inputValue); |
| | | this.$emit("update:modelValue", +this.inputValue); |
| | | this.$emit("change", +this.inputValue); |
| | | }, |
| | | _onFocus(event) { |
| | | this.$emit('focus', event) |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | <style lang="scss"> |
| | | $box-height: 26px; |
| | | $bg: #f5f5f5; |
| | | $br: 2px; |
| | | $color: #333; |
| | | |
| | | .uni-numbox { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | } |
| | | |
| | | .uni-numbox-btns { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 0 8px; |
| | | background-color: $bg; |
| | | /* #ifdef H5 */ |
| | | cursor: pointer; |
| | | /* #endif */ |
| | | } |
| | | |
| | | .uni-numbox__value { |
| | | margin: 0 2px; |
| | | background-color: $bg; |
| | | width: 40px; |
| | | height: $box-height; |
| | | text-align: center; |
| | | font-size: 14px; |
| | | border-width: 0; |
| | | color: $color; |
| | | } |
| | | |
| | | .uni-numbox__minus { |
| | | border-top-left-radius: $br; |
| | | border-bottom-left-radius: $br; |
| | | } |
| | | |
| | | .uni-numbox__plus { |
| | | border-top-right-radius: $br; |
| | | border-bottom-right-radius: $br; |
| | | } |
| | | |
| | | .uni-numbox--text { |
| | | // fix nvue |
| | | line-height: 20px; |
| | | margin-bottom: 2px; |
| | | font-size: 20px; |
| | | font-weight: 300; |
| | | color: $color; |
| | | } |
| | | |
| | | .uni-numbox .uni-numbox--disabled { |
| | | color: #c0c0c0 !important; |
| | | /* #ifdef H5 */ |
| | | cursor: not-allowed; |
| | | /* #endif */ |
| | | } |
| | | </style> |
New file |
| | |
| | | { |
| | | "id": "uni-number-box", |
| | | "displayName": "uni-number-box 数字输入框", |
| | | "version": "1.2.8", |
| | | "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。", |
| | | "keywords": [ |
| | | "uni-ui", |
| | | "uniui", |
| | | "数字输入框" |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "" |
| | | }, |
| | | "directories": { |
| | | "example": "../../temps/example_temps" |
| | | }, |
| | | "dcloudext": { |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "无", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
| | | "type": "component-vue" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": ["uni-scss"], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y", |
| | | "alipay": "n" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | |
| | | ## NumberBox 数字输入框 |
| | | > **组件名:uni-number-box** |
| | | > 代码块: `uNumberBox` |
| | | |
| | | |
| | | 带加减按钮的数字输入框。 |
| | | |
| | | ### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box) |
| | | #### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
| | | |
| | | |
New file |
| | |
| | | ## 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 端 |
New file |
| | |
| | | // #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 |
New file |
| | |
| | | <template> |
| | | <view class="uni-popup-dialog"> |
| | | <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, |
| | | } |
| | | }, |
| | | 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) { |
| | | setVal(val) |
| | | }, |
| | | // #ifdef VUE3 |
| | | modelValue(val) { |
| | | 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; |
| | | border-radius: 11px; |
| | | 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> |
New file |
| | |
| | | <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> |
New file |
| | |
| | | <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> |
New file |
| | |
| | | { |
| | | "uni-popup.cancel": "cancel", |
| | | "uni-popup.ok": "ok", |
| | | "uni-popup.placeholder": "pleace enter", |
| | | "uni-popup.title": "Hint", |
| | | "uni-popup.shareTitle": "Share to" |
| | | } |
New file |
| | |
| | | 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 |
| | | } |
New file |
| | |
| | | { |
| | | "uni-popup.cancel": "取消", |
| | | "uni-popup.ok": "确定", |
| | | "uni-popup.placeholder": "请输入", |
| | | "uni-popup.title": "提示", |
| | | "uni-popup.shareTitle": "分享到" |
| | | } |
New file |
| | |
| | | { |
| | | "uni-popup.cancel": "取消", |
| | | "uni-popup.ok": "確定", |
| | | "uni-popup.placeholder": "請輸入", |
| | | "uni-popup.title": "提示", |
| | | "uni-popup.shareTitle": "分享到" |
| | | } |
New file |
| | |
| | | // #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 |
New file |
| | |
| | | |
| | | 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; |
| | | }, |
| | | } |
| | | } |
New file |
| | |
| | | <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> |
New file |
| | |
| | | <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> |
New file |
| | |
| | | { |
| | | "id": "uni-popup", |
| | | "displayName": "uni-popup 弹出层", |
| | | "version": "1.9.8", |
| | | "description": " Popup 组件,提供常用的弹层", |
| | | "keywords": [ |
| | | "uni-ui", |
| | | "弹出层", |
| | | "弹窗", |
| | | "popup", |
| | | "弹框" |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "" |
| | | }, |
| | | "directories": { |
| | | "example": "../../temps/example_temps" |
| | | }, |
| | | "dcloudext": { |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "无", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
| | | "type": "component-vue" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [ |
| | | "uni-scss", |
| | | "uni-transition" |
| | | ], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y", |
| | | "alipay": "n" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y", |
| | | "app-harmony": "u", |
| | | "app-uvue": "u" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | |
| | | ## Popup 弹出层 |
| | | > **组件名:uni-popup** |
| | | > 代码块: `uPopup` |
| | | > 关联组件:`uni-transition` |
| | | |
| | | |
| | | 弹出层组件,在应用中弹出一个消息提示窗口、提示框等 |
| | | |
| | | ### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup) |
| | | #### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
| | | |
| | | |
| | | |
| | | |
| | | |
New file |
| | |
| | | ## 1.0.3(2022-01-21) |
| | | - 优化 组件示例 |
| | | ## 1.0.2(2021-11-22) |
| | | - 修复 / 符号在 vue 不同版本兼容问题引起的报错问题 |
| | | ## 1.0.1(2021-11-22) |
| | | - 修复 vue3中scss语法兼容问题 |
| | | ## 1.0.0(2021-11-18) |
| | | - init |
New file |
| | |
| | | @import './styles/index.scss'; |
New file |
| | |
| | | { |
| | | "id": "uni-scss", |
| | | "displayName": "uni-scss 辅助样式", |
| | | "version": "1.0.3", |
| | | "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。", |
| | | "keywords": [ |
| | | "uni-scss", |
| | | "uni-ui", |
| | | "辅助样式" |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "^3.1.0" |
| | | }, |
| | | "dcloudext": { |
| | | "category": [ |
| | | "JS SDK", |
| | | "通用 SDK" |
| | | ], |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "无", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": [], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "u" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | }, |
| | | "快应用": { |
| | | "华为": "n", |
| | | "联盟": "n" |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | `uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。 |
| | | |
| | | ### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass) |
| | | #### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
New file |
| | |
| | | @import './setting/_variables.scss'; |
| | | @import './setting/_border.scss'; |
| | | @import './setting/_color.scss'; |
| | | @import './setting/_space.scss'; |
| | | @import './setting/_radius.scss'; |
| | | @import './setting/_text.scss'; |
| | | @import './setting/_styles.scss'; |
New file |
| | |
| | | .uni-border { |
| | | border: 1px $uni-border-1 solid; |
| | | } |
New file |
| | |
| | | |
| | | // TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐 |
| | | // @mixin get-styles($k,$c) { |
| | | // @if $k == size or $k == weight{ |
| | | // font-#{$k}:#{$c} |
| | | // }@else{ |
| | | // #{$k}:#{$c} |
| | | // } |
| | | // } |
| | | $uni-ui-color:( |
| | | // 主色 |
| | | primary: $uni-primary, |
| | | primary-disable: $uni-primary-disable, |
| | | primary-light: $uni-primary-light, |
| | | // 辅助色 |
| | | success: $uni-success, |
| | | success-disable: $uni-success-disable, |
| | | success-light: $uni-success-light, |
| | | warning: $uni-warning, |
| | | warning-disable: $uni-warning-disable, |
| | | warning-light: $uni-warning-light, |
| | | error: $uni-error, |
| | | error-disable: $uni-error-disable, |
| | | error-light: $uni-error-light, |
| | | info: $uni-info, |
| | | info-disable: $uni-info-disable, |
| | | info-light: $uni-info-light, |
| | | // 中性色 |
| | | main-color: $uni-main-color, |
| | | base-color: $uni-base-color, |
| | | secondary-color: $uni-secondary-color, |
| | | extra-color: $uni-extra-color, |
| | | // 背景色 |
| | | bg-color: $uni-bg-color, |
| | | // 边框颜色 |
| | | border-1: $uni-border-1, |
| | | border-2: $uni-border-2, |
| | | border-3: $uni-border-3, |
| | | border-4: $uni-border-4, |
| | | // 黑色 |
| | | black:$uni-black, |
| | | // 白色 |
| | | white:$uni-white, |
| | | // 透明 |
| | | transparent:$uni-transparent |
| | | ) !default; |
| | | @each $key, $child in $uni-ui-color { |
| | | .uni-#{"" + $key} { |
| | | color: $child; |
| | | } |
| | | .uni-#{"" + $key}-bg { |
| | | background-color: $child; |
| | | } |
| | | } |
| | | .uni-shadow-sm { |
| | | box-shadow: $uni-shadow-sm; |
| | | } |
| | | .uni-shadow-base { |
| | | box-shadow: $uni-shadow-base; |
| | | } |
| | | .uni-shadow-lg { |
| | | box-shadow: $uni-shadow-lg; |
| | | } |
| | | .uni-mask { |
| | | background-color:$uni-mask; |
| | | } |
New file |
| | |
| | | @mixin radius($r,$d:null ,$important: false){ |
| | | $radius-value:map-get($uni-radius, $r) if($important, !important, null); |
| | | // Key exists within the $uni-radius variable |
| | | @if (map-has-key($uni-radius, $r) and $d){ |
| | | @if $d == t { |
| | | border-top-left-radius:$radius-value; |
| | | border-top-right-radius:$radius-value; |
| | | }@else if $d == r { |
| | | border-top-right-radius:$radius-value; |
| | | border-bottom-right-radius:$radius-value; |
| | | }@else if $d == b { |
| | | border-bottom-left-radius:$radius-value; |
| | | border-bottom-right-radius:$radius-value; |
| | | }@else if $d == l { |
| | | border-top-left-radius:$radius-value; |
| | | border-bottom-left-radius:$radius-value; |
| | | }@else if $d == tl { |
| | | border-top-left-radius:$radius-value; |
| | | }@else if $d == tr { |
| | | border-top-right-radius:$radius-value; |
| | | }@else if $d == br { |
| | | border-bottom-right-radius:$radius-value; |
| | | }@else if $d == bl { |
| | | border-bottom-left-radius:$radius-value; |
| | | } |
| | | }@else{ |
| | | border-radius:$radius-value; |
| | | } |
| | | } |
| | | |
| | | @each $key, $child in $uni-radius { |
| | | @if($key){ |
| | | .uni-radius-#{"" + $key} { |
| | | @include radius($key) |
| | | } |
| | | }@else{ |
| | | .uni-radius { |
| | | @include radius($key) |
| | | } |
| | | } |
| | | } |
| | | |
| | | @each $direction in t, r, b, l,tl, tr, br, bl { |
| | | @each $key, $child in $uni-radius { |
| | | @if($key){ |
| | | .uni-radius-#{"" + $direction}-#{"" + $key} { |
| | | @include radius($key,$direction,false) |
| | | } |
| | | }@else{ |
| | | .uni-radius-#{$direction} { |
| | | @include radius($key,$direction,false) |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | @mixin fn($space,$direction,$size,$n) { |
| | | @if $n { |
| | | #{$space}-#{$direction}: #{$size*$uni-space-root}px |
| | | } @else { |
| | | #{$space}-#{$direction}: #{-$size*$uni-space-root}px |
| | | } |
| | | } |
| | | @mixin get-styles($direction,$i,$space,$n){ |
| | | @if $direction == t { |
| | | @include fn($space, top,$i,$n); |
| | | } |
| | | @if $direction == r { |
| | | @include fn($space, right,$i,$n); |
| | | } |
| | | @if $direction == b { |
| | | @include fn($space, bottom,$i,$n); |
| | | } |
| | | @if $direction == l { |
| | | @include fn($space, left,$i,$n); |
| | | } |
| | | @if $direction == x { |
| | | @include fn($space, left,$i,$n); |
| | | @include fn($space, right,$i,$n); |
| | | } |
| | | @if $direction == y { |
| | | @include fn($space, top,$i,$n); |
| | | @include fn($space, bottom,$i,$n); |
| | | } |
| | | @if $direction == a { |
| | | @if $n { |
| | | #{$space}:#{$i*$uni-space-root}px; |
| | | } @else { |
| | | #{$space}:#{-$i*$uni-space-root}px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | @each $orientation in m,p { |
| | | $space: margin; |
| | | @if $orientation == m { |
| | | $space: margin; |
| | | } @else { |
| | | $space: padding; |
| | | } |
| | | @for $i from 0 through 16 { |
| | | @each $direction in t, r, b, l, x, y, a { |
| | | .uni-#{$orientation}#{$direction}-#{$i} { |
| | | @include get-styles($direction,$i,$space,true); |
| | | } |
| | | .uni-#{$orientation}#{$direction}-n#{$i} { |
| | | @include get-styles($direction,$i,$space,false); |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /* #ifndef APP-NVUE */ |
| | | |
| | | $-color-white:#fff; |
| | | $-color-black:#000; |
| | | @mixin base-style($color) { |
| | | color: #fff; |
| | | background-color: $color; |
| | | border-color: mix($-color-black, $color, 8%); |
| | | &:not([hover-class]):active { |
| | | background: mix($-color-black, $color, 10%); |
| | | border-color: mix($-color-black, $color, 20%); |
| | | color: $-color-white; |
| | | outline: none; |
| | | } |
| | | } |
| | | @mixin is-color($color) { |
| | | @include base-style($color); |
| | | &[loading] { |
| | | @include base-style($color); |
| | | &::before { |
| | | margin-right:5px; |
| | | } |
| | | } |
| | | &[disabled] { |
| | | &, |
| | | &[loading], |
| | | &:not([hover-class]):active { |
| | | color: $-color-white; |
| | | border-color: mix(darken($color,10%), $-color-white); |
| | | background-color: mix($color, $-color-white); |
| | | } |
| | | } |
| | | |
| | | } |
| | | @mixin base-plain-style($color) { |
| | | color:$color; |
| | | background-color: mix($-color-white, $color, 90%); |
| | | border-color: mix($-color-white, $color, 70%); |
| | | &:not([hover-class]):active { |
| | | background: mix($-color-white, $color, 80%); |
| | | color: $color; |
| | | outline: none; |
| | | border-color: mix($-color-white, $color, 50%); |
| | | } |
| | | } |
| | | @mixin is-plain($color){ |
| | | &[plain] { |
| | | @include base-plain-style($color); |
| | | &[loading] { |
| | | @include base-plain-style($color); |
| | | &::before { |
| | | margin-right:5px; |
| | | } |
| | | } |
| | | &[disabled] { |
| | | &, |
| | | &:active { |
| | | color: mix($-color-white, $color, 40%); |
| | | background-color: mix($-color-white, $color, 90%); |
| | | border-color: mix($-color-white, $color, 80%); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | .uni-btn { |
| | | margin: 5px; |
| | | color: #393939; |
| | | border:1px solid #ccc; |
| | | font-size: 16px; |
| | | font-weight: 200; |
| | | background-color: #F9F9F9; |
| | | // TODO 暂时处理边框隐藏一边的问题 |
| | | overflow: visible; |
| | | &::after{ |
| | | border: none; |
| | | } |
| | | |
| | | &:not([type]),&[type=default] { |
| | | color: #999; |
| | | &[loading] { |
| | | background: none; |
| | | &::before { |
| | | margin-right:5px; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | &[disabled]{ |
| | | color: mix($-color-white, #999, 60%); |
| | | &, |
| | | &[loading], |
| | | &:active { |
| | | color: mix($-color-white, #999, 60%); |
| | | background-color: mix($-color-white,$-color-black , 98%); |
| | | border-color: mix($-color-white, #999, 85%); |
| | | } |
| | | } |
| | | |
| | | &[plain] { |
| | | color: #999; |
| | | background: none; |
| | | border-color: $uni-border-1; |
| | | &:not([hover-class]):active { |
| | | background: none; |
| | | color: mix($-color-white, $-color-black, 80%); |
| | | border-color: mix($-color-white, $-color-black, 90%); |
| | | outline: none; |
| | | } |
| | | &[disabled]{ |
| | | &, |
| | | &[loading], |
| | | &:active { |
| | | background: none; |
| | | color: mix($-color-white, #999, 60%); |
| | | border-color: mix($-color-white, #999, 85%); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | &:not([hover-class]):active { |
| | | color: mix($-color-white, $-color-black, 50%); |
| | | } |
| | | |
| | | &[size=mini] { |
| | | font-size: 16px; |
| | | font-weight: 200; |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | |
| | | |
| | | &.uni-btn-small { |
| | | font-size: 14px; |
| | | } |
| | | &.uni-btn-mini { |
| | | font-size: 12px; |
| | | } |
| | | |
| | | &.uni-btn-radius { |
| | | border-radius: 999px; |
| | | } |
| | | &[type=primary] { |
| | | @include is-color($uni-primary); |
| | | @include is-plain($uni-primary) |
| | | } |
| | | &[type=success] { |
| | | @include is-color($uni-success); |
| | | @include is-plain($uni-success) |
| | | } |
| | | &[type=error] { |
| | | @include is-color($uni-error); |
| | | @include is-plain($uni-error) |
| | | } |
| | | &[type=warning] { |
| | | @include is-color($uni-warning); |
| | | @include is-plain($uni-warning) |
| | | } |
| | | &[type=info] { |
| | | @include is-color($uni-info); |
| | | @include is-plain($uni-info) |
| | | } |
| | | } |
| | | /* #endif */ |
New file |
| | |
| | | @mixin get-styles($k,$c) { |
| | | @if $k == size or $k == weight{ |
| | | font-#{$k}:#{$c} |
| | | }@else{ |
| | | #{$k}:#{$c} |
| | | } |
| | | } |
| | | |
| | | @each $key, $child in $uni-headings { |
| | | /* #ifndef APP-NVUE */ |
| | | .uni-#{$key} { |
| | | @each $k, $c in $child { |
| | | @include get-styles($k,$c) |
| | | } |
| | | } |
| | | /* #endif */ |
| | | /* #ifdef APP-NVUE */ |
| | | .container .uni-#{$key} { |
| | | @each $k, $c in $child { |
| | | @include get-styles($k,$c) |
| | | } |
| | | } |
| | | /* #endif */ |
| | | } |
New file |
| | |
| | | // @use "sass:math"; |
| | | @import '../tools/functions.scss'; |
| | | // 间距基础倍数 |
| | | $uni-space-root: 2 !default; |
| | | // 边框半径默认值 |
| | | $uni-radius-root:5px !default; |
| | | $uni-radius: () !default; |
| | | // 边框半径断点 |
| | | $uni-radius: map-deep-merge( |
| | | ( |
| | | 0: 0, |
| | | // TODO 当前版本暂时不支持 sm 属性 |
| | | // 'sm': math.div($uni-radius-root, 2), |
| | | null: $uni-radius-root, |
| | | 'lg': $uni-radius-root * 2, |
| | | 'xl': $uni-radius-root * 6, |
| | | 'pill': 9999px, |
| | | 'circle': 50% |
| | | ), |
| | | $uni-radius |
| | | ); |
| | | // 字体家族 |
| | | $body-font-family: 'Roboto', sans-serif !default; |
| | | // 文本 |
| | | $heading-font-family: $body-font-family !default; |
| | | $uni-headings: () !default; |
| | | $letterSpacing: -0.01562em; |
| | | $uni-headings: map-deep-merge( |
| | | ( |
| | | 'h1': ( |
| | | size: 32px, |
| | | weight: 300, |
| | | line-height: 50px, |
| | | // letter-spacing:-0.01562em |
| | | ), |
| | | 'h2': ( |
| | | size: 28px, |
| | | weight: 300, |
| | | line-height: 40px, |
| | | // letter-spacing: -0.00833em |
| | | ), |
| | | 'h3': ( |
| | | size: 24px, |
| | | weight: 400, |
| | | line-height: 32px, |
| | | // letter-spacing: normal |
| | | ), |
| | | 'h4': ( |
| | | size: 20px, |
| | | weight: 400, |
| | | line-height: 30px, |
| | | // letter-spacing: 0.00735em |
| | | ), |
| | | 'h5': ( |
| | | size: 16px, |
| | | weight: 400, |
| | | line-height: 24px, |
| | | // letter-spacing: normal |
| | | ), |
| | | 'h6': ( |
| | | size: 14px, |
| | | weight: 500, |
| | | line-height: 18px, |
| | | // letter-spacing: 0.0125em |
| | | ), |
| | | 'subtitle': ( |
| | | size: 12px, |
| | | weight: 400, |
| | | line-height: 20px, |
| | | // letter-spacing: 0.00937em |
| | | ), |
| | | 'body': ( |
| | | font-size: 14px, |
| | | font-weight: 400, |
| | | line-height: 22px, |
| | | // letter-spacing: 0.03125em |
| | | ), |
| | | 'caption': ( |
| | | 'size': 12px, |
| | | 'weight': 400, |
| | | 'line-height': 20px, |
| | | // 'letter-spacing': 0.03333em, |
| | | // 'text-transform': false |
| | | ) |
| | | ), |
| | | $uni-headings |
| | | ); |
| | | |
| | | |
| | | |
| | | // 主色 |
| | | $uni-primary: #2979ff !default; |
| | | $uni-primary-disable:lighten($uni-primary,20%) !default; |
| | | $uni-primary-light: lighten($uni-primary,25%) !default; |
| | | |
| | | // 辅助色 |
| | | // 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 |
| | | $uni-success: #18bc37 !default; |
| | | $uni-success-disable:lighten($uni-success,20%) !default; |
| | | $uni-success-light: lighten($uni-success,25%) !default; |
| | | |
| | | $uni-warning: #f3a73f !default; |
| | | $uni-warning-disable:lighten($uni-warning,20%) !default; |
| | | $uni-warning-light: lighten($uni-warning,25%) !default; |
| | | |
| | | $uni-error: #e43d33 !default; |
| | | $uni-error-disable:lighten($uni-error,20%) !default; |
| | | $uni-error-light: lighten($uni-error,25%) !default; |
| | | |
| | | $uni-info: #8f939c !default; |
| | | $uni-info-disable:lighten($uni-info,20%) !default; |
| | | $uni-info-light: lighten($uni-info,25%) !default; |
| | | |
| | | // 中性色 |
| | | // 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 |
| | | $uni-main-color: #3a3a3a !default; // 主要文字 |
| | | $uni-base-color: #6a6a6a !default; // 常规文字 |
| | | $uni-secondary-color: #909399 !default; // 次要文字 |
| | | $uni-extra-color: #c7c7c7 !default; // 辅助说明 |
| | | |
| | | // 边框颜色 |
| | | $uni-border-1: #F0F0F0 !default; |
| | | $uni-border-2: #EDEDED !default; |
| | | $uni-border-3: #DCDCDC !default; |
| | | $uni-border-4: #B9B9B9 !default; |
| | | |
| | | // 常规色 |
| | | $uni-black: #000000 !default; |
| | | $uni-white: #ffffff !default; |
| | | $uni-transparent: rgba($color: #000000, $alpha: 0) !default; |
| | | |
| | | // 背景色 |
| | | $uni-bg-color: #f7f7f7 !default; |
| | | |
| | | /* 水平间距 */ |
| | | $uni-spacing-sm: 8px !default; |
| | | $uni-spacing-base: 15px !default; |
| | | $uni-spacing-lg: 30px !default; |
| | | |
| | | // 阴影 |
| | | $uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default; |
| | | $uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default; |
| | | $uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default; |
| | | |
| | | // 蒙版 |
| | | $uni-mask: rgba($color: #000000, $alpha: 0.4) !default; |
New file |
| | |
| | | // 合并 map |
| | | @function map-deep-merge($parent-map, $child-map){ |
| | | $result: $parent-map; |
| | | @each $key, $child in $child-map { |
| | | $parent-has-key: map-has-key($result, $key); |
| | | $parent-value: map-get($result, $key); |
| | | $parent-type: type-of($parent-value); |
| | | $child-type: type-of($child); |
| | | $parent-is-map: $parent-type == map; |
| | | $child-is-map: $child-type == map; |
| | | |
| | | @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){ |
| | | $result: map-merge($result, ( $key: $child )); |
| | | }@else { |
| | | $result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) )); |
| | | } |
| | | } |
| | | @return $result; |
| | | }; |
New file |
| | |
| | | // 间距基础倍数 |
| | | $uni-space-root: 2; |
| | | // 边框半径默认值 |
| | | $uni-radius-root:5px; |
| | | // 主色 |
| | | $uni-primary: #2979ff; |
| | | // 辅助色 |
| | | $uni-success: #4cd964; |
| | | // 警告色 |
| | | $uni-warning: #f0ad4e; |
| | | // 错误色 |
| | | $uni-error: #dd524d; |
| | | // 描述色 |
| | | $uni-info: #909399; |
| | | // 中性色 |
| | | $uni-main-color: #303133; |
| | | $uni-base-color: #606266; |
| | | $uni-secondary-color: #909399; |
| | | $uni-extra-color: #C0C4CC; |
| | | // 背景色 |
| | | $uni-bg-color: #f5f5f5; |
| | | // 边框颜色 |
| | | $uni-border-1: #DCDFE6; |
| | | $uni-border-2: #E4E7ED; |
| | | $uni-border-3: #EBEEF5; |
| | | $uni-border-4: #F2F6FC; |
| | | |
| | | // 常规色 |
| | | $uni-black: #000000; |
| | | $uni-white: #ffffff; |
| | | $uni-transparent: rgba($color: #000000, $alpha: 0); |
New file |
| | |
| | | @import './styles/setting/_variables.scss'; |
| | | // 间距基础倍数 |
| | | $uni-space-root: 2; |
| | | // 边框半径默认值 |
| | | $uni-radius-root:5px; |
| | | |
| | | // 主色 |
| | | $uni-primary: #2979ff; |
| | | $uni-primary-disable:mix(#fff,$uni-primary,50%); |
| | | $uni-primary-light: mix(#fff,$uni-primary,80%); |
| | | |
| | | // 辅助色 |
| | | // 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。 |
| | | $uni-success: #18bc37; |
| | | $uni-success-disable:mix(#fff,$uni-success,50%); |
| | | $uni-success-light: mix(#fff,$uni-success,80%); |
| | | |
| | | $uni-warning: #f3a73f; |
| | | $uni-warning-disable:mix(#fff,$uni-warning,50%); |
| | | $uni-warning-light: mix(#fff,$uni-warning,80%); |
| | | |
| | | $uni-error: #e43d33; |
| | | $uni-error-disable:mix(#fff,$uni-error,50%); |
| | | $uni-error-light: mix(#fff,$uni-error,80%); |
| | | |
| | | $uni-info: #8f939c; |
| | | $uni-info-disable:mix(#fff,$uni-info,50%); |
| | | $uni-info-light: mix(#fff,$uni-info,80%); |
| | | |
| | | // 中性色 |
| | | // 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。 |
| | | $uni-main-color: #3a3a3a; // 主要文字 |
| | | $uni-base-color: #6a6a6a; // 常规文字 |
| | | $uni-secondary-color: #909399; // 次要文字 |
| | | $uni-extra-color: #c7c7c7; // 辅助说明 |
| | | |
| | | // 边框颜色 |
| | | $uni-border-1: #F0F0F0; |
| | | $uni-border-2: #EDEDED; |
| | | $uni-border-3: #DCDCDC; |
| | | $uni-border-4: #B9B9B9; |
| | | |
| | | // 常规色 |
| | | $uni-black: #000000; |
| | | $uni-white: #ffffff; |
| | | $uni-transparent: rgba($color: #000000, $alpha: 0); |
| | | |
| | | // 背景色 |
| | | $uni-bg-color: #f7f7f7; |
| | | |
| | | /* 水平间距 */ |
| | | $uni-spacing-sm: 8px; |
| | | $uni-spacing-base: 15px; |
| | | $uni-spacing-lg: 30px; |
| | | |
| | | // 阴影 |
| | | $uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5); |
| | | $uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2); |
| | | $uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5); |
| | | |
| | | // 蒙版 |
| | | $uni-mask: rgba($color: #000000, $alpha: 0.4); |
New file |
| | |
| | | ## 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 目录规范 |
New file |
| | |
| | | // 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) |
| | | } |
New file |
| | |
| | | <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: 1, |
| | | 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 |
| | | for (let i in obj) { |
| | | try { |
| | | if(typeof obj[i] === 'object'){ |
| | | this.animation[i](...obj[i]) |
| | | }else{ |
| | | this.animation[i](obj[i]) |
| | | } |
| | | } catch (e) { |
| | | console.error(`方法 ${i} 不存在`) |
| | | } |
| | | } |
| | | this.animation.step(config) |
| | | return this |
| | | }, |
| | | /** |
| | | * ref 触发 执行动画 |
| | | */ |
| | | run(fn) { |
| | | if (!this.animation) return |
| | | this.animation.run(fn) |
| | | }, |
| | | // 开始过度动画 |
| | | open() { |
| | | clearTimeout(this.timer) |
| | | this.transform = '' |
| | | this.isShow = true |
| | | let { opacity, transform } = this.styleInit(false) |
| | | if (typeof opacity !== 'undefined') { |
| | | this.opacity = opacity |
| | | } |
| | | this.transform = transform |
| | | // 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常 |
| | | this.$nextTick(() => { |
| | | // TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器 |
| | | this.timer = setTimeout(() => { |
| | | this.animation = createAnimation(this.config, this) |
| | | this.tranfromInit(false).step() |
| | | this.animation.run(() => { |
| | | this.transform = '' |
| | | this.opacity = opacity || 1 |
| | | }) |
| | | this.$emit('change', { |
| | | detail: this.isShow |
| | | }) |
| | | }, 20) |
| | | }) |
| | | }, |
| | | // 关闭过度动画 |
| | | 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: '' |
| | | } |
| | | let buildStyle = (type, mode) => { |
| | | if (mode === 'fade') { |
| | | styles.opacity = this.animationType(type)[mode] |
| | | } else { |
| | | styles.transform += this.animationType(type)[mode] + ' ' |
| | | } |
| | | } |
| | | 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 ? 0 : 1, |
| | | '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> |
New file |
| | |
| | | { |
| | | "id": "uni-transition", |
| | | "displayName": "uni-transition 过渡动画", |
| | | "version": "1.3.4", |
| | | "description": "元素的简单过渡动画", |
| | | "keywords": [ |
| | | "uni-ui", |
| | | "uniui", |
| | | "动画", |
| | | "过渡", |
| | | "过渡动画" |
| | | ], |
| | | "repository": "https://github.com/dcloudio/uni-ui", |
| | | "engines": { |
| | | "HBuilderX": "" |
| | | }, |
| | | "directories": { |
| | | "example": "../../temps/example_temps" |
| | | }, |
| | | "dcloudext": { |
| | | "sale": { |
| | | "regular": { |
| | | "price": "0.00" |
| | | }, |
| | | "sourcecode": { |
| | | "price": "0.00" |
| | | } |
| | | }, |
| | | "contact": { |
| | | "qq": "" |
| | | }, |
| | | "declaration": { |
| | | "ads": "无", |
| | | "data": "无", |
| | | "permissions": "无" |
| | | }, |
| | | "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
| | | "type": "component-vue" |
| | | }, |
| | | "uni_modules": { |
| | | "dependencies": ["uni-scss"], |
| | | "encrypt": [], |
| | | "platforms": { |
| | | "cloud": { |
| | | "tcb": "y", |
| | | "aliyun": "y", |
| | | "alipay": "n" |
| | | }, |
| | | "client": { |
| | | "App": { |
| | | "app-vue": "y", |
| | | "app-nvue": "y", |
| | | "app-harmony": "u", |
| | | "app-uvue": "n" |
| | | }, |
| | | "H5-mobile": { |
| | | "Safari": "y", |
| | | "Android Browser": "y", |
| | | "微信浏览器(Android)": "y", |
| | | "QQ浏览器(Android)": "y" |
| | | }, |
| | | "H5-pc": { |
| | | "Chrome": "y", |
| | | "IE": "y", |
| | | "Edge": "y", |
| | | "Firefox": "y", |
| | | "Safari": "y" |
| | | }, |
| | | "小程序": { |
| | | "微信": "y", |
| | | "阿里": "y", |
| | | "百度": "y", |
| | | "字节跳动": "y", |
| | | "QQ": "y" |
| | | }, |
| | | "快应用": { |
| | | "华为": "u", |
| | | "联盟": "u" |
| | | }, |
| | | "Vue": { |
| | | "vue2": "y", |
| | | "vue3": "y" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | |
| | | |
| | | ## Transition 过渡动画 |
| | | > **组件名:uni-transition** |
| | | > 代码块: `uTransition` |
| | | |
| | | |
| | | 元素过渡动画 |
| | | |
| | | ### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition) |
| | | #### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |