目录
目标效果
弹框要在及时响应数右边的icon旁展示
问题一 获取弹框元素失败
<el-dialog
title="及时响应时间配置"
:visible.sync="dialogVisible"
width="380px"
:modal="false"
:append-to-body="true"
:before-close="handleClose"
custom-class="custom-dialog">
openDialog() {
this.dialogVisible = true;
const targetDiv = document.getElementById('targetDiv');
const rect = targetDiv.getBoundingClientRect();
const dialog = this.$el.querySelector('.custom-dialog');
const dialogLeft = rect.left + rect.width + 10;
dialog.style.left = `${dialogLeft}px`; // 设置弹框的左边缘与目标 div 的右边缘对齐
dialog.style.top = `${rect.top}px`; // 设置弹框的顶部与目标 div 的顶部对齐
},
成功定位但是控制台有报错
问题二 定位不生效
通过 :style="dialogStyle"动态修改行内样式的定位top和left
<el-dialog
title="及时响应时间配置"
:visible.sync="dialogVisible"
width="380px"
:modal="false"
:append-to-body="true"
:before-close="handleClose"
ref="customDialog"
:style="dialogStyle">
data() {
return {
dialogVisible: false,
dialogStyle: {
left: '',
top: '',
},
dialogLeft: '',
};
},
openDialog() {
this.dialogVisible = true;
const targetDiv = document.getElementById('targetDiv');
const rect = targetDiv.getBoundingClientRect();
// const dialog = this.$el.querySelector('.custom-dialog');
const dialog = this.$refs.customDialog; // 使用ref直接访问元素
const dialogLeft = rect.left + rect.width + 10;
this.dialogStyle.left = rect.left + rect.width + 10 + 'px';
this.dialogStyle.top = rect.top + 'px';
// dialog.style.position = 'absolute';
// dialog.style.left = `${dialogLeft}px`; // 设置弹框的左边缘与目标 div 的右边缘对齐
// dialog.style.top = `${rect.top}px`; // 设置弹框的顶部与目标 div 的顶部对齐
// console.log('object', rect);
console.log('object--', dialog.style);
console.log('object2--', this.dialogStyle);
},
作用在弹框外层的el-dialog__wrapper上了
没有直接作用在弹框上
排查思路
控制台报错解决
通过 ref="customDialog"绑定弹框,而不是this.$el.querySelector(‘.custom-dialog’)
<el-dialog
title="及时响应时间配置"
:visible.sync="dialogVisible"
width="380px"
:modal="false"
:append-to-body="true"
:before-close="handleClose"
ref="customDialog"
修改后,通过this.$refs.customDialog访问到弹框元素,解决报错问题
const dialog = this.$refs.customDialog; // 使用ref直接访问元素
定位不生效问题解决
通过由问题一二可知, custom-class="custom-dialog"修改的定位可生效,直接作用于弹框,其他方式(行内)修改的定位不生效,所以在通过ref成功获取弹框元素后,将计算后的定位值作用在元素里的 custom-class类上,而不是 this.$el.querySelector(‘.custom-dialog’)获取的元素上
1、 观察this.$ refs.customDialog和 this.$el.querySelector(‘.custom-dialog’)获取元素的构成:
this.$ el.querySelector(‘.custom-dialog’):
获取到的是 custom-dialog类所在的元素
this.$ refs.customDialog:
获取到整个弹框对象,包括所有相关的属性、方法和元素,包括弹框最外层的dialog__wrapper元素:
观察发现:this.$refs.customDialog获取的对象里的 $el属性下的firstElementChild就是custom-dialog类所在元素,也是修改定位可以生效的元素:
2、获取refs里的定位作用元素
refs里的$el下的firstElementChild里的style属性上的top、left可成功修改弹框定位
const dialog = this.$refs.customDialog;
dialog.$el.firstElementChild.style.left = `${dialogLeft}px`;
3、完整实现
openDialog() {
//打开弹框
this.dialogVisible = true;
//获取目标元素
const targetDiv = document.getElementById('targetDiv');
//获取目标元素位置信息
const rect = targetDiv.getBoundingClientRect();
//获取定位元素
const dialog= this.$refs.customDialog;
//计算定位
const dialogLeft = rect.left + rect.width + 10;
//修改定位元素位置
dialog.$el.firstElementChild.style.left = `${dialogLeft}px`; // 设置弹框的左边缘与目标 div 的右边缘对齐
dialog.$el.firstElementChild.style.top = `${rect.top}px`; // 设置弹框的顶部与目标 div 的顶部对齐
},
注意,要在弹框上加入custom-class=“custom-dialog”,
<el-dialog
title="及时响应时间配置"
:visible.sync="dialogVisible"
width="380px"
:modal="false"
:append-to-body="true"
:before-close="handleClose"
custom-class="custom-dialog"
ref="customDialog">
并且保持custom-dialog类的定位是绝对定位
::v-deep .custom-dialog {
position: absolute !important;
}
效果展示
弹框能在及时响应数图表旁边展示,控制台无报错