vue3自定义弹框组件,函数方式调用

news2024/9/9 1:17:39

缘由:项目要用到一个弹框,需要公共函数内调用。考虑封装成像 Element PlusElMessageBox.confirm 的方式调用,而不是直接在 template 中写组件的方式调用。

思路逻辑

实现

实现弹框 component

<template>
  <el-dialog
    v-model="visible"
    width="480"
    :title="props.title"
    :close-on-click-modal="false"
    @close="onClose()"
    @open="onOpen()"
  >
    <template #default>
      <el-form ref="formRef" :model="formData" inline-message label-width="120px">
        <template v-for="(item, index) in formData.barcodeList" :key="index">
          <el-form-item
            :label="`${$t('common.label')}(${index + 1})`"
            :prop="`barcodeList.${index}.barcode`"
            :rules="getRule(index)"
          >
            <div class="w-full flex items-center">
              <el-input v-model="item.barcode"></el-input>
              <el-button
                v-if="index !== 0"
                class="flex-center ml-10"
                type="plain"
                size="small"
                circle
                @click="onDelete(index)"
              >
                <i class="iconfont icon-delete ml-4 error-color"></i>
              </el-button>
            </div>
          </el-form-item>
        </template>
      </el-form>
      <el-button type="primary" @click="addNewBarcode()">{{ $t('common.addBarCode') }}</el-button>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="onClose()">{{ $t('common.cancel') }}</el-button>
        <el-button type="primary" @click="submitForm(formRef)">
          {{ $t('common.confirm') }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { ElMessage, FormInstance, FormRules } from 'element-plus'
import { computed, reactive, ref, PropType } from 'vue'
import { useI18n } from 'vue-i18n'

const { t: $t } = useI18n()

defineOptions({
  name: 'CompleteDialog',
})

const props = defineProps({
  message: String,
  title: String,
  onOpen: Function as PropType<() => void>,
  onCancel: Function as PropType<() => void>,
  onConfirm: Function as PropType<(data: any) => void>,
})
const emits = defineEmits(['submit'])

const visible = defineModel({ type: Boolean, default: false })

const formRef = ref<FormInstance>()
const formDataDefault = {
  barcodeList: [
    {
      barcode: '',
    },
  ] as any[],
}
const formData = reactive<typeof formDataDefault>({ ...formDataDefault })
const formRules = reactive<FormRules>({})
const getRule = (index?: number) => {
  return [{ required: true, message: $t('common.RequiredInput'), trigger: 'change' }]
}

const onDelete = (index: number) => {
  formData.barcodeList.splice(index, 1)
}

const addNewBarcode = () => {
  const len = formData.barcodeList.length
  formData.barcodeList.push({ barcode: '' })
}

const onOpen = () => {
  const { onOpen } = props
  if (onOpen) {
    onOpen()
  }
}

const onClose = () => {
  const { onCancel } = props
  if (onCancel) {
    onCancel()
  }
  formRef.value?.resetFields()
  Object.assign(formData, formDataDefault)
  visible.value = false
}

const submitForm = async (formEl?: FormInstance) => {
  if (!formEl) return

  await formEl.validate(async (valid: any) => {
    if (!valid) return false
    const result = { ...formData }
    emits('submit', result)
    if (props.onConfirm) {
      props.onConfirm(result)
    }
    onClose()
  })
}
</script>

<style lang="scss" scoped></style>

封装函数方式调用 index.tsx
因为用了 sx ,所以没有用 h 函数.如果没有用 jsx,需要用 h 函数创建 VNode

import { i18n, locale } from '@/lang/index'
import { createApp, ref, watch } from 'vue'
import ElementPlus from 'element-plus'
import CompleteDialog from './completeDialog.vue'

export const useConfirmCompleteDialog = <T extends any>(
  message?: string,
  title?: string
): Promise<T> => {
  return new Promise((resolve, reject) => {
    const div = document.createElement('div')
    document.body.appendChild(div)

    const app = createApp({
      setup() {
        const visible = ref(true)

        const close = () => {
          visible.value = false
        }

        const onConfirm = (data: any) => {
          resolve(data)
          close()
        }

        const onCancel = () => {
          reject()
          close()
        }

        watch(visible, newValue => {
          if (!newValue) {
            app.unmount()
            document.body.removeChild(div)
          }
        })

        return () => (
          <CompleteDialog
            modelValue={visible.value}
            onUpdate:modelValue={value => {
              visible.value = value
            }}
            message={message}
            title={title}
            onConfirm={onConfirm}
            onCancel={onCancel}
          ></CompleteDialog>
        )
      },
    })
    // 因为项目用了 i18n 国际化, ElementPlus UI组件,所以引入
    // 根据实际项目需要修改,不需要i18n,ElementPlus的可以取消,只需要注册自定义组件
    app.use(i18n).use(ElementPlus, { locale })
    app.component(CompleteDialog.name, CompleteDialog)
    app.mount(div)
  })
}

最小化实现:

vim myComponent.vue

<template>
	<div v-if="visiable">
		<div class="title">{{props.title}}</div>
		<div class="message">{{props.message}}</div>
		<div @click="onCancel">Cancel</div>
		<div @click="onConfirm">Confirm</div>
	</div>
<template>

<script setup>

const props = defineProps({
	title: String,
	message: String,
	onOpen: Function as PropType<() => void>,
  	onCancel: Function as PropType<() => void>,
  	onConfirm: Function as PropType<(data: any) => void>,
})

const onOpen = () => {
  const { onOpen } = props
  if (onOpen) {
    onOpen()
  }
}
const onCancel= () => {
  const { onCancel} = props
  if (onCancel) {
    onCancel()
  }
}
const onConfirm= () => {
  const { onConfirm} = props
  if (onConfirm) {
    onConfirm()
  }
}
</script>

vim completeDialog.tsx

import { createApp, ref, watch } from 'vue'
import CompleteDialog from './completeDialog.vue'

export const useConfirmCompleteDialog = <T extends any>(
  message?: string,
  title?: string
): Promise<T> => {
  return new Promise((resolve, reject) => {
    const div = document.createElement('div')
    document.body.appendChild(div)

    const app = createApp({
      setup() {
        const visible = ref(true)

        const close = () => {
          visible.value = false
        }

        const onConfirm = (data: any) => {
          resolve(data)
          close()
        }

        const onCancel = () => {
          reject()
          close()
        }

        watch(visible, newValue => {
          if (!newValue) {
            app.unmount()
            document.body.removeChild(div)
          }
        })

        return () => (
          <CompleteDialog
            modelValue={visible.value}
            onUpdate:modelValue={value => {
              visible.value = value
            }}
            message={message}
            title={title}
            onConfirm={onConfirm}
            onCancel={onCancel}
          ></CompleteDialog>
        )
      },
    })
    app.component(CompleteDialog.name, CompleteDialog)
    app.mount(div)
  })
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1958966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

求.netcore 按模板导出pdf免费插件,来谈谈。

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

图书管理系统设计

设计一个图书管理系统时&#xff0c;我们需要考虑系统的基本功能、用户需求、技术选型以及数据的安全性和完整性。下面是一个基本的图书管理系统的设计概览&#xff1a; 1. 系统目标 管理图书信息&#xff1a;添加、删除、修改图书信息。借阅管理&#xff1a;处理借书、还书流…

低代码应用版本管理能力探讨

低代码平台为开发者提供易用的可视化、定制化开发能力&#xff0c;无需编写原生代码或者只有少量代码编写就能实现需求&#xff0c;从而带来开发门槛的降低&#xff0c;开发效率的提升。低代码作为提升应用研发生产力的关键型技术&#xff0c;成为企业数字化转型的助推器。 低代…

StarRock3.3 安装部署(存算分离、存算一体保姆式教程)

服务器前置要求&#xff1a; 1、内存>32GB 2、JDK 8 is not supported, please use JDK 11 or 17 1、安装 wget https://releases.starrocks.io/starrocks/StarRocks-3.3.0.tar.gz tar zxvf StarRocks-3.3.0.tar.gz 2、FE服务启动 2.1 配置FE节点(默认配置&#xff0c;…

C#知识|文件与目录操作:文本读写操作

哈喽,你好啊,我是雷工! 今天学习文件与目录的操作,以下为文本读写操作的学习笔记。 01 文件操作说明 1.1、数据的存取方式 数据库:适合存取大量且关系复杂并有序的数据; 文件:适合存取大量但数据关系简单的数据,像系统的日志文件; 1.2、文件存取的优点 ①:读取操…

根据ip地址能查询出具体地址吗?

在数字化时代&#xff0c;互联网已成为我们日常生活不可或缺的一部分&#xff0c;而IP地址作为网络世界的“身份证”&#xff0c;承载着每一台设备在网络中的唯一标识。你是否曾经好奇&#xff0c;通过一串看似无意义的数字组合——IP地址&#xff0c;我们究竟能否揭开其背后的…

springboot校园失物招领系统-计算机毕业设计源码17082

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 相关技术介绍 2.1 B/S结构 2.2 Spring Boot框架 2.3 MySQL数据库 3系统分析 3.1 可行性分析 3.2 系统流程分析 3.2.1 数据新增流程 3.2.2 数据删除流程 3.3 系统功能分析 3.3.1 功能性分…

解决亚马逊测评困境:买家号支付失败与砍单率高的应对策略

在销售旺季期间&#xff0c;众多商家倾向于采用自建买家账号进行产品评价&#xff0c;以期快速提升产品权重。然而&#xff0c;不少商家在此过程中遭遇了订单无法成功提交或遭遇高比例订单取消的困境。部分商家首先怀疑的是支付卡的问题&#xff0c;也有部分认为IP地址可能已被…

拥抱人工智能浪潮,95后如何为未来职场做好准备?

随着毕业季的落幕&#xff0c;新一代青年力量步入社会&#xff0c;他们面临的是一个正在被人工智能深刻改变的劳动力市场。特别是对于“95后”这一群体&#xff0c;如何在即将席卷而来的人工智能革命中站稳脚跟&#xff0c;甚至乘风破浪&#xff0c;成为摆在他们面前的重要课题…

在 Kali Linux 虚拟机中实现主机代理共享的详细指南

Kali Linux 是网络安全和渗透测试领域中广泛使用的操作系统。它提供了丰富的工具和灵活的环境&#xff0c;适合各种网络安全任务。在某些情况下&#xff0c;您可能需要通过主机的代理服务器来实现特定的网络配置&#xff0c;以便更好地保护隐私或进行网络测试。这篇文章将详细介…

昇思25天学习打卡营第18天|xiaoyushao

今天分享基于MobileNetv2的垃圾分类。读取本地图像数据作为输入&#xff0c;对图像中的垃圾物体进行检测&#xff0c;并且将检测结果图片保存到文件中。 目录 一、 MobileNetv2模型原理介绍 二、 数据处理 1. 数据准备 2. 数据加载 3. 数据预处理 三、 MobileNetv2模型搭建 四、…

Redis 7.x 系列【34】Spring Boot 集成

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 前言2. Spring Data Redis3. Spring Boot Data Redis Starter3.1 起步依赖3.2 自动…

精品PPT | 微信云原生大数据平台构建及落地实践.pptx

一、大数据上云概述 1.为什么大数据要上云 2.微信大数据平台架构演进 二、大数据上云基础建设 1.统一编排 2.Pod 设计及大数据配套能力 3.计算组件云环境适配 三、稳定性及效率提升 1.K8S 集群稳定性与弹性配额 2.可观测性与智能运维

Java学习笔记(六)面向对象编程(基础部分)

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍Java面向对象编程&#xff08;基础部分&#xff09;类与对象、方法重载、作用域、构造器细节、this关键字、可变参数使用以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1…

C# 12 新增功能实操!

前言 今天咱们一起来探索并实践 C# 12 引入的全新功能&#xff01; C#/.NET该如何自学入门&#xff1f; 注意&#xff1a;使用这些功能需要使用最新的 Visual Studio 2022 版本或安装 .NET 8 SDK 。 主构造函数 主构造函数允许你直接在类定义中声明构造函数参数&#xff0c;…

停车共享小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;停车场管理&#xff0c;停车预约管理&#xff0c;停车缴费管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;停车场&#xff0c;我的 开发系统&…

主图趋势交易九稳量化系统 期货指标公式大全 最准的期货指标源码 看期货涨跌最简单的方法文华财经指标公式源码

交易的动机必须来自于内心&#xff0c;一种解决问题的执着。在整个交易生涯的漫长岁月里&#xff0c;无法始终保持这种热忱。除非亲身体验&#xff0c;否则很难理解这种疯狂的热忱。这是一种高度的专注&#xff0c;其他一切好像都不存在&#xff0c;视野之内没有其他的东西。这…

【STL】之 vector 使用方法及模拟实现

前言&#xff1a; 本文主要讲在C STL库中vector容器的使用方法和底层的模拟实现~ 成员变量的定义&#xff1a; 对于vector容器&#xff0c;我们首先采用三个成员变量去进行定义&#xff0c;分别是&#xff1a; private:iterator _start; // 指向数据块的开始iterator _finish…

论文解读(10)-图神经网络

加油&#xff0c;继续看论文。 这次学图神经网络&#xff0c;这个概念经常在其他论文里出现&#xff0c;所以我想先学习一下这方面的知识。 参考&#xff1a; 【图神经网络综述】一文道尽GNN原理、框架和应用-CSDN博客 【图神经网络】10分钟掌握图神经网络及其经典模型_图神经…

网络爬虫必备工具:代理IP科普指南

文章目录 1. 网络爬虫简介1.1 什么是网络爬虫&#xff1f;1.2 网络爬虫的应用领域1.3 网络爬虫面临的主要挑战 2. 代理IP&#xff1a;爬虫的得力助手2.1 代理IP的定义和工作原理2.2 为什么爬虫需要代理IP&#xff1f;2.3 代理IP如何解决爬虫的常见问题&#xff1f; 3. 代理IP的…