記錄--vue3函數式彈窗

来源:https://www.cnblogs.com/smileZAZ/Undeclared/17959269
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 最近接到一個需求,需要在一些敏感操作進行前要求輸入賬號和密碼,然後將輸入的賬號和密碼加到介面請求的header裡面。如果每個頁面都去手動導入彈窗組件,在點擊按鈕後彈出彈窗。再拿到彈窗返回的賬號密碼後去請求介面也太累了,那麼有沒有更簡 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

最近接到一個需求,需要在一些敏感操作進行前要求輸入賬號和密碼,然後將輸入的賬號和密碼加到介面請求的header裡面。如果每個頁面都去手動導入彈窗組件,在點擊按鈕後彈出彈窗。再拿到彈窗返回的賬號密碼後去請求介面也太累了,那麼有沒有更簡單的實現方式呢?

函數式彈窗的使用場景

首先我們來看看什麼是函數式彈窗?

函數式彈窗是一種使用函數來創建彈窗的技術。它可以簡化彈窗的使用,只需要在需要彈窗的地方調用函數就可以了。那麼這裡使用函數式彈窗就能完美的解決我們的問題。

我們只需要封裝一個showPasswordDialog函數,調用該函數後會彈出一個彈窗。該函數會返回一個resolve後的值就是賬號密碼的Promise。然後在http請求攔截器中加一個needValidatePassword欄位,攔截請求時如果該欄位為true,就await調用showPasswordDialog函數。拿到賬號和密碼後塞到請求的header裡面。這樣就我們就只需要在發起請求的地方加一個needValidatePassword: true配置就行了。

先來實現一個彈窗組件

這個是簡化後template中的代碼,和Element Plus官網中的demo代碼差不多,沒有什麼說的。

<template>
  <el-dialog :model-value="visible" title="賬號和密碼" @close="handleClose">
    <!-- 省略賬號、密碼表單部分... -->
    <el-button type="primary" @click="submitForm()">提交</el-button>
  </el-dialog>
</template>
這個是簡化後的script代碼,大部分和Element Plus官網的demo代碼差不多。需要註意的是我們這裡將close關閉事件和confirm確認事件定義在了props中,而不是在emits中,因為後面函數式組件會通過props將這兩個回調傳入進來。具體的我們下麵會講。
<script setup lang="ts">
interface Props {
  visible: boolean;
  close?: () => void;
  confirm?: (data) => void;
}

const props = defineProps<Props>();

const emit = defineEmits(["update:visible"]);

const submitForm = async () => {
  // 省略validate表單校驗的代碼
  // 這裡的data為表單中輸入的賬號密碼
  props.confirm?.(data);
  handleClose();
};

const handleClose = () => {
  emit("update:visible", false);
  props.close?.();
};
</script>

再基於彈窗組件實現函數式彈窗

createApp函數和app.mount方法

createApp函數會創建和返回一個vue應用實例,也就是我們平時常說的app,該函數接受兩個參數。第一個參數為接收一個組件,也就是我們平時寫的vue文件。第二個參數為可選的對象,這個對象會傳遞給第一個參數組件的props

舉個例子:

import MyComponent from "./MyComponent"

const app = createApp(MyComponent, {
  visible: true
})

在這個例子中我們基於MyComponent組件生成了一個app應用實例,如果MyComponent組件的props中有定義visible,那麼visible就會被賦值為true

調用createApp函數創建的這個應用實例app實際就是在記憶體中創建的一個對象,並沒有渲染到瀏覽器的dom上面。這個時候我們就要調用應用實例app暴露出來的mount方法將這個組件掛載到真實的dom上面去。mount方法接收一個“容器”參數,用於將組件掛載上去,可以是一個實際的 DOM 元素或是一個 CSS 選擇器字元串。比如下麵這個例子是將組件掛載到body上面:

app.mount(document.body)

app提供了很多方法和屬性,詳見 vue官網

封裝一個showPasswordDialog函數

首先我們來看看期望如何使用showPasswordDialog函數?

我們希望showPasswordDialog函數返回一個Promiseresolve的值就是彈窗中輸入的表單。例如,我們可以使用以下代碼使用showPasswordDialog函數:

try {
  // 調用這個就會彈出彈窗
    const res: RuleForm = await showPasswordDialog();
    // 這個res就是輸入的賬號密碼
    console.log("res", res);
  } catch (error) {
    console.log(error);
  }

具體如何實現showPasswordDialog函數?

經過上面的介紹我們知道了可以調用createApp函數傳入指定組件生成app,然後使用app.mount方法將這個組件掛載到指定的dom上面去。那麼現在思路就清晰了,我們只需要將我們前面實現的彈窗組件作為第一個參數傳遞給createApp函數。第二個參數傳入一個對象給彈窗組件的props,用以控制打開彈窗和註冊彈窗關閉和確認的事件回調。下麵是實現的showPasswordDialog函數

import { App, createApp } from "vue";
import PasswordDialog from "./index.vue";
// 這個index.vue就是我們前面實現的彈窗組件

export async function showPasswordDialog(): Promise<RuleForm> {
  return new Promise((resolve, reject) => {
    let mountNode = document.createElement("div");
    let dialogApp: App<Element> | undefined = createApp(PasswordDialog, {
      visible: true,
      close: () => {
        if (dialogApp) {
          dialogApp.unmount();
          document.body.removeChild(mountNode);
          dialogApp = undefined;
          reject("close");
        }
      },
      confirm: (res: RuleForm) => {
        resolve(res);
        dialogApp?.unmount();
        document.body.removeChild(mountNode);
        dialogApp = undefined;
      },
    });
    document.body.appendChild(mountNode);
    dialogApp.mount(mountNode);
  });
}

在這個showPasswordDialog函數中我們先創建了一個div元素,再將彈窗組件傳遞給了createApp函數生成一個dialogApp的實例。然後將創建的div元素掛載到body上面,再調用mount方法將我們的彈窗組件掛載到創建的div元素上,至此我們實現了通過函數式調用將彈窗組件渲染到body中。

現在我們再來看看傳入到createApp函數的第二個對象參數,我們給這個對象分別傳入了visible屬性、closeconfirm回調方法,分別會賦值給彈窗組件props中的visiblecloseconfirm

彈窗組件中觸發關閉事件時會調用props.close?.(),實際這裡就是在調用我們傳入的close回調方法。在這個方法中我們調用了實例的unmount方法卸載組件,然後將創建的彈窗組件dom從body中移除,並且返回一個rejectPromise

當我們將賬號和密碼輸入完成後,會調用props.confirm?.(ruleForm),這裡的ruleForm就是我們表單中的賬號和密碼。實際這裡就是在調用我們傳入的confirm回調方法,接下來同樣也是卸載組件和移除彈窗組件生成的dom,並且返回一個resolve值為賬號密碼表單的Promise

總結

這篇文章主要介紹瞭如何創建函數式彈窗:

  1. 創建一個常規的彈窗組件,有點不同的是closeconfirm事件不是定義在emits中,而是作為回調定義在props中。

  2. 創建一個showPasswordDialog函數,該函數返回一個Promiseresolve的值就是我們彈窗中輸入的表單。

  3. 調用createApp函數將步驟一的彈窗組件作為第一個參數傳入,並且第二個對象參數中傳入屬性visibletrue打開彈窗和註入彈窗close關閉和confirm確認的回調。

  4. 使用者只需await調用showPasswordDialog就可以打開彈窗和拿到表單中填入的賬號和密碼。

本文轉載於:

https://juejin.cn/post/7322229620391673908

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1月9日,計世資訊(CCW Research)發佈《2022-2023年中國信創資料庫行業市場研究報告》(以下簡稱“報告”),從產品技術能力和市場及戰略能力兩個維度對我國主要資料庫產品服務商進行競爭力分析。其中,中國電信天翼雲憑藉其產品豐富的管理功能、靈活的部署架構,位列雲資料庫產品領域領導者象限。 ...
  • 作者:俊達 引言 MySQL是MySQL安裝包預設的客戶端,該客戶端程式通常位於二進位安裝包的bin目錄中,或者通過rpm安裝包安裝mysql-community-client,是資料庫管理系統的重要組成部分。MySQL客戶端不僅僅是一個簡單的軟體工具,更是連接用戶與資料庫之間的橋梁,對於有效地使用 ...
  • 作者:櫰木 環境準備 本次使用到的二進位軟體包目錄為:系統初始化前提是操作系統已完成安裝、各個主機之間網路互通,系統常用命令已安裝,本預設這些前提條件已具備,不在闡述。 1 主機環境初始化 安裝centos系統完成後需要對主機進行初始化配置和驗證工作,在所有主機上(hd1.dtstack.com-h ...
  • 摘要 隨著任務數量、任務類型需求不斷增長,對我們的數據開發平臺提出了更高的要求。本文主要分享我們將調度引擎升級到 Apache DolphinScheduler 的實踐經驗,以及對數據開發平臺的一些思考。 1. 背景 首先介紹下我們的大數據平臺架構: 數據計算層承接了全公司的數據開發需求,負責運行各 ...
  • 一、背景 為瞭解決應卡頓,分析耗時。 二、原理 Looper中的loop方法: public static void loop() { ... for (;;) { ... // This must be in a local variable, in case a UI event sets th ...
  • ☞ Github ☜ ☞ Gitee ☜ 說明 Binder作為Android系統跨進程通信的核心機制。網上也有很多深度講解該機制的文章,如: Android跨進程通信詳解Binder機制原理 Android系統核心機制Binder【系列】 這些文章和系統源碼可以很好幫助我們理解Binder的實現原 ...
  • Android 中 View 的佈局是一個樹形結構,各個 ViewGroup 和 View 是按樹形結構嵌套佈局的,從而會出現用戶觸摸的位置坐標可能會落在多個 View 的範圍內,這樣就不知道哪個 View 來響應這個事件,為瞭解決這一問題,就出現了事件分發機制。 ...
  • 截止到2024-1-11,使用的主要軟體的版本如下: 軟體實體 版本 react-native 0.73.1 react 18.2.0 react-native-cli 2.0.1 Android Studio 2022.3.1 Patch3 Android SDK Android SDK Plat ...
一周排行
    -Advertisement-
    Play Games
  • 前言 插件化的需求主要源於對軟體架構靈活性的追求,特別是在開發大型、複雜或需要不斷更新的軟體系統時,插件化可以提高軟體系統的可擴展性、可定製性、隔離性、安全性、可維護性、模塊化、易於升級和更新以及支持第三方開發等方面的能力,從而滿足不斷變化的業務需求和技術挑戰。 一、插件化探索 在WPF中我們想要開 ...
  • 歡迎ReaLTaiizor是一個用戶友好的、以設計為中心的.NET WinForms項目控制項庫,包含廣泛的組件。您可以使用不同的主題選項對項目進行個性化設置,並自定義用戶控制項,以使您的應用程式更加專業。 項目地址:https://github.com/Taiizor/ReaLTaiizor 步驟1: ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 一、ReZero簡介 ReZero是一款.NET中間件 : 全網唯一開源界面操作就能生成API , 可以集成到任何.NET6+ API項目,無破壞性,也可讓非.NET用戶使用exe文件 免費開源:MIT最寬鬆協議 , 一直從事開源事業十年,一直堅持開源 1.1 純ReZero開發 適合.Net Co ...
  • 一:背景 1. 講故事 停了一個月沒有更新文章了,主要是忙於寫 C#內功修煉系列的PPT,現在基本上接近尾聲,可以回頭繼續更新這段時間分析dump的一些事故報告,有朋友微信上找到我,說他們的系統出現了大量的http超時,程式不響應處理了,讓我幫忙看下怎麼回事,dump也抓到了。 二:WinDbg分析 ...
  • 開始做項目管理了(本人3年java,來到這邊之後真沒想到...),天天開會溝通整理需求,他們講話的時候忙裡偷閑整理一下常用的方法,其實語言還是有共通性的,基本上看到方法名就大概能猜出來用法。出去打水的時候看到外面太陽好好,真想在外面坐著曬太陽,回來的時候好兄弟三年前送給我的鍵盤D鍵不靈了,在打"等待 ...