queenwuli
2020-12-15 3522317ba504a84199e185437b4ba66dbb4baf85
会员筛选条件
8 files added
3 files modified
1371 ■■■■■ changed files
hive-app/App.vue 2 ●●● patch | view | raw | blame | history
hive-app/components/filterDropdown/index.vue 120 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-popup/message.js 22 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-popup/popup.js 25 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-popup/uni-popup-dialog.vue 243 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-popup/uni-popup-message.vue 116 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-popup/uni-popup-share.vue 165 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-popup/uni-popup.vue 294 ●●●●● patch | view | raw | blame | history
hive-app/components/uni-transition/uni-transition.vue 279 ●●●●● patch | view | raw | blame | history
hive-app/pages/member/index.vue 88 ●●●●● patch | view | raw | blame | history
hive-app/pages/mine/index.vue 17 ●●●● patch | view | raw | blame | history
hive-app/App.vue
@@ -15,5 +15,5 @@
<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>
hive-app/components/filterDropdown/index.vue
New file
@@ -0,0 +1,120 @@
<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>
hive-app/components/uni-popup/message.js
New file
@@ -0,0 +1,22 @@
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()
            }
        }
    }
}
hive-app/components/uni-popup/popup.js
New file
@@ -0,0 +1,25 @@
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],
}
hive-app/components/uni-popup/uni-popup-dialog.vue
New file
@@ -0,0 +1,243 @@
<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>
hive-app/components/uni-popup/uni-popup-message.vue
New file
@@ -0,0 +1,116 @@
<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>
hive-app/components/uni-popup/uni-popup-share.vue
New file
@@ -0,0 +1,165 @@
<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>
hive-app/components/uni-popup/uni-popup.vue
New file
@@ -0,0 +1,294 @@
<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>
hive-app/components/uni-transition/uni-transition.vue
New file
@@ -0,0 +1,279 @@
<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>
hive-app/pages/member/index.vue
@@ -2,19 +2,20 @@
    <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>
@@ -45,19 +46,92 @@
<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;
                }
            }
        }
    }
hive-app/pages/mine/index.vue
@@ -33,17 +33,17 @@
                <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">
@@ -61,7 +61,7 @@
                            <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>
@@ -89,10 +89,10 @@
</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 {
@@ -158,13 +158,12 @@
        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%;