乐趣区

关于前端:Vue3-优雅的模态框封装方案

Mr Mao’blog – gitee.io/mao-blog

Vue3 优雅的模态框封装办法 – 初探

Vue3 优雅的模态框封装办法 – 实际

Vue3 优雅的模态框封装办法 – 定制

上次说到利用虚构节点和瞬移组件制作模态框组件,并反对 template 中调用和 JavaScript 中调起

但实际上,咱们在工作中不会花这么大的精力去做这些繁琐的工作,个别都会间接应用组件库的弹出层去批改(例如 element-plus)

但所波及到的问题又回到了通篇都在形容的点上:

不通用,不能很不便的调用(例如我想在 js / ts 中调用我该怎么办)

后果就是又回到了 template 中一个个的当做组件应用

但并不是不能解决,在第二章中要实现无非就是将一个 vnode 节点渲染到 html 当中,用某种伎俩传入销毁的办法给予组件本身。

通过了长时间的积攒 …(咕咕咕

我制作了 unoverlay-vue,他用于更加简略不便制作和二次封装 overlay 层。

原理大同小异,就是利用 vue render 和闭包失去销毁组件本身的办法给予组件。

这个工具能够用于:

  • 制作相似于 element-plus/naiveui/vuetifyjs/vant... 的 Message 或 Dialog
  • 同时反对两种调用形式(组件 / javascript-api)
  • 应用现有组件库(如 element-plus)集成和定制化性能

应用 unoverlay-vue 定制化组件

以 element-plus@2.15.7(dialog) 为例(你也能够应用其余组件库)

⚙️ Install

pnpm add unoverlay-vue
# Or Yarn
yarn add unoverlay-vue

在 main.js 中全局装置能够使所有 overlay 继承利用上下文 (appContext)

// main.js
import {createApp} from 'vue'
import App from './App.vue'
import unoverlay from 'unoverlay-vue'

const app = createApp(App)
app.use(unoverlay)
app.mount('#app')

定制 el-dialog 组件

<!-- overlay.vue -->
<template>
  <el-dialog :title="title" :visible.sync="visible" @close="cancel()">
    <!-- 你的定制化内容 -->
    <button @click="confirm(title +':confirmed')"></button>
  </el-dialog>
</template>
<script setup>
import {defineProps, defineEmits} from 'vue'
import {useOverlayMeta} from 'unoverlay-vue'
const props = defineProps({
  title: String,
  // 如果你还想将其用作 template 中的组件应用,
  // 你须要在 props 中定义 visible 字段
  visible: Boolean
})

// 从 useOverlayMeta 获取 Overlay 信息, 这里利用了 vue 的 inject
const {visible, confirm, cancel} = useOverlayMeta({
  // 弹出层动画的持续时间, 能够防止组件过早被销毁
  // 仅在 template 中应用 component 则不须要定义
  animation: 1000
})
</script>

创立回调后,在 Javascript / Typescript 中调用

import {transformOverlay} from 'unoverlay-vue'
import OverlayComponent from './overlay.vue'
// 转换为命令式回调
const callback = transformOverlay(OverlayComponent)
// 调用组件并获取 confirm 回调的值
const value = await callback({title: 'myElDialog'})
// value === "myElDialog:confirmed"

或在 setup 中调用

import {useOverlayCall} from 'unoverlay-vue'
import OverlayComponent from './overlay.vue'

const value = await useOverlayCall(OverlayComponent, {props: { title: 'useOverlay'}
})
// value === "useOverlay:confirmed"

或在 template 中调用

<!-- overlay.vue -->
<template>
  <overlay-component
    v-model:visible="visible"
    @confirm="confirm"
    @cancel="cancel"
  >
  </overlay-component>
</template>
<script setup>
import OverlayComponent from './overlay.vue'
const visible = ref(false)

const confirm = () => {// ...}
const cancel = () => {// ...}
</script>

更多可查看 unoverlay-vue#cn-docs

该我的项目还在试验阶段,欢送 commit | issue

退出移动版