最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

封裝一個(gè)更易用的Dialog組件過程詳解

 更新時(shí)間:2022年05月18日 11:38:06   作者:WinRTl  
這篇文章主要為大家介紹了封裝一個(gè)更易用的Dialog組件過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

場(chǎng)景

在項(xiàng)目中,我們經(jīng)常會(huì)遇到使用彈窗的場(chǎng)景,但有時(shí)組件庫(kù)自帶的彈窗不能滿足我們的需求,需要我們自己封裝,這時(shí)我們?nèi)绾稳プ远x一個(gè)更加方便調(diào)用的彈窗?

搭建環(huán)境

首先我們需要搭建一個(gè)Vue3+ts的環(huán)境。

用vite的官方模板:

yarn create vite demo-app --template vue-ts

進(jìn)入并安裝依賴

cd demo-app
yarn

依賴安裝完成后啟動(dòng)app

yarn dev

創(chuàng)建組件

先在src/components目錄下創(chuàng)建MyDialog.vue,搭建一個(gè)組件的基本框架

<script lang="ts" setup>
import { ref, reactive } from "vue";
defineProps({
  message: {
    type: String,
    default: "",
  },
  title: {
    type: String,
    default: "",
  },
});
const emits = defineEmits<{
  (e: "confirm"): void;
  (e: "close"): void;
}>();
const visible = ref(true);
function clickConfirm() {
  console.log("確認(rèn)");
  emits("confirm");
}
function clickClose() {
  console.log("取消");
  emits("close");
}
</script>
<template>
  <div class="wrap" v-if="visible">
    <div class="container">
      <div class="title">{{ title }}</div>
      <div class="content">
        <div>{{ message }}</div>
      </div>
      <div class="controll">
        <button @click="clickConfirm">確認(rèn)</button>
        <button @click="clickClose">取消</button>
      </div>
    </div>
  </div>
</template>
<style scoped>
.wrap {
  position: absolute;
  top: 0;
  left: 0;
  background: rgba(15, 15, 15, 0.5);
  width: 100%;
  height: 100%;
}
.container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: 300px;
  min-height: 200px;
  padding: 10px;
  background: white;
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1;
  padding: 10px;
  text-align: left;
}
.title {
  min-height: 30px;
}
.controll {
  display: flex;
  width: 100%;
  justify-content: space-around;
}
</style>

創(chuàng)建調(diào)用組件的hook函數(shù)

在src目錄下創(chuàng)建hooks目錄,然后再hooks目錄下創(chuàng)建useMyDialog.ts.

函數(shù)調(diào)用組件我們需要:

  • 將組件轉(zhuǎn)換成VNode
  • 將VNode轉(zhuǎn)換成DOM然后渲染到頁(yè)面
import { createVNode, render, ComponentPublicInstance } from "vue";
export default function useMyDialog(option?: any) {
  const props = {
    ...option,
  };
  const vm = createVNode(MyDialog, props);
  const container = document.createElement("div");
  render(vm, container);
  document.querySelector("#app")?.appendChild(container.firstElementChild!);
}

ps:

container.firstElementChild!中的!表示container.firstElementChild不為null或者undefined

接下來我們?cè)贏pp.vue中測(cè)試一下

<script setup lang="ts">
import useMyDialog from "./hooks/useMyDialog";
function showDialog() {
  useMyDialog({
    message: "test1",
    onClose: () => {
      console.log("self");
    },
  });
}
</script>
<template>
  <button @click="showDialog">顯示Dialog</button>
</template>

Dialog的緩存、隱藏

隱藏

我們需要將close返回出去,這樣我們就可以手動(dòng)調(diào)用close函數(shù)關(guān)閉Dialog.

在useMyDialog.ts中添加

import { ComponentPublicInstance,VNode } from "vue";
export default function useMyDialog(option?: any) {
  const userCloseFn = option?.onClose;
  props.onClose = () =&gt; {
    close();
    userCloseFn ?? userCloseFn();
  };
  function close(vm: VNode) {
    (
      vm.component!.proxy as ComponentPublicInstance&lt;{ visible: boolean }&gt;
    ).visible = false;
  }
  return {
    close: close.bind(null, vm),
  }
}

緩存

現(xiàn)在每次點(diǎn)擊顯示Dialog按鈕時(shí)都會(huì)創(chuàng)建一個(gè)新的組件實(shí)例,這不是我們的預(yù)期,所以我們需要將組件進(jìn)行緩存.

在useMyDialog.ts中添加

import { ComponentPublicInstance } from 'vue'
const instances: any[] = [];
export default function useMyDialog(option?: any) {
  const tempVm: any = instances.find(
    (item) =>
      `${item.vm.props?.message ?? ""}` === `${(option as any).message ?? ""}`
  );
  if (tempVm) {
    (
      tempVm.vm.component!.proxy as ComponentPublicInstance<{
        visible: boolean;
      }>
    ).visible = true;
    return {
      close: close.bind(null, tempVm.vm),
    };
  }
}

完整代碼

src/hooks/useMyDialog.ts

import { createVNode, render, ComponentPublicInstance, VNode } from "vue";
import MyDialog from "../components/MyDialog.vue";
const instances: any[] = [];
export default function useMyDialog(option?: any) {
  const props = {
    ...option,
  };
  const userCloseFn = option?.onClose;
  props.onClose = () => {
    close(vm);
    userCloseFn ?? userCloseFn();
  };
  function close(vm: VNode) {
    (
      vm.component!.proxy as ComponentPublicInstance<{ visible: boolean }>
    ).visible = false;
  }
  const tempVm: any = instances.find(
    (item) =>
      `${item.vm.props?.message ?? ""}` === `${(option as any).message ?? ""}`
  );
  if (tempVm) {
    (
      tempVm.vm.component!.proxy as ComponentPublicInstance<{
        visible: boolean;
      }>
    ).visible = true;
    return {
      close: close.bind(null, tempVm.vm),
    };
  }
  const vm = createVNode(MyDialog, props);
  const container = document.createElement("div");
  render(vm, container);
  document.querySelector("#app")?.appendChild(container.firstElementChild!);
  instances.push({ vm });
  return {
    close: close.bind(null, vm),
  };
}

總結(jié)

這種調(diào)用方式不局限于Dialog組件,其他有需要的業(yè)務(wù)組件也可以通過這種封裝方式去簡(jiǎn)化調(diào)用.

以上代碼其實(shí)是element-plus的message組件的簡(jiǎn)化版,有興趣的可以去看看element-plus的源碼,鏈接貼在下方.

element-plus源碼

以上就是封裝一個(gè)更易用的Dialog組件過程詳解的詳細(xì)內(nèi)容,更多關(guān)于Dialog組件封裝的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue使用drag與drop實(shí)現(xiàn)拖拽的示例代碼

    vue使用drag與drop實(shí)現(xiàn)拖拽的示例代碼

    本篇文章主要介紹了vue使用drag與drop實(shí)現(xiàn)拖拽的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • vue+vant 上傳圖片需要注意的地方

    vue+vant 上傳圖片需要注意的地方

    這篇文章主要介紹了vue+vant 上傳圖片需要注意的地方,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下
    2021-01-01
  • Vue項(xiàng)目新一代狀態(tài)管理工具Pinia的使用教程

    Vue項(xiàng)目新一代狀態(tài)管理工具Pinia的使用教程

    pinia是一個(gè)輕量級(jí)的狀態(tài)管理庫(kù),屬于 vue3 生態(tài)圈新的成員之一,下面這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目新一代狀態(tài)管理工具Pinia的使用教程,需要的朋友可以參考下
    2022-11-11
  • vue中created和mounted的區(qū)別淺析

    vue中created和mounted的區(qū)別淺析

    這篇文章主要給大家介紹了關(guān)于vue中created和mounted區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • vue實(shí)現(xiàn)戶籍管理系統(tǒng)

    vue實(shí)現(xiàn)戶籍管理系統(tǒng)

    這篇文章主要介紹了Vue實(shí)現(xiàn)戶籍管理系統(tǒng),戶籍信息的添加與刪除,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Element UI 自定義正則表達(dá)式驗(yàn)證方法

    Element UI 自定義正則表達(dá)式驗(yàn)證方法

    今天小編就為大家分享一篇Element UI 自定義正則表達(dá)式驗(yàn)證方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開功能的實(shí)現(xiàn)

    vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開功能的實(shí)現(xiàn)

    這篇文章主要介紹了vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • vue如何使用HMAC-SHA256簽名算法

    vue如何使用HMAC-SHA256簽名算法

    這篇文章主要介紹了vue使用HMAC-SHA256簽名算法的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • vue中的vue-router?query方式和params方式詳解

    vue中的vue-router?query方式和params方式詳解

    這篇文章主要介紹了vue中的vue-router?query方式和params方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue:el-input輸入時(shí)限制輸入的類型操作

    vue:el-input輸入時(shí)限制輸入的類型操作

    這篇文章主要介紹了vue:el-input輸入時(shí)限制輸入的類型操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評(píng)論

凤山县| 兴海县| 台东市| 漯河市| 西吉县| 瑞丽市| 无极县| 睢宁县| 大冶市| 河北区| 留坝县| 文安县| 车险| 舒兰市| 瑞昌市| 丰城市| 军事| 平顺县| 东宁县| 油尖旺区| 黄山市| 十堰市| 积石山| 临潭县| 泸水县| 东港市| 中西区| 石棉县| 安阳县| 象山县| 嘉义县| 海南省| 北票市| 华容县| 根河市| 伊川县| 东乌珠穆沁旗| 榆树市| 莱西市| 阳原县| 波密县|