<template> <div> <transition name="el-fade-in"> <div class="proper__model" v-if="show" @click="hideProper"></div> </transition> <transition @before-enter="beforeEnter" @enter="enter" @leave="leave"> <div :class="['proper__content',`proper__${placement}`]" :style="getClient()" v-if="show"> <slot></slot> </div> </transition> </div> </template> <script> /** * 邊界滑出層 * @desc 在頁面中彈出一個遮罩層,與一快內容區域 * @param 見props * @example <slide-model v-model="showProper" placement="right" client="300">這里是content</slide-model> */ export default { name: 'search-model', data () { return { show: this.value } }, watch: { value: function (val) { this.show = val } }, props: { value: { // 是否顯示 type: Boolean, default: false }, placement: { type: String, // content出現位置 default: 'right' // {left,top,bottom,right} }, client: { // 內容區域的高度或者寬度,左邊或者右邊表示寬度,上邊或者下邊表示高度 type: [String, Number], default: 300 } }, methods: { /** * 獲取定位確定固定高或寬樣式 * @return {Object} style 內容區域高或寬樣式 */ getClient () { let style = {} if (this.placement === 'top' || this.placement === 'bottom') { style = { height: this.client + 'px' } } else { style = { width: this.client + 'px' } } return style }, /** * 隱藏彈窗 */ hideProper () { this.show = false this.$emit('input', this.show) }, beforeEnter (el) { switch (this.placement) { case 'left': el.style.transform = `translateX(-${this.client}px)` break case 'right': el.style.transform = `translateX(${this.client}px)` break case 'top': el.style.transform = `translateY(-${this.client}px)` break case 'bottom': el.style.transform = `translateY(${this.client}px)` break } el.style.opacity = 0 }, enter (el, done) { done() el.style.transition = 'all .3s ease' el.style.transform = 'translateX(0px) translateY(0px)' el.style.opacity = 1 }, leave (el, done) { el.style.transition = 'all .2s ease' switch (this.placement) { case 'left': el.style.transform = `translateX(-${this.client}px)` break case 'right': el.style.transform = `translateX(${this.client}px)` break case 'top': el.style.transform = `translateY(-${this.client}px)` break case 'bottom': el.style.transform = `translateY(${this.client}px)` break } el.style.opacity = 0 setTimeout(_ => { done() }, 1500) } } } </script> <style scoped lang="less"> .proper__model { position: fixed; height: 100%; width: 100%; top: 0; left: 0; z-index: 1999; background-color: rgba(0, 0, 0, 0.3); } .proper__content { position: fixed; overflow: hidden; z-index: 2000; padding: 10px; box-shadow: 0 0 3px #fff; background-color: #fff; } .proper__left { bottom: 0; left: 0; height: 100%; padding-top: 20px; } .proper__right { bottom: 0; right: 0; height: 100%; padding-top: 20px; } .proper__top { top: 0; left: 0; width: 100%; padding-top: 20px; } .proper__bottom { bottom: 0; left: 0; width: 100%; padding-top: 20px; } </style>