Skip to content
此页目录
本文总阅读量

ElementUi-Dialog 弹窗动画 origin 设置

以下操作可以模仿Ant Design弹窗弹出动画,弹窗缩放的起点为点击的位置。可以参考Ant Designmodal组件的弹出动画。

注意

下列代码示例以Vue 2.7+setup语法为例。

新建useTransformOrigin.ts监听事件获取点击的x y

ts
import { ref } from "vue"

export const x = ref()
export const y = ref()

// dialog transform origin 获取
window.addEventListener("mousedown", e => {
  x.value = e.clientX
  y.value = e.clientY
})

新建ComDialog.vueDialog二次封装

  1. @mousedown.stop.native阻止事件冒泡,防止x y值在弹窗内被赋值。
  2. 监听x y值计算transformOrigin的缩放点
  3. .dialog-fade样式动画进行修改

已知问题

使用组件时第一次加载或在组件上使用了v-if不会触发动画。

vue
<!-- ComDialog.vue -->
<template>
  <el-dialog
    ref="dialogRef"
    :top="top"
    :width="width"
    :style="{
      transformOrigin,
    }"
    @mousedown.stop.native
    v-bind="$attrs"
    v-on="$listeners"
  >
    ...
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch, PropType } from "vue"
import { x, y } from "./useTransformOrigin"

const props = defineProps({
  width: {
    type: String as PropType<string>,
    default: "700px",
  },
  top: {
    type: String as PropType<string>,
    default: "15vh",
  },
})

const dialogRef = ref()

const transformOrigin = ref("")

watch([x, y], () => {
  const dialog = dialogRef.value?.$el.querySelector(".el-dialog")
  if (!dialog) return "center"
  transformOrigin.value = `calc(${x.value}px - ${props.width}) calc(${y.value}px - ${props.top})`
})
</script>


<style lang="scss" scoped>
.el-dialog__wrapper {
  transition-duration: 0.3s;
}
.dialog-fade-enter-active,
.dialog-fade-leave-active {
  animation: none !important;
}

.dialog-fade-enter-active {
  ::v-deep .el-dialog {
    animation: anim-open 0.3s;
    transform-origin: inherit;
  }
}

.dialog-fade-leave-active {
  ::v-deep .el-dialog {
    animation: anim-close 0.4s;
    transform-origin: inherit;
  }
}
</style>

评论

交流群