我的子页面打印的时候通过isPdf来隐藏“选择参加人员”按钮。
我子页面有个el-dialog,el-dialog里面有个大的div它的id为app-pre-meet-add,在子页面我通过isPdf来显示我想要的内容。现在我在父页面先通过this.$refs.child.controlPdf(true)来调用子页面的controlPdf方法使得子页面的isPdf变成true,然后通过下面的代码来克隆子页面的id为app-pre-meet-add的div:
const container = document.getElementById("app-pre-meet-add");
// 克隆父元素(深刻隆)
const clonedParent = container.cloneNode(true);
clonedParent.setAttribute("class", "cloned-app-pre-meet-add-class");
container.parentNode.insertBefore(clonedParent, container.nextSibling);
// 查找所有带有 hidden 类的子元素 form,并在克隆的元素中移除 hidden 类
const clonedHiddenForms = clonedParent.querySelectorAll(".hidden");
clonedHiddenForms.forEach((form) => {
form.classList.remove("hidden");
});
理论上这个新克隆的div应该是有子页面div在isPdf为true情况下的状态,但是为什么isPdf没有用
这个问题的根源在于cloneNode
方法的行为。当你克隆一个DOM元素时,你得到的是该元素在那一刻的快照,包括它的所有子元素和属性。但是,这个方法不会克隆与该元素相关联的JavaScript状态或事件监听器。在你的情况下,isPdf
可能是一个响应式数据属性或者计算属性,它控制着el-dialog
中某些元素的显示或隐藏。当你克隆div
时,你只是复制了它的静态结构,而没有复制Vue实例中的响应式状态。
使用Vue的ref
和$nextTick
:
你可以在子组件的div
上使用ref
,并在父组件中通过$refs
访问它。然后,你可以在父组件中调用一个方法来改变isPdf
的状态,并使用$nextTick
来确保DOM已经被更新。在$nextTick
的回调函数中,你可以克隆div
。
就是使用nextTick!!!
appPreAdd(formText, vdata, flag, res) {
this.$refs.child.controlPdf(true);
this.$nextTick(async () => {
const container = document.getElementById("app-pre-meet-add");
// 克隆父元素(深刻隆)
const clonedParent = container.cloneNode(true);
clonedParent.setAttribute("class", "cloned-app-pre-meet-add-class");
container.parentNode.insertBefore(clonedParent, container.nextSibling);
// 查找所有带有 hidden 类的子元素 form,并在克隆的元素中移除 hidden 类
const clonedHiddenForms = clonedParent.querySelectorAll(".hidden");
clonedHiddenForms.forEach((form) => {
form.classList.remove("hidden");
});
await htmlToPdftoFile.getPdfFromHtml(
".cloned-app-pre-meet-add-class",
formText,
"add",
res.data.data,
new Date(vdata.createTime),
this.checkFormTypeList[flag]
);
container.parentNode.removeChild(clonedParent);
this.$refs.child.controlPdf(false);
});
},