Element UI フレームワークにはドロワーコンポーネントが用意されていないため、ここではカスタムドロワーコンポーネントの実装方法について解説します。
以下に、ドロワーコンポーネントのソースコードを示します。
<template>
<div class="custom-drawer">
<div :class="maskClasses" @click="handleMaskClick"></div>
<div :class="drawerClasses" :style="drawerStyles">
<div class="drawer-header">
<span>{{ title }}</span>
<span v-if="closable" class="close-button" @click="closeDrawer">×</span>
</div>
<div class="drawer-content">
<slot />
</div>
</div>
</div>
</template>
<script>
export default {
props: {
isOpen: {
type: Boolean,
required: true
},
title: {
type: String,
default: 'ドロワータイトル'
},
closable: {
type: Boolean,
default: true
},
showMask: {
type: Boolean,
default: true
},
maskClosable: {
type: Boolean,
default: true
},
width: {
type: String,
default: '300px'
},
isInner: {
type: Boolean,
default: false
}
},
computed: {
maskClasses() {
return {
'drawer-mask': true,
'mask-visible': this.showMask && this.isOpen,
'mask-hidden': !(this.showMask && this.isOpen),
'inner-mask': this.isInner
};
},
drawerClasses() {
return {
'drawer-panel': true,
'panel-visible': this.isOpen,
'panel-hidden': !this.isOpen,
'inner-panel': this.isInner
};
},
drawerStyles() {
const styles = {
width: this.width,
right: this.isOpen ? '0' : `-${this.width}`,
};
if (!this.showMask) {
styles.borderLeft = '1px solid #eee';
}
return styles;
}
},
mounted() {
if (this.isInner) {
const parentElement = this.$el.parentNode;
parentElement.style.position = 'relative';
}
},
methods: {
handleMaskClick() {
if (this.maskClosable) {
this.$emit('update:isOpen', false);
}
},
closeDrawer() {
this.$emit('update:isOpen', false);
}
}
};
</script>
<style lang="scss" scoped>
.custom-drawer {
.drawer-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
background-color: rgba(0, 0, 0, 0.5);
opacity: 1;
transition: opacity 0.5s ease;
&.mask-hidden {
opacity: 0;
}
&.inner-mask {
position: absolute;
}
}
.drawer-panel {
position: fixed;
z-index: 1001;
top: 0;
height: 100%;
background-color: #fff;
transition: transform 0.5s ease, opacity 0.5s ease;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
&.panel-visible {
opacity: 1;
}
&.panel-hidden {
opacity: 0;
}
&.inner-panel {
position: absolute;
}
}
.drawer-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
padding: 0 20px;
border-bottom: 1px solid #e0e0e0;
font-size: 16px;
font-weight: bold;
.close-button {
cursor: pointer;
font-size: 18px;
padding: 5px;
}
}
.drawer-content {
padding: 20px;
}
}
</style>
このコンポーネントの使用例を以下に示します。
<template>
<div class="usage-example">
<el-button type="primary" @click="drawerVisible = true">ドロワーを開く</el-button>
<custom-drawer
title="詳細情報"
:isOpen.sync="drawerVisible"
:isInner="true"
:width="'450px'"
:showMask="false">
<p>これはドロワー内のコンテンツです。</p>
<p>追加情報はこちらに記載します。</p>
</custom-drawer>
</div>
</template>
<script>
import CustomDrawer from '@/components/CustomDrawer.vue';
export default {
components: {
CustomDrawer
},
data() {
return {
drawerVisible: false
};
}
};
</script>