8 files added
3 files modified
| | |
| | | <style> |
| | | /*每个页面公共css */ |
| | | @import url("./common/styles/index"); |
| | | @import url("//at.alicdn.com/t/font_2263696_mnf8362pruj.css"); |
| | | @import url("//at.alicdn.com/t/font_2263696_85i6dla763h.css"); |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <view :class="isShow?'dropdown-wrap-open':'dropdown-wrap-close'"> |
| | | <view class="mask" @touchmove.stop.prevent="moveHandle" @click.stop="hide"> |
| | | <view v-if="type===1" class="dropdown-wrap-con"> |
| | | <view v-for="(item, index) in list" class="flex justify-between"> |
| | | <text :class="index===0?'blue':''">{{item}}</text> |
| | | <text v-if="index===0" class="iconfont icongouxuan blue font-18"></text> |
| | | </view> |
| | | </view> |
| | | <view v-else class="all-screen-wrap"> |
| | | <view v-for="(item, index) in list" class="all-screen"> |
| | | <text class="title">{{item.title}}</text> |
| | | <view> |
| | | <text v-for="op in item.list" class="name">{{op.title}}</text> |
| | | </view> |
| | | </view> |
| | | <view class="btn-group"> |
| | | <text class="btn">重置</text> |
| | | <text class="btn btn-blue">完成</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | props:{ |
| | | list: { |
| | | default: [] |
| | | }, |
| | | type: { |
| | | default: 1 //0表示全部筛选 |
| | | } |
| | | }, |
| | | data(){ |
| | | return { |
| | | isShow: false |
| | | } |
| | | }, |
| | | created() { |
| | | |
| | | }, |
| | | methods:{ |
| | | moveHandle(){ |
| | | |
| | | }, |
| | | show(){ |
| | | this.isShow = true; |
| | | }, |
| | | hide(){ |
| | | this.isShow = false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .mask{ |
| | | position: fixed; |
| | | left: 0; |
| | | right: 0; |
| | | height: 100%; |
| | | background: rgba(0,0,0,0.4); |
| | | transition: all 0.2s; |
| | | } |
| | | .dropdown-wrap-close .mask{ |
| | | display: none; |
| | | } |
| | | .dropdown-wrap-open .mask{ |
| | | display: block; |
| | | } |
| | | .dropdown-wrap-con{ |
| | | background: #FFFFFF; |
| | | padding: 10px 10px; |
| | | font-size: 14px; |
| | | line-height: 32px; |
| | | color: #999999; |
| | | } |
| | | .all-screen-wrap{ |
| | | background: #FFFFFF; |
| | | } |
| | | .all-screen{ |
| | | padding: 5px 10px 0; |
| | | } |
| | | .all-screen .title{ |
| | | display: block; |
| | | font-size: 14px; |
| | | padding: 10px 0; |
| | | color: #666666; |
| | | } |
| | | .all-screen .name{ |
| | | font-size: 12px; |
| | | background: #F2f2f2; |
| | | color: #666666; |
| | | padding: 5px 10px; |
| | | min-width: 56px; |
| | | text-align: center; |
| | | display: inline-block; |
| | | margin-right: 10px; |
| | | border-radius: 2px; |
| | | margin-bottom: 5px; |
| | | } |
| | | .btn-group{ |
| | | display: flex; |
| | | border-top: 1px solid #EDEAF4; |
| | | margin-top: 20px; |
| | | } |
| | | .btn-group .btn{ |
| | | flex: 1; |
| | | line-height: 44px; |
| | | text-align: center; |
| | | font-size: 15px; |
| | | color: #666666; |
| | | } |
| | | .btn-group .btn-blue{ |
| | | background: #518EFF; |
| | | color: #FFFFFF; |
| | | } |
| | | </style> |
New file |
| | |
| | | export default { |
| | | created() { |
| | | if (this.type === 'message') { |
| | | // 不显示遮罩 |
| | | this.maskShow = false |
| | | // 获取子组件对象 |
| | | this.childrenMsg = null |
| | | } |
| | | }, |
| | | methods: { |
| | | customOpen() { |
| | | if (this.childrenMsg) { |
| | | this.childrenMsg.open() |
| | | } |
| | | }, |
| | | customClose() { |
| | | if (this.childrenMsg) { |
| | | this.childrenMsg.close() |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import message from './message.js'; |
| | | // 定义 type 类型:弹出类型:top/bottom/center |
| | | const config = { |
| | | // 顶部弹出 |
| | | top:'top', |
| | | // 底部弹出 |
| | | bottom:'bottom', |
| | | // 居中弹出 |
| | | center:'center', |
| | | // 消息提示 |
| | | message:'top', |
| | | // 对话框 |
| | | dialog:'center', |
| | | // 分享 |
| | | share:'bottom', |
| | | } |
| | | |
| | | export default { |
| | | data(){ |
| | | return { |
| | | config:config |
| | | } |
| | | }, |
| | | mixins: [message], |
| | | } |
New file |
| | |
| | | <template> |
| | | <view class="uni-popup-dialog"> |
| | | <view class="uni-dialog-title"> |
| | | <text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{title}}</text> |
| | | </view> |
| | | <view class="uni-dialog-content"> |
| | | <text class="uni-dialog-content-text" v-if="mode === 'base'">{{content}}</text> |
| | | <input v-else class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholder" :focus="focus" > |
| | | </view> |
| | | <view class="uni-dialog-button-group"> |
| | | <view class="uni-dialog-button" @click="close"> |
| | | <text class="uni-dialog-button-text">取消</text> |
| | | </view> |
| | | <view class="uni-dialog-button uni-border-left" @click="onOk"> |
| | | <text class="uni-dialog-button-text uni-button-color">确定</text> |
| | | </view> |
| | | </view> |
| | | |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | /** |
| | | * PopUp 弹出层-对话框样式 |
| | | * @description 弹出层-对话框样式 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=329 |
| | | * @property {String} value input 模式下的默认值 |
| | | * @property {String} placeholder input 模式下输入提示 |
| | | * @property {String} type = [success|warning|info|error] 主题样式 |
| | | * @value success 成功 |
| | | * @value warning 提示 |
| | | * @value info 消息 |
| | | * @value error 错误 |
| | | * @property {String} mode = [base|input] 模式、 |
| | | * @value base 基础对话框 |
| | | * @value input 可输入对话框 |
| | | * @property {String} content 对话框内容 |
| | | * @property {Boolean} beforeClose 是否拦截取消事件 |
| | | * @event {Function} confirm 点击确认按钮触发 |
| | | * @event {Function} close 点击取消按钮触发 |
| | | */ |
| | | |
| | | export default { |
| | | name: "uniPopupDialog", |
| | | props: { |
| | | value: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | placeholder: { |
| | | type: [String, Number], |
| | | default: '请输入内容' |
| | | }, |
| | | /** |
| | | * 对话框主题 success/warning/info/error 默认 success |
| | | */ |
| | | type: { |
| | | type: String, |
| | | default: 'error' |
| | | }, |
| | | /** |
| | | * 对话框模式 base/input |
| | | */ |
| | | mode: { |
| | | type: String, |
| | | default: 'base' |
| | | }, |
| | | /** |
| | | * 对话框标题 |
| | | */ |
| | | title: { |
| | | type: String, |
| | | default: '提示' |
| | | }, |
| | | /** |
| | | * 对话框内容 |
| | | */ |
| | | content: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | /** |
| | | * 拦截取消事件 ,如果拦截取消事件,必须监听close事件,执行 done() |
| | | */ |
| | | beforeClose: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogType: 'error', |
| | | focus: false, |
| | | val: "" |
| | | } |
| | | }, |
| | | inject: ['popup'], |
| | | watch: { |
| | | type(val) { |
| | | this.dialogType = val |
| | | }, |
| | | mode(val) { |
| | | if (val === 'input') { |
| | | this.dialogType = 'info' |
| | | } |
| | | }, |
| | | value(val) { |
| | | this.val = val |
| | | } |
| | | }, |
| | | created() { |
| | | // 对话框遮罩不可点击 |
| | | this.popup.mkclick = false |
| | | if (this.mode === 'input') { |
| | | this.dialogType = 'info' |
| | | this.val = this.value |
| | | } else { |
| | | this.dialogType = this.type |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.focus = true |
| | | }, |
| | | methods: { |
| | | /** |
| | | * 点击确认按钮 |
| | | */ |
| | | onOk() { |
| | | this.$emit('confirm', () => { |
| | | this.popup.close() |
| | | if (this.mode === 'input') this.val = this.value |
| | | }, this.mode === 'input' ? this.val : '') |
| | | }, |
| | | /** |
| | | * 点击取消按钮 |
| | | */ |
| | | close() { |
| | | if (this.beforeClose) { |
| | | this.$emit('close', () => { |
| | | this.popup.close() |
| | | }) |
| | | return |
| | | } |
| | | this.popup.close() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .uni-popup-dialog { |
| | | width: 300px; |
| | | border-radius: 15px; |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .uni-dialog-title { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | justify-content: center; |
| | | padding-top: 15px; |
| | | padding-bottom: 5px; |
| | | } |
| | | |
| | | .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: 5px 15px 15px 15px; |
| | | } |
| | | |
| | | .uni-dialog-content-text { |
| | | font-size: 14px; |
| | | color: #6e6e6e; |
| | | } |
| | | |
| | | .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: 14px; |
| | | } |
| | | |
| | | .uni-button-color { |
| | | color: $uni-color-primary; |
| | | } |
| | | |
| | | .uni-dialog-input { |
| | | flex: 1; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .uni-popup__success { |
| | | color: $uni-color-success; |
| | | } |
| | | |
| | | .uni-popup__warn { |
| | | color: $uni-color-warning; |
| | | } |
| | | |
| | | .uni-popup__error { |
| | | color: $uni-color-error; |
| | | } |
| | | |
| | | .uni-popup__info { |
| | | color: #909399; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <view class="uni-popup-message" :class="'uni-popup__'+[type]"> |
| | | <text class="uni-popup-message-text" :class="'uni-popup__'+[type]+'-text'">{{message}}</text> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | /** |
| | | * 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', |
| | | props: { |
| | | /** |
| | | * 主题 success/warning/info/error 默认 success |
| | | */ |
| | | type: { |
| | | type: String, |
| | | default: 'success' |
| | | }, |
| | | /** |
| | | * 消息文字 |
| | | */ |
| | | message: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | /** |
| | | * 显示时间,设置为 0 则不会自动关闭 |
| | | */ |
| | | duration: { |
| | | type: Number, |
| | | default: 3000 |
| | | } |
| | | }, |
| | | inject: ['popup'], |
| | | data() { |
| | | return {} |
| | | }, |
| | | created() { |
| | | this.popup.childrenMsg = this |
| | | }, |
| | | methods: { |
| | | open() { |
| | | if (this.duration === 0) return |
| | | clearTimeout(this.popuptimer) |
| | | this.popuptimer = setTimeout(() => { |
| | | this.popup.close() |
| | | }, this.duration) |
| | | }, |
| | | close() { |
| | | clearTimeout(this.popuptimer) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .uni-popup-message { |
| | | /* #ifndef APP-NVUE */ |
| | | display: flex; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | background-color: #e1f3d8; |
| | | padding: 10px 15px; |
| | | border-color: #eee; |
| | | border-style: solid; |
| | | border-width: 1px; |
| | | } |
| | | .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">{{title}}</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">取消</button> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'UniPopupShare', |
| | | props: { |
| | | title: { |
| | | type: String, |
| | | default: '分享到' |
| | | } |
| | | }, |
| | | inject: ['popup'], |
| | | data() { |
| | | return { |
| | | bottomData: [{ |
| | | text: '微信', |
| | | icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-2.png', |
| | | name: 'wx' |
| | | }, |
| | | { |
| | | text: '支付宝', |
| | | icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-8.png', |
| | | name: 'wx' |
| | | }, |
| | | { |
| | | text: 'QQ', |
| | | icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/gird-3.png', |
| | | name: 'qq' |
| | | }, |
| | | { |
| | | text: '新浪', |
| | | icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-1.png', |
| | | name: 'sina' |
| | | }, |
| | | { |
| | | text: '百度', |
| | | icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-7.png', |
| | | name: 'copy' |
| | | }, |
| | | { |
| | | text: '其他', |
| | | icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-5.png', |
| | | name: 'more' |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | created() {}, |
| | | methods: { |
| | | /** |
| | | * 选择内容 |
| | | */ |
| | | select(item, index) { |
| | | this.$emit('select', { |
| | | item, |
| | | index |
| | | }, () => { |
| | | this.popup.close() |
| | | }) |
| | | }, |
| | | /** |
| | | * 关闭窗口 |
| | | */ |
| | | close() { |
| | | this.popup.close() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .uni-popup-share { |
| | | background-color: #fff; |
| | | } |
| | | .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 |
| | |
| | | <template> |
| | | <view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear"> |
| | | <uni-transition v-if="maskShow" :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" |
| | | @click="onTap" /> |
| | | <uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap"> |
| | | <view class="uni-popup__wrapper-box" @click.stop="clear"> |
| | | <slot /> |
| | | </view> |
| | | </uni-transition> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import uniTransition from '../uni-transition/uni-transition.vue' |
| | | import popup from './popup.js' |
| | | /** |
| | | * PopUp 弹出层 |
| | | * @description 弹出层组件,为了解决遮罩弹层的问题 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=329 |
| | | * @property {String} type = [top|center|bottom] 弹出方式 |
| | | * @value top 顶部弹出 |
| | | * @value center 中间弹出 |
| | | * @value bottom 底部弹出 |
| | | * @value message 消息提示 |
| | | * @value dialog 对话框 |
| | | * @value share 底部分享示例 |
| | | * @property {Boolean} animation = [ture|false] 是否开启动画 |
| | | * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗 |
| | | * @event {Function} change 打开关闭弹窗触发,e={show: false} |
| | | */ |
| | | |
| | | export default { |
| | | name: 'UniPopup', |
| | | components: { |
| | | uniTransition |
| | | }, |
| | | props: { |
| | | // 开启动画 |
| | | animation: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层 |
| | | // message: 消息提示 ; dialog : 对话框 |
| | | type: { |
| | | type: String, |
| | | default: 'center' |
| | | }, |
| | | // maskClick |
| | | maskClick: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | provide() { |
| | | return { |
| | | popup: this |
| | | } |
| | | }, |
| | | mixins: [popup], |
| | | watch: { |
| | | /** |
| | | * 监听type类型 |
| | | */ |
| | | type: { |
| | | handler: function(newVal) { |
| | | this[this.config[newVal]]() |
| | | }, |
| | | immediate: true |
| | | }, |
| | | /** |
| | | * 监听遮罩是否可点击 |
| | | * @param {Object} val |
| | | */ |
| | | maskClick(val) { |
| | | this.mkclick = val |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | duration: 300, |
| | | ani: [], |
| | | showPopup: false, |
| | | showTrans: false, |
| | | maskClass: { |
| | | 'position': 'fixed', |
| | | 'bottom': 0, |
| | | 'top': 0, |
| | | 'left': 0, |
| | | 'right': 0, |
| | | 'backgroundColor': 'rgba(0, 0, 0, 0.4)' |
| | | }, |
| | | transClass: { |
| | | 'position': 'fixed', |
| | | 'left': 0, |
| | | 'right': 0, |
| | | }, |
| | | maskShow: true, |
| | | mkclick: true, |
| | | popupstyle: 'top' |
| | | } |
| | | }, |
| | | created() { |
| | | this.mkclick = this.maskClick |
| | | if (this.animation) { |
| | | this.duration = 300 |
| | | } else { |
| | | this.duration = 0 |
| | | } |
| | | }, |
| | | methods: { |
| | | clear(e) { |
| | | // TODO nvue 取消冒泡 |
| | | e.stopPropagation() |
| | | }, |
| | | open() { |
| | | this.showPopup = true |
| | | this.$nextTick(() => { |
| | | new Promise(resolve => { |
| | | clearTimeout(this.timer) |
| | | this.timer = setTimeout(() => { |
| | | this.showTrans = true |
| | | // fixed by mehaotian 兼容 app 端 |
| | | this.$nextTick(() => { |
| | | resolve(); |
| | | }) |
| | | }, 50); |
| | | }).then(res => { |
| | | // 自定义打开事件 |
| | | clearTimeout(this.msgtimer) |
| | | this.msgtimer = setTimeout(() => { |
| | | this.customOpen && this.customOpen() |
| | | }, 100) |
| | | this.$emit('change', { |
| | | show: true, |
| | | type: this.type |
| | | }) |
| | | }) |
| | | }) |
| | | }, |
| | | close(type) { |
| | | this.showTrans = false |
| | | this.$nextTick(() => { |
| | | this.$emit('change', { |
| | | show: false, |
| | | type: this.type |
| | | }) |
| | | clearTimeout(this.timer) |
| | | // 自定义关闭事件 |
| | | this.customOpen && this.customClose() |
| | | this.timer = setTimeout(() => { |
| | | this.showPopup = false |
| | | }, 300) |
| | | }) |
| | | }, |
| | | onTap() { |
| | | if (!this.mkclick) return |
| | | this.close() |
| | | }, |
| | | /** |
| | | * 顶部弹出样式处理 |
| | | */ |
| | | top() { |
| | | this.popupstyle = 'top' |
| | | this.ani = ['slide-top'] |
| | | this.transClass = { |
| | | 'position': 'fixed', |
| | | 'left': 0, |
| | | 'right': 0, |
| | | } |
| | | }, |
| | | /** |
| | | * 底部弹出样式处理 |
| | | */ |
| | | bottom() { |
| | | this.popupstyle = 'bottom' |
| | | this.ani = ['slide-bottom'] |
| | | this.transClass = { |
| | | 'position': 'fixed', |
| | | 'left': 0, |
| | | 'right': 0, |
| | | 'bottom': 0 |
| | | } |
| | | }, |
| | | /** |
| | | * 中间弹出样式处理 |
| | | */ |
| | | center() { |
| | | this.popupstyle = 'center' |
| | | this.ani = ['zoom-out', 'fade'] |
| | | this.transClass = { |
| | | 'position': 'fixed', |
| | | /* #ifndef APP-NVUE */ |
| | | 'display': 'flex', |
| | | 'flexDirection': 'column', |
| | | /* #endif */ |
| | | 'bottom': 0, |
| | | 'left': 0, |
| | | 'right': 0, |
| | | 'top': 0, |
| | | 'justifyContent': 'center', |
| | | 'alignItems': 'center' |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .uni-popup { |
| | | position: fixed; |
| | | /* #ifndef APP-NVUE */ |
| | | z-index: 99; |
| | | /* #endif */ |
| | | } |
| | | |
| | | .uni-popup__mask { |
| | | position: absolute; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background-color: $uni-bg-color-mask; |
| | | opacity: 0; |
| | | } |
| | | |
| | | .mask-ani { |
| | | transition-property: opacity; |
| | | transition-duration: 0.2s; |
| | | } |
| | | |
| | | .uni-top-mask { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .uni-bottom-mask { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .uni-center-mask { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .uni-popup__wrapper { |
| | | /* #ifndef APP-NVUE */ |
| | | display: block; |
| | | /* #endif */ |
| | | position: absolute; |
| | | } |
| | | |
| | | .top { |
| | | /* #ifdef H5 */ |
| | | top: var(--window-top); |
| | | /* #endif */ |
| | | /* #ifndef H5 */ |
| | | top: 0; |
| | | /* #endif */ |
| | | } |
| | | |
| | | .bottom { |
| | | bottom: 0; |
| | | } |
| | | |
| | | .uni-popup__wrapper-box { |
| | | /* #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 */ |
| | | } |
| | | |
| | | .content-ani { |
| | | // transition: transform 0.3s; |
| | | transition-property: transform, opacity; |
| | | transition-duration: 0.2s; |
| | | } |
| | | |
| | | |
| | | .uni-top-content { |
| | | transform: translateY(0); |
| | | } |
| | | |
| | | .uni-bottom-content { |
| | | transform: translateY(0); |
| | | } |
| | | |
| | | .uni-center-content { |
| | | transform: scale(1); |
| | | opacity: 1; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject" |
| | | @click="change"> |
| | | <slot></slot> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | // #ifdef APP-NVUE |
| | | const animation = uni.requireNativePlugin('animation'); |
| | | // #endif |
| | | /** |
| | | * Transition 过渡动画 |
| | | * @description 简单过渡动画组件 |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=985 |
| | | * @property {Boolean} show = [false|true] 控制组件显示或隐藏 |
| | | * @property {Array} 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', |
| | | props: { |
| | | show: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | modeClass: { |
| | | type: Array, |
| | | default () { |
| | | return [] |
| | | } |
| | | }, |
| | | duration: { |
| | | type: Number, |
| | | default: 300 |
| | | }, |
| | | styles: { |
| | | type: Object, |
| | | default () { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | isShow: false, |
| | | transform: '', |
| | | ani: { in: '', |
| | | active: '' |
| | | } |
| | | }; |
| | | }, |
| | | watch: { |
| | | show: { |
| | | handler(newVal) { |
| | | if (newVal) { |
| | | this.open() |
| | | } else { |
| | | this.close() |
| | | } |
| | | }, |
| | | immediate: true |
| | | } |
| | | }, |
| | | computed: { |
| | | stylesObject() { |
| | | let styles = { |
| | | ...this.styles, |
| | | 'transition-duration': this.duration / 1000 + 's' |
| | | } |
| | | let transfrom = '' |
| | | for (let i in styles) { |
| | | let line = this.toLine(i) |
| | | transfrom += line + ':' + styles[i] + ';' |
| | | } |
| | | return transfrom |
| | | } |
| | | }, |
| | | created() { |
| | | // this.timer = null |
| | | // this.nextTick = (time = 50) => new Promise(resolve => { |
| | | // clearTimeout(this.timer) |
| | | // this.timer = setTimeout(resolve, time) |
| | | // return this.timer |
| | | // }); |
| | | }, |
| | | methods: { |
| | | change() { |
| | | this.$emit('click', { |
| | | detail: this.isShow |
| | | }) |
| | | }, |
| | | open() { |
| | | clearTimeout(this.timer) |
| | | this.isShow = true |
| | | this.transform = '' |
| | | this.ani.in = '' |
| | | for (let i in this.getTranfrom(false)) { |
| | | if (i === 'opacity') { |
| | | this.ani.in = 'fade-in' |
| | | } else { |
| | | this.transform += `${this.getTranfrom(false)[i]} ` |
| | | } |
| | | } |
| | | this.$nextTick(() => { |
| | | setTimeout(() => { |
| | | this._animation(true) |
| | | }, 50) |
| | | }) |
| | | |
| | | }, |
| | | close(type) { |
| | | clearTimeout(this.timer) |
| | | this._animation(false) |
| | | }, |
| | | _animation(type) { |
| | | let styles = this.getTranfrom(type) |
| | | // #ifdef APP-NVUE |
| | | if(!this.$refs['ani']) return |
| | | animation.transition(this.$refs['ani'].ref, { |
| | | styles, |
| | | duration: this.duration, //ms |
| | | timingFunction: 'ease', |
| | | needLayout: false, |
| | | delay: 0 //ms |
| | | }, () => { |
| | | if (!type) { |
| | | this.isShow = false |
| | | } |
| | | this.$emit('change', { |
| | | detail: this.isShow |
| | | }) |
| | | }) |
| | | // #endif |
| | | // #ifndef APP-NVUE |
| | | this.transform = '' |
| | | for (let i in styles) { |
| | | if (i === 'opacity') { |
| | | this.ani.in = `fade-${type?'out':'in'}` |
| | | } else { |
| | | this.transform += `${styles[i]} ` |
| | | } |
| | | } |
| | | this.timer = setTimeout(() => { |
| | | if (!type) { |
| | | this.isShow = false |
| | | } |
| | | this.$emit('change', { |
| | | detail: this.isShow |
| | | }) |
| | | |
| | | }, this.duration) |
| | | // #endif |
| | | |
| | | }, |
| | | getTranfrom(type) { |
| | | let styles = { |
| | | transform: '' |
| | | } |
| | | this.modeClass.forEach((mode) => { |
| | | switch (mode) { |
| | | case 'fade': |
| | | styles.opacity = type ? 1 : 0 |
| | | break; |
| | | case 'slide-top': |
| | | styles.transform += `translateY(${type?'0':'-100%'}) ` |
| | | break; |
| | | case 'slide-right': |
| | | styles.transform += `translateX(${type?'0':'100%'}) ` |
| | | break; |
| | | case 'slide-bottom': |
| | | styles.transform += `translateY(${type?'0':'100%'}) ` |
| | | break; |
| | | case 'slide-left': |
| | | styles.transform += `translateX(${type?'0':'-100%'}) ` |
| | | break; |
| | | case 'zoom-in': |
| | | styles.transform += `scale(${type?1:0.8}) ` |
| | | break; |
| | | case 'zoom-out': |
| | | styles.transform += `scale(${type?1:1.2}) ` |
| | | break; |
| | | } |
| | | }) |
| | | return styles |
| | | }, |
| | | _modeClassArr(type) { |
| | | let mode = this.modeClass |
| | | if (typeof(mode) !== "string") { |
| | | let modestr = '' |
| | | mode.forEach((item) => { |
| | | modestr += (item + '-' + type + ',') |
| | | }) |
| | | return modestr.substr(0, modestr.length - 1) |
| | | } else { |
| | | return mode + '-' + type |
| | | } |
| | | }, |
| | | // getEl(el) { |
| | | // console.log(el || el.ref || null); |
| | | // return el || el.ref || null |
| | | // }, |
| | | toLine(name) { |
| | | return name.replace(/([A-Z])/g, "-$1").toLowerCase(); |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .uni-transition { |
| | | transition-timing-function: ease; |
| | | transition-duration: 0.3s; |
| | | transition-property: transform, opacity; |
| | | } |
| | | |
| | | .fade-in { |
| | | opacity: 0; |
| | | } |
| | | |
| | | .fade-active { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .slide-top-in { |
| | | /* transition-property: transform, opacity; */ |
| | | transform: translateY(-100%); |
| | | } |
| | | |
| | | .slide-top-active { |
| | | transform: translateY(0); |
| | | /* opacity: 1; */ |
| | | } |
| | | |
| | | .slide-right-in { |
| | | transform: translateX(100%); |
| | | } |
| | | |
| | | .slide-right-active { |
| | | transform: translateX(0); |
| | | } |
| | | |
| | | .slide-bottom-in { |
| | | transform: translateY(100%); |
| | | } |
| | | |
| | | .slide-bottom-active { |
| | | transform: translateY(0); |
| | | } |
| | | |
| | | .slide-left-in { |
| | | transform: translateX(-100%); |
| | | } |
| | | |
| | | .slide-left-active { |
| | | transform: translateX(0); |
| | | opacity: 1; |
| | | } |
| | | |
| | | .zoom-in-in { |
| | | transform: scale(0.8); |
| | | } |
| | | |
| | | .zoom-out-active { |
| | | transform: scale(1); |
| | | } |
| | | |
| | | .zoom-out-in { |
| | | transform: scale(1.2); |
| | | } |
| | | </style> |
| | |
| | | <view class="container"> |
| | | <search-bar></search-bar> |
| | | <view class="sort-wrap"> |
| | | <view> |
| | | <text>到店次数</text> |
| | | <view @click="filterCustom(1)"> |
| | | <text>到店排序</text> |
| | | <text class="iconfont iconjiantouarrow486"></text> |
| | | </view> |
| | | <view> |
| | | <text>消费金额</text> |
| | | <view @click="filterCustom(2)"> |
| | | <text>卡项排序</text> |
| | | <text class="iconfont iconjiantouarrow486"></text> |
| | | </view> |
| | | <view> |
| | | <view @click="filterCustom(3)"> |
| | | <text>全部筛选</text> |
| | | <text class="iconfont iconjiantouarrow486"></text> |
| | | </view> |
| | | </view> |
| | | <filter-dropdown ref="filterDropdownEl" :list="filterList" :type="filterType"></filter-dropdown> |
| | | <view class="sort-tab"> |
| | | <text class="sort-tab-item">正式客户</text> |
| | | <text class="sort-tab-item">体验客户</text> |
| | |
| | | <script> |
| | | import searchBar from '../../components/searchBar/index.vue'; |
| | | import indexedList from '../../components/indexedList/index.vue'; |
| | | import filterDropdown from '../../components/filterDropdown/index.vue'; |
| | | export default { |
| | | components:{ |
| | | searchBar, |
| | | indexedList |
| | | indexedList, |
| | | filterDropdown |
| | | }, |
| | | data() { |
| | | return { |
| | | colors: ['#CCC6B4', '#C0CCB4', '#B4C2CC', '#BEB4CC', '#B4CCBE', '#B4CCCA', '#CCB4C6', '#CCB4B4'] |
| | | colors: ['#CCC6B4', '#C0CCB4', '#B4C2CC', '#BEB4CC', '#B4CCBE', '#B4CCCA', '#CCB4C6', '#CCB4B4'], |
| | | filterType: 1, |
| | | filterList: [], |
| | | filter1: ['本月到店次数(由低到高)','本月到店次数(由高到低)','本年到店次数(由低到高)','本年到店次数(由高到低)','本月消费(由高到低)','本月消费(由低到高)','本月消耗(由高到低)','本月消耗(由低到高)'], |
| | | filter2: ['7天内卡项到期','15天内卡项到期','30天内卡项到期'], |
| | | filter3: [{ |
| | | title: '到店途径', |
| | | list: [ |
| | | { |
| | | 'title': '美团预约', |
| | | 'value': '' |
| | | }, |
| | | { |
| | | 'title': '网络预约', |
| | | 'value': '' |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | title: '会员等级', |
| | | list: [ |
| | | { |
| | | 'title': '一级会员', |
| | | 'value': '' |
| | | }, |
| | | { |
| | | 'title': '二级会员', |
| | | 'value': '' |
| | | }, |
| | | { |
| | | 'title': '三级会员', |
| | | 'value': '' |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | title: '活跃度', |
| | | list: [ |
| | | { |
| | | 'title': '活跃', |
| | | 'value': '' |
| | | }, |
| | | { |
| | | 'title': '不活跃', |
| | | 'value': '' |
| | | }, |
| | | { |
| | | 'title': '睡眠', |
| | | 'value': '' |
| | | }, |
| | | { |
| | | 'title': '沉睡', |
| | | 'value': '' |
| | | } |
| | | ] |
| | | }] |
| | | }; |
| | | }, |
| | | onHide(){ |
| | | this.$refs.filterDropdownEl.hide(); |
| | | }, |
| | | methods:{ |
| | | caculateBgcolor(index){ |
| | | return this.colors[index%8]; |
| | | }, |
| | | filterCustom(type){ |
| | | this.$refs.filterDropdownEl.show(); |
| | | if(type===1){ |
| | | this.filterList = this.filter1; |
| | | this.filterType = 1; |
| | | } else if(type===2){ |
| | | this.filterList = this.filter2; |
| | | this.filterType = 1; |
| | | } else { |
| | | this.filterList = this.filter3; |
| | | this.filterType = 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | <text class="font-18">我的业绩</text> |
| | | </view> |
| | | <view class="tab-box"> |
| | | <liuyuno-tabs |
| | | <h-tabs |
| | | class="tab" |
| | | :tabData="tabs" |
| | | :config="{ |
| | | color: '#abb1cc', |
| | | activeColor: '#518EFF', |
| | | underLineColor: '#518EFF', |
| | | underLineHeight: 5, |
| | | fontSize: 30, |
| | | underLineHeight: 4, |
| | | fontSize: '30px', |
| | | itemWidth: 70, |
| | | underLineWidth: 50, |
| | | underLineWidth: 60, |
| | | }" |
| | | /> |
| | | <view class="performance-content"> |
| | |
| | | <text class="font-14 mt-5">项目业绩</text> |
| | | </view> |
| | | </view> |
| | | <view class="flex justify-around mt-20"> |
| | | <view class="flex justify-around mt-15"> |
| | | <view class="flex flex-v align-center performance-item"> |
| | | <text class="font-16 blueness">600.00</text> |
| | | <text class="font-14 mt-5">产品业绩</text> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import liuyunoTabs from "@/components/liuyuno-tabs/liuyuno-tabs.vue"; |
| | | import HTabs from "@/components/liuyuno-tabs/liuyuno-tabs.vue"; |
| | | export default { |
| | | components: { |
| | | liuyunoTabs |
| | | HTabs |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | border: 1px solid #EDEAF4; |
| | | border-radius: 4px; |
| | | box-shadow:0 6px 6px rgba(237,234,244,0.5); |
| | | padding: 10px; |
| | | } |
| | | .tab{ |
| | | border-bottom: 1px solid #EDEAF4; |
| | | } |
| | | .performance-content{ |
| | | padding: 10px 0; |
| | | padding: 20px 0; |
| | | } |
| | | .performance-item{ |
| | | width: 33.3%; |