v-if控制div内容显示,克隆这个div但是v-if没有效果

问题描述:

我的子页面打印的时候通过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:

  this.$refs.child.controlPdf(true);
  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);
      });
    },

最新问题:

这个问题就是await后面要跟promise,我没注意。

可以看到await修饰 this.appPreAdd方法

解决:

appPreAdd(formText, vdata, flag, res) {
      return new Promise((resolve, reject) => {
        this.$refs.child.controlPdf(true);
        this.$nextTick(async () => {
          try {
            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
            );
            const clonedHiddenForms = clonedParent.querySelectorAll(".hidden");
            clonedHiddenForms.forEach((form) => {
              form.classList.remove("hidden");
            });
            // 等待 PDF 生成完成
            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);
            // 成功完成,解析 Promise
            resolve();
          } catch (error) {
            // 发生错误,拒绝 Promise
            reject(error);
          }
        });
      });
    },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值