欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

封裝一個更易用的Dialog組件過程詳解

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

場景

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

搭建環(huán)境

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

用vite的官方模板:

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

進入并安裝依賴

cd demo-app
yarn

依賴安裝完成后啟動app

yarn dev

創(chuàng)建組件

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

<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("確認");
  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">確認</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然后渲染到頁面
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

接下來我們在App.vue中測試一下

<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返回出去,這樣我們就可以手動調(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)在每次點擊顯示Dialog按鈕時都會創(chuàng)建一個新的組件實例,這不是我們的預(yù)期,所以我們需要將組件進行緩存.

在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ù)組件也可以通過這種封裝方式去簡化調(diào)用.

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

element-plus源碼

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

相關(guān)文章

  • Vue?github用戶搜索案例分享

    Vue?github用戶搜索案例分享

    這篇文章主要介紹了Vue?github用戶搜索案例分享,文章基于Vue的相關(guān)資料展開對主題的詳細介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-04-04
  • Vue組件教程之Toast(Vue.extend 方式)詳解

    Vue組件教程之Toast(Vue.extend 方式)詳解

    這篇文章主要給大家介紹了關(guān)于Vue組件教程之Toast(Vue.extend 方式)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-01-01
  • vue3 provide與inject的使用小技巧分享

    vue3 provide與inject的使用小技巧分享

    這篇文章主要介紹了vue3 provide與inject的使用小技巧,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue3獲取和操作DOM元素的項目實踐

    Vue3獲取和操作DOM元素的項目實踐

    在Vue3中,有時我們需要直接操作DOM節(jié)點,本文主要介紹了Vue3獲取和操作DOM元素的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-08-08
  • Vue實現(xiàn)移動端拖拽交換位置

    Vue實現(xiàn)移動端拖拽交換位置

    這篇文章主要為大家詳細介紹了Vue實現(xiàn)移動端拖拽交換位置,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • vuex中store存儲store.commit和store.dispatch的用法

    vuex中store存儲store.commit和store.dispatch的用法

    這篇文章主要介紹了vuex中store存儲store.commit和store.dispatch的用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Vue中使用create-keyframe-animation與動畫鉤子完成復(fù)雜動畫

    Vue中使用create-keyframe-animation與動畫鉤子完成復(fù)雜動畫

    這篇文章主要介紹了Vue中使用create-keyframe-animation與動畫鉤子完成復(fù)雜動畫,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • Vue首屏性能優(yōu)化組件知識點總結(jié)

    Vue首屏性能優(yōu)化組件知識點總結(jié)

    在本篇文章里小編給大家整理了一篇關(guān)于Vue首屏性能優(yōu)化組件知識點總結(jié),有需要的朋友們可以跟著學習下。
    2021-11-11
  • vue項目前端錯誤收集之sentry教程詳解

    vue項目前端錯誤收集之sentry教程詳解

    Sentry 是一個開源的錯誤追蹤工具,可以幫助開發(fā)人員實時監(jiān)控和修復(fù)系統(tǒng)中的錯誤。這篇文章主要介紹了vue項目前端錯誤收集之sentry,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • 詳解Vue 動態(tài)組件與全局事件綁定總結(jié)

    詳解Vue 動態(tài)組件與全局事件綁定總結(jié)

    這篇文章主要介紹了詳解Vue 動態(tài)組件與全局事件綁定總結(jié),從示例中發(fā)現(xiàn)并解決問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論