vue el-drawer 想要在指定div打开,并且设置自定义的蒙层效果。而且支持嵌套drawer进行设置。
2. 然后还要给 el-drawer设置样式 position:absolute;首先设置两个属性也就是隐藏el-drawer自带的蒙层。:modal-append-to-body=“false” // 遮罩层不能插入至 body。:wrapperClosable= “false”, // 点击遮罩层不可关闭drawer。需要 append-to-body: false, 因为设置为true会插入
核心是要 给其父元素设置 position: relative;
2. 然后还要给 el-drawer设置样式 position:absolute; 注意参考官方文档,
需要 append-to-body: false, 因为设置为true会插入body
3. 之后就是 蒙层 也要插入到指定位置;首先设置两个属性也就是隐藏el-drawer自带的蒙层
:modal-append-to-body=“false” // 遮罩层不能插入至 body
:modal=“false” // 不需要遮罩层
:wrapperClosable= “false”, // 点击遮罩层不可关闭drawer
4. 然后就是写自己的 蒙层:
在el-drawer出现的实现 出现该蒙层
5. 设置样式:
.drawer_mask {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.5);
}
下面进行改进,支持在指定div打开,而且支持嵌套。主要还是利用给父亲dom设置position属性。
主要解决的问题是:
1.1. 嵌套的drawer需要设置position:absolute,如果不是嵌套的drawer,只调用一次的情况,需要手动设置其 父dom为position:relative
解决:
mounted() {
// 获取一级父组件和子组件
// 设置在指定的 包裹该子组件的父dom节点打开 抽屉
const fatherDom = this.$parent.$el
const allCss = window.getComputedStyle(fatherDom, null)
console.log(allCss.position, fatherDom.classList, Array.from(fatherDom.classList).includes('el-drawer__wrapper'), 'allCssallCss')
if (Array.from(fatherDom.classList).includes('el-drawer__wrapper')) {
fatherDom.style.position = 'absolute'
} else {
if (allCss.position == 'static') {
// 不是el-drawer
fatherDom.style.position = 'relative'
}
}
},
1.2 嵌套的drawer 如果在父组件 引用的时候,可能有人会设置positon:absolute,这样会影响子drawer的定位。所以需要加入判断,移除这个属性,设置为position:static。
问题:
解决:
onOpen() {
// Drawer 的内容是懒渲染的,即在第一次被打开之前,
// 传入的默认 slot 不会被渲染到 DOM 上。
// 因此,如果需要执行 DOM 操作,
// 或通过 ref 获取相应组件,请在 open 事件回调中进行。
this.$nextTick(() => {
// // 只有一个div dom传入,清除在父组件使用slot时候 传入的position属性
if (this.$slots.default && this.$slots.default.length === 1) {
console.log(this.$slots.default[0], 'defaultSlots')
this.$slots.default[0].elm.style = `
position : static !important
` // 默认值,元素的位置有文档流决定,不受top,left等影响
}
})
}
<template>
<div>
<div v-show="visible" class="drawer_mask" />
<el-drawer
ref="elDrawer"
:title="title"
:visible="visible"
:append-to-body="false"
:modal-append-to-body="false"
:modal="false"
style="position: absolute;"
:direction="direction"
:size="size"
:wrapper-closable="false"
destroy-on-close
@close="onClose"
@open="onOpen"
>
<div>
<slot />
</div>
</el-drawer>
</div>
</template>
<script>
export default {
name: 'CustElDrawer',
props: {
title: {
type: String,
default: '测试'
},
visible: {
type: Boolean,
default: false
},
direction: {
type: String,
default: 'rtl'
},
size: {
type: [String, Number],
default: '30%'
}
},
mounted() {
// 获取一级父组件和子组件
// 设置在指定的 包裹该子组件的父dom节点打开 抽屉
const fatherDom = this.$parent.$el
const allCss = window.getComputedStyle(fatherDom, null)
console.log(allCss.position, fatherDom.classList, Array.from(fatherDom.classList).includes('el-drawer__wrapper'), 'allCssallCss')
if (Array.from(fatherDom.classList).includes('el-drawer__wrapper')) {
fatherDom.style.position = 'absolute'
} else {
if (allCss.position == 'static') {
// 不是el-drawer
fatherDom.style.position = 'relative'
}
}
},
methods: {
onClose() {
this.$emit('close')
},
onOpen() {
// Drawer 的内容是懒渲染的,即在第一次被打开之前,
// 传入的默认 slot 不会被渲染到 DOM 上。
// 因此,如果需要执行 DOM 操作,
// 或通过 ref 获取相应组件,请在 open 事件回调中进行。
this.$nextTick(() => {
// // 只有一个div dom传入,清除在父组件使用slot时候 传入的position属性
if (this.$slots.default && this.$slots.default.length === 1) {
console.log(this.$slots.default[0], 'defaultSlots')
this.$slots.default[0].elm.style = `
position : static !important
` // 默认值,元素的位置有文档流决定,不受top,left等影响
}
})
}
}
}
</script>
<style lang="scss" scoped>
.drawer_mask {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.5);
}
</style>
更多推荐
所有评论(0)