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

Vue3使用 createApp 自定義通用Dialog的方法

 更新時間:2024年01月16日 09:42:38   作者:小小楠瓜子  
這篇文章主要介紹了Vue3使用 createApp 自定義通用Dialog的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

最近在做一個項目的技術(shù)棧升級,從Vue2升級至Vue3,Vue2中有一個通用的全局 Dialog 方法,是通過 Vue.extend 來實現(xiàn)的,具體請看下方的Vue2代碼:

一、main.js 中定義通用方法

Vue.prototype.$dialog = {
    open(component, args) {
        return new Promise((resolve, reject) => {
            let Dialog = Vue.extend(component);
            var $vm = new Dialog({
                el: document.createElement("div"),
                router,
                store,
                eventBus: new Vue(),
            });
            var node = document.body.appendChild($vm.$el);
            $vm.open(args).then(
                result => {
                    if (resolve) {
                        resolve(result);
                    }
                    node.remove();
                    $vm.$destroy();
                },
                (arg) => {
                    if (reject) {
                        reject(arg)
                    }
                    node.remove();
                    $vm.$destroy();
                }
            );
        });
    }
};

二、定義通用 DialogLayout.vue

<template>
  <el-dialog :title="title" :visible.sync="visible" :center="center" :modal="true" :width="width"
    class="n-dialog-layout" :class="$slots.footer ? 'has-footer' : ''" :modal-append-to-body="true"
    :append-to-body="true" :lock-scroll="true" :show-close="showClose" :close-on-click-modal="false"
    :before-close="beforeClose" @opened="$emit('opened')" @close="handleClose" :fullscreen="fullscreen">
    <slot name="title" slot="title"></slot>
    <slot></slot>
    <slot name="footer" slot="footer"></slot>
  </el-dialog>
</template>
<script>
export default {
  name: "n-dialog-layout",
  props: {
    title: {},
    fullscreen: {
      default: false,
      type: Boolean,
    },
    width: {
      default: "50%",
      type: String,
    },
    showClose: {
      default: true,
      type: Boolean,
    },
    center: {
      default: false,
      type: Boolean,
    },
    beforeClose: {
      default: (done) => {
        done();
      },
      type: Function,
    },
  },
  data() {
    return {
      promise: null,
      resolve: null,
      reject: null,
      visible: false,
      confirmClose: false,
      result: {},
    };
  },
  methods: {
    open() {
      this.confirmClose = false;
      this.promise = new Promise((resolve, reject) => {
        this.resolve = resolve;
        this.reject = reject;
        this.visible = true;
      });
      return this.promise;
    },
    close(result) {
      this.confirmClose = true;
      this.result = result;
      this.visible = false;
    },
    cancel(arg) {
      this.confirmClose = false;
      this.result = arg;
      this.visible = false;
    },
    handleClose() {
      if (this.confirmClose) {
        this.resolve(this.result);
      } else {
        this.reject(this.result);
      }
    },
  },
};
</script>

三、 定義需要通過 Dialog 打開的具體頁面

<template>
  <n-dialog-layout :title='l("ChangePassword")' ref="dialog">
    <div class="info" v-loading="loading">
      <el-form ref="passwordForm" status-icon size="large" :model="item" label-width="100px" label-position="top"
        class="m-b" :rules="rules">
        <el-form-item :label="l('CurrentPassword')" prop="currentPassword">
          <el-input type="password" v-model="item.currentPassword"></el-input>
        </el-form-item>
        <el-form-item :label="l('NewPassword')" prop="password">
          <el-input type="password" v-model="item.password"></el-input>
        </el-form-item>
        <el-form-item :label="l('NewPasswordRepeat')" prop="confirmPassword">
          <el-input type="password" v-model="item.confirmPassword"></el-input>
        </el-form-item>
      </el-form>
    </div>
    <template slot="footer">
      <span class="dialog-footer">
        <el-button @click="cancel()" size="large">{{ l('Cancel') }}</el-button>
        <el-button type="primary" @click="ok()" size="large">{{ l('Save') }}</el-button>
      </span>
    </template>
  </n-dialog-layout>
</template>

四、具體使用

import ChangePasswordDialog from './dialog/changePassword';
this.$dialog.open(ChangePasswordDialog).then(res => {
	this.save();
})

五、如何用 Vue3 的語法來重寫 main.js 中的 $dialog 方法?

  • app.config.globalProperties 代替 Vue.prototype;
  • 用什么來代替 Vue.extend 呢?這里使用的 createApp;
  • createApp 代替 Vue.extend 以后遇到的問題,例如:無法使用 ElementPlus 的UI控件、無法解析全局注冊的組件

問題1:無法使用 ElementPlus 的UI控件、無法解析全局注冊的組件
回答: 使用 createApp 創(chuàng)建出來的應(yīng)用實例,use ElementPlus,register 里面是我放的全局通用方法和組件
問題2:為什么Dialog.mount 的節(jié)點是寫死的?而不是 動態(tài) document.createElement ?
回答:實踐過程中發(fā)現(xiàn) document.createElement 通過 proxy.$dialog.open(ChangePasswordDialog) 打開正常,但是加上 .then() 就會出現(xiàn)關(guān)閉兩次才可以正常關(guān)閉的情況

createdApp 代替 Vue.extend 實現(xiàn)創(chuàng)建一個“子類”,實現(xiàn)同樣的效果,先看代碼

app.config.globalProperties.$dialog = {
  open(component, args) {
    return new Promise((resolve, reject) => {
      const Dialog = createApp(component);
      Dialog.use(ElementPlus);
      Dialog.use(register);
      const $vm = Dialog.mount("#Dialog");
      const node = document.body.appendChild($vm.$el);
      $vm.open(args).then(
        (result) => {
          if (resolve) {
            resolve(result);
          }
          node.remove();
        },
        (arg) => {
          if (reject) {
            reject(arg);
          }
          node.remove();
        }
      );
    });
  },
};

具體效果如下

比較靈活,可插拔的通用Dialog

到此這篇關(guān)于Vue3 如何優(yōu)雅的使用 createApp 自定義通用Dialog的文章就介紹到這了,更多相關(guān)Vue3自定義通用Dialog內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue?項目中Echarts?5使用方法詳解

    Vue?項目中Echarts?5使用方法詳解

    這篇文章主要為大家介紹了Vue?項目中Echarts?5使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • vue接入高德地圖繪制扇形效果的案例詳解

    vue接入高德地圖繪制扇形效果的案例詳解

    這篇文章主要介紹了vue接入高德地圖繪制扇形,需求是有一個列表,列表的數(shù)據(jù)就是一個基站信息,包含基站的經(jīng)緯度信息和名字,基站下面又分扇區(qū),本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • iview實現(xiàn)動態(tài)表單和自定義驗證時間段重疊

    iview實現(xiàn)動態(tài)表單和自定義驗證時間段重疊

    這篇文章主要介紹了iview實現(xiàn)動態(tài)表單和自定義驗證時間段重疊,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 使用Vue-cli 3.0搭建Vue項目的方法

    使用Vue-cli 3.0搭建Vue項目的方法

    這篇文章主要介紹了使用Vue-cli 3.0搭建Vue項目的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Vue Element使用icon圖標教程詳解(第三方)

    Vue Element使用icon圖標教程詳解(第三方)

    element-ui自帶的圖標庫不夠全,還是需要需要引入第三方icon。下面小編給大家?guī)砹薞ue Element使用icon圖標教程,感興趣的朋友一起看看吧
    2018-02-02
  • Vue數(shù)據(jù)變化監(jiān)聽錯誤的常見原因與解決方案

    Vue數(shù)據(jù)變化監(jiān)聽錯誤的常見原因與解決方案

    在?Vue.js?開發(fā)中,watch?是一個強大的工具,用于監(jiān)聽數(shù)據(jù)的變化并執(zhí)行相應(yīng)的操作,然而,許多開發(fā)者在使用?watch?時會遇到數(shù)據(jù)變化未被正確監(jiān)聽的問題,這可能導(dǎo)致程序邏輯錯誤或視圖更新失敗,本文將探討這些問題的常見原因,并提供相應(yīng)的解決方案,需要的朋友可以參考下
    2025-03-03
  • 詳解vue3.0 diff算法的使用(超詳細)

    詳解vue3.0 diff算法的使用(超詳細)

    這篇文章主要介紹了詳解vue3.0 diff算法的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • elementUI給el-tabs/el-tab-pane添加圖標效果實例

    elementUI給el-tabs/el-tab-pane添加圖標效果實例

    這篇文章主要給大家介紹了關(guān)于elementUI給el-tabs/el-tab-pane添加圖標效果實例的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用elementUI具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-07-07
  • vue解決跨域問題(推薦)

    vue解決跨域問題(推薦)

    這篇文章主要介紹了vue解決跨域問題,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • vue elementui select標簽監(jiān)聽change事件失效問題

    vue elementui select標簽監(jiān)聽change事件失效問題

    這篇文章主要介紹了vue elementui select標簽監(jiān)聽change事件失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04

最新評論

舒城县| 化隆| 秦皇岛市| 眉山市| 镶黄旗| 宁化县| 徐闻县| 甘洛县| 本溪市| 乾安县| 阜康市| 佛教| 运城市| 手机| 九江市| 西乌珠穆沁旗| 皮山县| 盘山县| 保康县| 连州市| 大埔县| 微山县| 尼勒克县| 定安县| 铅山县| 大安市| 金乡县| 苏尼特右旗| 革吉县| 江阴市| 鸡东县| 定南县| 安岳县| 自贡市| 靖州| 西和县| 沙田区| 福泉市| 苏尼特左旗| 长岭县| 商丘市|