slide-select.vue 3.36 KB
<template>
<div class="slide-select" :class="{active: active, 'slide-in': slideIn}">
    <v-touch class="shadow" @tap="hide"></v-touch>
    <div class="select-box">
        <slide-select-header :title="title" @selected="selected"></slide-select-header>
        <slide-select-swipe v-if="active"
            :model="model" 
            :slides="currentSlides" 
            @change="slideChange"></slide-select-swipe>
    </div>
</div>
</template>

<script>
import slideSelectHeader from './slide-select-header.vue';
import slideSelectSwipe from './slide-select-swipe.vue';

export default {
    name: 'slide-select',
    props: {
        slides: {
            type: Array,
            default() {
                return [];
            }
        },
        model: {
            type: Number,
            default: 0
        },
        title: {
            type: String,
        },
        tag: {
            type: String,
        }
    },
    data() {
        return {
            active: false,
            slideIn: false,
            currentSlides: this.slides,
            currentModel: this.model
        };
    },
    methods: {
        show() {
            this.active = true;
            setTimeout(() => {
                this.slideIn = true;
            }, 0);
            this.bodyElStyle = document.querySelector('body').style;
            this.bodyElStyle.position = 'absolute';
            this.bodyElStyle.top = 0;
            this.bodyElStyle.left = 0;
            this.bodyElStyle.right = 0;
            this.bodyElStyle.bottom = 0;
            this.bodyElStyle.overflow = 'hidden';
            this.$emit('show', this.tag);
        },
        hide() {
            this.slideIn = false;
            setTimeout(() => {
                this.active = false;
            }, 200);
            this.bodyElStyle.position = 'static';
            this.bodyElStyle.overflow = 'auto';
            this.$emit('hide', this.tag);
        },
        slideChange(model) {
            this.currentModel = model;
        },
        selected() {
            let currentSlide = this.currentSlides.find(slide => slide.id === this.currentModel);

            this.hide();
            this.$emit('selected', {slide: currentSlide, tag: this.tag });
        }
    },
    beforeDestroy() {
        this.bodyElStyle.position = 'static';
        this.bodyElStyle.overflow = 'auto';
    },
    watch: {
        slides(val) {
            this.currentSlides = val;
        },
        model(val) {
            this.model = val;
        }
    },
    components: {
        slideSelectHeader,
        slideSelectSwipe,
    }
};

</script>

<style>
$show-speed: 0.2s;

.slide-select {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 211;
    display: none;

    &.active {
        display: block;
    }

    &.slide-in {
        .shadow {
            background-color: rgba(0, 0, 0, 0.2);
        }

        .select-box {
            transform: translate(0, 0);
        }
    }
}

.shadow {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    background-color: rgba(0, 0, 0, 0);
    transition: background-color $show-speed ease-in-out;
}

.select-box {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 511px;
    background-color: #fff;
    z-index: 2;
    transform: translate(0, 100%);
    transition: transform $show-speed ease-in-out;
}

</style>