【发布时间】:2018-04-21 21:06:36
【问题描述】:
我有一个简单的 popover 组件,它抓取其父级在 dom 中的位置,然后将自身提升到 document.body 并绝对定位自身。
当我使用 v-show 显示和隐藏组件时,这一切都很好,但是如果我尝试使用 v-if,它会抱怨 this.$el.parentElement 为 null。
根据documentation,当调用mounted() 时,$el 应该在文档中,但是当它通过v-if 有条件地呈现时,情况似乎并非如此。
我尝试过使用nextTick,但这也无济于事。
我做错了吗?
这是我的组件的代码:
<template>
<div class="popover"><slot ></slot></div>
</template>
<script>
export default {
name: 'pop-over',
props: ['position', 'anchor', 'offset'],
methods: {
},
mounted() {
let rect = {};
let parent = this.$el.parentElement;
document.body.appendChild(this.$el);
let offset = {
x: this.offset ? this.offset.x || 0 : 0,
y: this.offset ? this.offset.y || 0 : 0
}
if (this.position) {
rect = {
top: this.position.top,
left: this.position.left
}
} else {
rect = parent.getBoundingClientRect();
rect = {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
bottom: window.innerHeight - rect.bottom - + window.scrollY,
right: window.innerWidth - rect.right + window.scrollX
}
}
this.$el.style.left = (rect.left + offset.x) + 'px';
if (this.anchor == 'below') {
this.$el.style.top = (rect.top + offset.y) + 'px';
} else {
this.$el.style.bottom = (rect.bottom + offset.y) + 'px';
}
}
}
</script>
【问题讨论】:
-
你为什么要
document.body.appendChild(this.$el)?尝试在没有该行的情况下运行代码,看看会发生什么。 [编辑以澄清我提出建议的原因] 我尝试在我的一个项目中重现这一点。 v-if 和 parentElement 工作正常,直到我将该行添加到我的代码中。将元素附加到 document.body 时,会将其从其原始位置移除,从而更改 parentElement。 -
附加到正文的目的是为了将其从文档流中取出,因此它会出现在所有其他内容之上。我在移动之前复制了父级,所以这应该不是问题。
标签: vue.js vuejs2 vue-component