Vue3 优雅的模态框封装方案 - 初探

Posted Mr_mao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3 优雅的模态框封装方案 - 初探相关的知识,希望对你有一定的参考价值。

my-blog:https://tuimao233.gitee.io/ma...

Vue3 优雅的模态框封装方法 - 初探

Vue3 优雅的模态框封装方法 - 实践

想必大家使用 Vue 开发时,都有使用过 Element 或 Ant Design of Vue 的模态框

例如 Ant Design of Vue 中的 a-message:

  <a-modal v-model="visible" title="Title" on-ok="handleOk">
    自定义内容
  </a-modal>

又或者直接在 js 代码中直接调起的 ElMessageBox:

import { ElMessageBox } from \'element-plus\';

ElMessageBox.confirm(\'此操作将永久删除该文件, 是否继续?\', \'提示\')
    .then(()=> {
    })
    .catch(()=> {
    })

例如在项目当中,有需要定义模态框调用的场景,就需要掌握自定义模态框的封装

就好比如在一个后台管理系统中的一个图片选择器

ImageSelect({ multiple: true })
    .then((images)=> {
    
    })

又或者是使用组件库的模态框自定义样式功能,导致需要写全局类名覆盖组件模态框,复用率低下

  <!-- 组件 A -->
  <el-dialog custom-class="purchase-dialog">
    ...自定义内容...
  </el-dialog>
  <!-- 组件 B -->
  <el-dialog custom-class="purchase-dialog">
    ...自定义内容...
  </el-dialog>

可见要封装好一个模态框组件的重要性还是很高的,那么整个大纲中会循环渐进的告诉你如果需要自定义封装一个又支持在 template 中使用,又支持在 js 代码中直接调用的对话框,以及如何利用组件库已有的模态框在不影响其复用性,扩展性的前提下进行二次封装。

本篇文章主要讲解要封装模态框之前要有所了解的一些技巧和 API

  • 虚拟节点创建 (create vnode)
  • 虚拟节点渲染 (render vnode)
  • Vue3 新增瞬移组件 (teleport)

虚拟节点创建 (create vnode)

虚拟节点可以理解成节点描述对象,它描述了应该怎样去创建真实的DOM节点。

利用 Vue3 默认导出的 h 函数,创建 vnode ,h 函数可以有多种传参方式:

import { h } from \'vue\'
// 传入组件内容, 与组件 props 参数, 生成虚拟节点
const vnode = h(Component, props)

// 组件内容可为导入组件, 例如
import Component from \'./Component.vue\'
const vnode = h(Component, props)
// 也可为 template 例如
const vnode = h(\'<div>hello world!!</div>\', props)
// 也可为节点的描述数据 例如
const vnode = h(\'div\', { id: \'app\' }, [h(\'span\', \'我是 span\')])

虚拟节点渲染 (render vnode)

利用 Vue3 默认导出的 render 函数,渲染至 document.body 当中:

import { h, render } from \'vue\'
render(h(\'div\', \'我是一个 div\'), container)

利用一个中间节点容器,卸载节点下所有 vnode:

import { h, render } from \'vue\'
const container = document.createElement(\'div\')
render(h(\'div\', \'我是一个 div\'), container)
document.body.appendChild(container.firstElementChild)
// 销毁真实节点的所有实例 ( 卸载组件 )
// 这里不需要调用 document.body.removeChild(container.firstElementChild)
// 因为调用 render(null, container) 为我们完成了这项工作
render(null, container)

Vue3 内置组件 - 瞬移组件 (Teleport)

瞬移组件需要传入 to 参数,代表挂载到对应真实 DOM 当中,瞬移组件有以下特点:

  • 该组件需要一个目标元素,该元素是通过需要一个htmlElement或querySelector字符串的prop提供的
  • 组件将其子代移动到DOM选择器标识的元素
  • 虚拟DOM级别,子级仍然是子代的后代<teleport>,因此他们可以从其祖先那里获得注入
  <teleport to="body">
    <div id="content">
      <p>
        this will be moved to #endofbody.
        <br />Pretend that it\'s a modal
      </p>
    </div>
  </teleport>

以上是关于Vue3 优雅的模态框封装方案 - 初探的主要内容,如果未能解决你的问题,请参考以下文章

原生js封装模态框

Vue模态框的封装

原生js封装模态框

vue3 封装单选框组件

vue3 封装单选框组件

Vue3封装数字框组件