隐藏组件,但保留 ref

发布时间 2023-12-07 17:28:32作者: shayloyuki

需求

背景

已知:二次封装 el-uploadImport 导入组件,点击 A 或 B,都弹出文件选择框。显示如下图所示:

image

父组件:

模板代码
              <el-col :span="1.5" class="import-btn">
                <import
                  ref="importRef"
                  :file-label="searchLabel"
                  :import-btn-title="importBtnTitle"
                  :para-name="paraName"
                  :addition-paras="additionParas"
                  :upload-url="uploadUrl"
                  :show-file-list="showFileList"
                  :file-type="fileType"
                  :is-plain="isPlain"
                  :has-temp="false"
                  @refreshList="loadSheets"
                />
              </el-col>
点击 B 触发的函数
    // 导入数据表
    nodeImport(data) {
      const { id, name } = data;
      this.$modal
        .confirm(`是否确认给“${name}”文件夹节点导入${this.searchLabel}?`)
        .then(() => {
          this.$set(this.additionParas, "dirId", id);
          this.$refs.importRef.triggerFileSelect();
        })
        .catch(() => {});
    },

Import 组件:

模板代码
    <!-- 导入组件 -->
    <el-upload
      :disabled="disableUpload"
      element-loading-text=""
      element-loading-spinner="null"
      v-loading.fullscreen.lock="progressUrl && isUploading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
      class="upload-file"
      ref="upload"
      :action="uploadUrl"
      :http-request="uploadFile"
      :show-file-list="showFileList"
      multiple
      :accept="acceptText"
      :on-exceed="handleExceed"
      :before-upload="beforeUpload"
      :limit="limitNum"
      :file-list="fileList"
    >
      <el-button
        :disabled="!uploadUrl || disableImport"
        type="warning"
        :plain="isPlain"
        :icon="importIcon"
        size="mini"
        :class="btnColor"
        v-hasPermi="btnPermiImport"
        :loading="isUploading"
        @click="onImportFile"
        :title="importBtnTitle"
        >{{ isUploading ? `${importText}中` : importText }}</el-button
      >
    </el-upload>
触发文件选择框弹出的函数
    triggerFileSelect() {
      this.$refs.upload.$children[0].$refs.input.click();
    },

效果

隐藏A,实现点击B仍然触发文件选择框。

解决

坑:尝试直接把A代码注释掉,但是点击B无法触发文件选择框,因为 DOM 上不存在该 ref 实例了。

隐藏页面元素,有两种方式:

  1. display: none:不展示元素,不占据文档流空间。
  2. visibility: hidden:只是视觉看不到,但仍然占据文档流空间。

根据需求,此处选择方式一。

因此,只需要添加以下代码即可:

.import-btn {
    display: none;
}

注意

display: none不展示元素,但DOM上仍然存在该实例;这不同于注释。

因此,这样是可以使用 ref 的,确保点击B仍然触发文件选择框。

参考链接

  1. CSS中如何隐藏元素但保留其占位空间(display:none vs visibility:hidden)?
  2. html元素设置display为none,绑定的事件还存在么