龙空技术网

Vue3 函数式组件 - confirm实现

爱摸鱼的程序员 487

前言:

此刻咱们对“js中的confirm函数”大概比较看重,你们都想要分析一些“js中的confirm函数”的相关文章。那么小编同时在网摘上网罗了一些对于“js中的confirm函数””的相关资讯,希望小伙伴们能喜欢,小伙伴们一起来学习一下吧!

在做后台项目时候,使用声明式组件比较多,就是写一个.vue文件,在里面写 template、script、style哪里需要,就在哪里导入。

而对于前台项目而言,我们期望可以直接通过方法的形式调用,利用函数式组件,在封装时除了要写.vue,还要多一个手动渲染和卸载的步骤。我们可以通过 h 函数可以生成一个vnode,该vnode利用render函数渲染和卸载。

<template>  <!-- 声明式组件 -->  <el-row class="mb-4">    <el-button type="primary"  @click="open">Primary</el-button>    <el-button type="success">Success</el-button>  </el-row></template><script lang="ts" setup>// 函数式组件import { ElMessage } from 'element-plus'// 通常是在某个交互完成时触发const open = () => {  ElMessage('this is a message.')}</script>

1.1. h 函数

Vue中,提供了一个h()函数用于创建 vnodes。创建虚拟节点时会多种不同情况,比如传入标签名和属性,就会创建一个标签的虚拟节点,传入组件名和属性,就会创建一个组件的虚拟节点。

h()接收三个参数(要渲染的dom,attrs 对象,子元素)

h()有一个更准确的名称是 createVnode(),考虑到多次使用,一个简短的名字会更省力。

import { h } from 'vue'// 使用 h 创建普通标签  const vnode1 = h('div', { class: 'bar', innerHTML: 'hello' })// vnode1 等同于 <div class="bar">hello</div>  // 使用 h 创建组件const vnode2 =  h(myComponent, {		//组件的属性    title: '测试'})// vnode2 等同于 <myComponent title="测试"/>

1.2. render 函数

render()接收标签或者组件的 vnode,将其渲染成为真实 DOM,并挂载到一个指定的父节点上。

import { h, render } from 'vue'render(vnode2, document.body)render(null, document.body)     // 当第1个参数为null时,相当于从父节点上移除此组件。

1.3. confirm组件

以实现 comfirm 组件为例,具体实现逻辑如下:

创建一个 confirm 组件创建一个 comfirm.js 模块,该模块返回一个 promise同时利用 h()生成 confirm.vue的 vode最后利用 render函数,渲染 vnode到 body 中1.3.1. 构建 confirm.vue 组件

<script setup>  import { ref, onMounted } from 'vue'  // 因为将来 confirm 组件是以方法调用的形式展示,所以我们需要手动导入需要使用到的其他通用组件  import mButton from '@/libs/button/index.vue'  const props = defineProps({    // 标题    title: {      type: String    },    // 描述    content: {      type: String,      required: true    },    // 取消按钮文本    cancelText: {      type: String,      default: '取消'    },    // 确定按钮文本    confirmText: {      type: String,      default: '确定'    },    // 取消按钮事件    cancelHandler: {      type: Function    },    // 确定按钮事件    confirmHandler: {      type: Function    },    // 关闭 confirm 的回调    close: {      type: Function    }  })  // 控制显示处理  const isVisible = ref(false)  /**   * confirm 展示   */  const show = () => {    isVisible.value = true  }  /**   * 处理动画 (render 函数的渲染,会直接进行)   */  onMounted(() => {    show()  })  /**   * 取消事件   */  const onCancelClick = () => {    if (props.cancelHandler) {      props.cancelHandler()    }    close()  }  /**   * 确定事件   */  const onConfirmClick = () => {    if (props.confirmHandler) {      props.confirmHandler()    }    close()  }  // 关闭动画处理时间  const duration = '0.5s'  /**   * 关闭事件,保留动画执行时长   */  const close = () => {    isVisible.value = false    // 延迟一段时间进行关闭    setTimeout(() => {      if (props.close) {        props.close()      }    }, parseInt(duration.replace('0.', '').replace('s', '')) * 100)  }</script><template>  <!-- 基于 tailwindcss 创建对应样式 -->  <div>    <!-- 蒙版 -->    <transition name="fade">      <div        v-if="isVisible"        @click="close"        class="w-screen h-screen bg-zinc-900/80 z-40 fixed left-0 top-0"        ></div>    </transition>    <!-- 内容 -->    <transition name="up">      <div        v-if="isVisible"        class="w-[80%] fixed top-1/3 left-[50%] translate-x-[-50%] z-50 px-2 py-1.5 rounded-sm border dark:border-zinc-600 cursor-pointer bg-white dark:bg-zinc-800 xl:w-[35%]"        @click="close"        >        <!-- 标题 -->        <div class="text-lg font-bold text-zinc-800 dark:text-zinc-200 mb-2">{{ title }}</div>        <!-- 文本 -->        <div class="text-base tex-zinc-800 dark:text-zinc-200 mb-2">{{ content }}</div>        <!-- 按钮 -->        <div class="flex justify-end">          <m-button type="info" class="mr-2" @click="onCancelClick">{{ cancelText }}</m-button>          <m-button type="primary" @click="onConfirmClick">{{ confirmText }}</m-button>        </div>      </div>    </transition>  </div></template><style lang="scss" scoped>  .fade-enter-active,  .fade-leave-active {    transition: all v-bind(duration);  }  .fade-enter-from,  .fade-leave-to {    opacity: 0;  }  .up-enter-active,  .up-leave-active {    transition: all v-bind(duration);  }  .up-enter-from,  .up-leave-to {    opacity: 0;    transform: translate3d(-50%, -100%, 0);  }</style>

1.3.2. 创建 confirm.js 模块

import { h, render } from 'vue'import confirmComponent from './confirm.vue'/** * @param {*} title 标题 * @param {*} content 内容 * @param {*} cancelText 取消文本 * @param {*} confirmText 确认文本 */export const confirmBox = (title, content, cancelText, confirmText) => {  return new Promise((resolve, reject) => {    // 不传入标题,只传入内容时    if (title && !content) {      content = title      title = ''    }    // 取消按钮事件    const cancelHandler = () => {      reject(new Error('取消按钮点击'))    }    // 确定按钮事件    const confirmHandler = () => {      resolve()    }    // 关闭弹层事件    const close = () => {      render(null, document.body)    }        // 1. 生成 vnode    const vnode = h(confirmComponent, {      title,      content,      cancelText,      confirmText,      cancelHandler,      confirmHandler,      close    })    // 2. render 渲染    render(vnode, document.body)  })}

1.3.3. 触发 comfirm 组件

import  { confirmBox } from './confirm.js'const onDeleteAllClick = () => {  confirmBox('要删除所有历史记录吗?').then(() => {    // 点击确定后执行事件    ...  })  .catch(()=>{    // 点击取消后执行事件    ...  })}

作者:LZR

链接:

标签: #js中的confirm函数 #jsconfirm用法 #jsconfirm用法 close #js获取控件的属性