el-select选择器或date-picker,time-picker日期选择的下拉选项框点开时,点击浏览器返回上一步后,显示在上一个网页左上角【ElementUI】

环境:ElementUI+vue3+setup语法+ts(typescript,js的超集)

(一)、bug重现:

自己搭了个简单的页面,如下:【源码在本文最下方

 点开弹窗:

 第一步:点击下拉框

第二步:点击左上角返回一步 

可以看到bug出现 :

仅适用于返回一步之后路由会出现变化的情况!!

(二)、分析bug出现原因

打开F12调试,会发现元素中出现了不该出现的东西:

 同时发现,这里的下拉框的div定位为absolute,没有写top,left之类的属性,那它的默认值就是0,absolute为绝对定位,是按照最近父元素边框border最内侧定位的,在没有给定非static祖先元素定位的时候,定位是按照html边框border最外侧定位。

所以,此时的下拉框div位置才会在左上角。

所以,撸一下完整的逻辑是这样的:打开弹窗->点开下拉框->下拉框的div元素插入到当前网页中->返回上一步->下拉框的元素并未销毁,留在了上一个网页中,并由于定位问题,出现在了左上角

(如果路由不变化,不会出现这种问题)

(三)、如何解决

我们的需求是:关闭弹窗时 弹窗中已打开的东西也一并关闭销毁。

这时候就需要用到el-select的一个属性popper-append-to-body 或 teleported

 顺便贴一下官网地址:一个 Vue 3 UI 框架 | Element Plus

此时只需要在el-select中添加一句: :teleported="false" 即可

<el-select v-model="value" class="m-2" placeholder="Select" size="large" :teleported="false">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>

再做同样操作,发现元素已被销毁,网页正常显示,bug解决 :

TIP:以下为源码

//router/index.ts

import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views//HomePage.vue'
import Dialog from '@/views/dialog.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component:()=>Home
  },{
    path: '/dialog',
    name: 'dialog',
    component:()=>Dialog
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router
<!-- views/HomePage.vue --> 

<template>
  <div>
    <el-button @click="next">下一界面</el-button>

  </div>
</template>
  
<script lang="ts" setup>
import router from '@/router';


const next = () => {
  router.push('dialog')
}
</script>
 
<style lang="less" scoped></style>
<!-- views/dialog.vue -->
<template>
  <div>
    <el-dialog title="新界面" width="30%" destroy-on-close center v-model="dialogVisible">

      <div style="height:300px;width:600px">
        <strong>返回上一步,多选框/单选框的下拉选项信息,浮窗显示在系统左上角</strong>
        <el-select v-model="value" class="m-2" placeholder="Select" size="large" :teleported="false">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="close">Cancel</el-button>
          <el-button type="primary">
            Confirm
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
  
<script lang="ts" setup>
import router from '@/router';


const value = ref('')
const dialogVisible = ref(true)

const options = [
  {
    value: 'Option1',
    label: 'Option1',
  },
  {
    value: 'Option2',
    label: 'Option2',
  },
  {
    value: 'Option3',
    label: 'Option3',
  },
  {
    value: 'Option4',
    label: 'Option4',
  },
  {
    value: 'Option5',
    label: 'Option5',
  },
]

const close = () => {
  router.push('/')
  dialogVisible.value = false
}
</script>
 
<style lang="less" scoped></style>

猜你喜欢

转载自blog.csdn.net/qq_38686683/article/details/129991299
今日推荐