關於el-dialog,我更推薦的用法

来源:http://www.cnblogs.com/default/archive/2017/10/07/7634443.html
-Advertisement-
Play Games

最近的項目里用上了vue和element-ui。vue這種輕量級漸進式框架的舒適自不必說,但一直困擾著我的,是如何方便又優雅的彈出模態dialog... 對於我這種在jquery出現之前就用document.getElementById敲代碼的老頑固來說,我始終不能完全接受把dialog在編碼期就寫 ...


最近的項目里用上了vue和element-ui。vue這種輕量級漸進式框架的舒適自不必說,但一直困擾著我的,是如何方便又優雅的彈出模態dialog...

對於我這種在jquery出現之前就用document.getElementById敲代碼的老頑固來說,我始終不能完全接受把dialog在編碼期就寫入模板的方式,下麵是尤大在知乎某個相關問題的回答節選(全文請看https://www.zhihu.com/question/35820643):

為什麼一定要非同步插入?
其實以前也有一些用戶跟我糾結過這個問題,他們覺得一定要在需要的時候創建這個組件才是符合他們思維的做法。在我看來,這是沒有理解『狀態驅動的界面』的一種表現。
傳統的命令式 (Imperative) 的思維寫出來的代碼:

$('.open-modal').on('click', function () {
  var modal = new Modal()
  modal.$appendTo('body')
  modal.open()
})

// 在 modal 內部還要處理關閉、銷毀自身的邏輯

狀態驅動的思維寫出來的代碼:

this.showModal = true

// 關掉
this.showModal = false

不可否認,尤大所說的狀態驅動確實是vue的精髓,但是在實際應用中,dialog往往需要直接在body下才能避免這樣那樣的問題,就比如本文要說的element-ui的el-dialog問題:如果你在一個el-dialog里,嵌套了另外一個el-dialog,那麼彈窗的遮罩層會相互影響,導致用戶無法使用(新發佈的element-ui 2.0已經解決了嵌套彈窗的問題,文檔在這裡http://element.eleme.io/#/zh-CN/component/dialog)。

這就要求我們把系統中所有可能出現的dialog,都預先放在vue的根組件中,但顯然這是不合理的,根組件無法預知業務模塊中將會出現的dialog。dialog應該和alert、messagebox、toast一樣,提供方法級別的調用,但不知為何element-ui為後者們提供了全局方法,但對dialog卻沒有。

本文的目的,就是為了分享一個為dialog提供全局方法的做法。這是我在csdn上看到的一篇文章,確實解決了我的問題,原文在這裡:http://blog.csdn.net/zmy_coder/article/details/78042485

原理就是在方法被調用時,在body里create一個div,並且創建一個Vue實例,指定el屬性為這個div。

 

//dialog.js
function makeDialog(option) {
    var dom = document.createElement('div');
    document.getElementsByTagName('body')[0].appendChild(dom);
    let tpl = '\
        <el-dialog \
            :close-on-click-modal="false" \
            :custom-class="customClass" \
            :title="title" \
            :visible.sync="show" \
            :size="size" \
            :before-close="handleClose" \
            @close="close">\
                <dialogContent  @close="closeDialog" @confirm="confirmDialog" v-model="dialogData"></dialogContent>\
        </el-dialog>';
    var vue = new Vue({
        el: dom,
        data: function () {
            return {
                title: option.title,
                size: option.size || 'small',
                show: true,
                dialogData: option.data,
            };
        },
        template: tpl,
        computed: {
            customClass(){
                return `el-dialog--width-${option.size || 'auto'}`;
            }
        },
        methods: {
            handleClose(done){
                if (option.beforeClose) {
                    option.beforeClose(done);
                } else {
                    done();
                }
            },
            close() {
                if (option.close) {
                    option.close();
                }
            },

            closeDialog(){
                this.show = false
            },
            confirmDialog(result){
                this.show = false
                option.confirm && option.confirm(result)
            }
        },
        components: {
            dialogContent: option.component,
        },
    });
    return vue;
}

export default {
    open(options){
        return makeDialog(options)
    }
}

在創建的這個Vue實例里,用到了el-dialog組件,並且具體的內容由外部調用者以component的形式傳入,如果該component需要初始數據,需要為該component定義一個value屬性,並且在調用open方法時,用options.data傳入,並且可以設置在對話框beforeClose、close、confirm時的回調

用法示例:

對話框內容:

<!--SimpleDialogTest.vue-->
<template>
    <div class="tutorial">
        請輸入您的姓名 <input class="form-control" v-model="name">

        <button type="button" class="btn btn-primary" @click="submit">確定</button>
        <button type="button" class="btn btn-default" @click="cancel">取消</button>
    </div>
</template>
<style lang="scss" rel="stylesheet/scss" scoped>

</style>
<script type="text/ecmascript-6">
    import dialog from '../../assets/js/dialog'
    export default{
        props: {
            value: Object,
        },
        data(){
            return {
                name : this.value.name
            }
        },

        methods: {
            submit(){
                console.log('your name is ' + this.name)
                //do something if you like
                //...

                //關閉對話框
                this.$emit('close');

                //關閉對話框, 並回調調用者的option.confirm方法
//                this.$emit('confirm', {
//                        ...
//                });
            },
            cancel(){
                this.$emit('close')
            }
        },

    }
</script>

 

 

調用方:

<!---調用方-->
<template>
    <button @click="openDialog">彈出對話框</button>
</template>
<script type="text/ecmascript-6">
    import dialog from '../assets/js/dialog'
    import SimpleDialogTest from 'SimpleDialogTest.vue'
    export default{
        data(){
            return{
            }
        },
        methods:{
            openDialog(){
                dialog.open({
                    title: '標題標題',
                    size:'small', //可選項tiny/small/large/full, 對應el-dialog的size屬性
                    component: SimpleDialogTest,
                    data: {
                        name: 'your name',
                    },
//                    beforeClose: (done) => {
//                        //點右上角關閉按鈕後觸發
//                        console.log('dialog is closing');
//                        done()
//                    },
                    close: () => {
                        //關閉後觸發
                        console.log('dialog is closed')
                    },
                    confirm: (result) => {
                        //顯式$emit('confirm')時觸發
                        console.log('dialog is confirmed, and dialog result is ', result)
                    }
                })
            }
        }
    }
</script>

 

 

 關於option的size

 el-dialog中size的四個選項tiny/small/large/full在實際應用中是不夠的,有時候我們希望能為dialog能自適應內容組件的寬度,也就是說由內容組件來決定寬度,應該怎麼做呢?

首先定義一個全局的css:

.el-dialog.el-dialog--width-auto{
  width:auto !important;
}

 

然後在調用dialog.open()的時候,不要指定size屬性就行了。

 


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

-Advertisement-
Play Games
更多相關文章
  • 過濾器 字面義上理解的過濾器類似下圖,從一堆物品中篩選出符合條件的留下,不符合的丟棄。 GOF 職責鏈 GOF中有一種設計模式叫職責鏈,或者叫責任鏈,常規的UML圖如下: 正統的職責鏈是將一個請求發給第一個接收者,接收者判斷是否屬於自己能處理的,如果能處理則執行操作並中止請求下發,流程到此為止。如果 ...
  • 設計模式的最終目的是解決軟體的高可維護性和高復用性問題以及應對大數據、高併發、高智能的挑戰。 設計模式遵循的原則: 1 開閉原則。對開展開放,對修改關閉。不修改原代碼的前提下實施功能擴展。 2 里氏代換。子類可以代替基類出現在任何地方。 3 依賴倒轉。依賴於抽象,不要依賴於實現。代碼往上走,數據往下 ...
  • (2.2)第二種擴展方式,隱示擴展,通過__proto__屬性。 2,簡單方式實現繼承 使用圖梳理一下原理: 索引的變化: (1) ...
  • 編寫高效率的js,第一步就是將自己的代碼風格規範起來,畢竟寫一堆爛代碼,是一件讓自己很難容忍的事情。我就是這樣,業精於勤荒於嬉,行成於思毀於隨,對代碼編寫提出高標準,對團隊,對個人都是一件應該努力的方向。 進入正題,2017年10月起,我會每周優先更新兩個重要部分,以下藍色字體代表已更新的內容,黑色 ...
  • 前 言 MUI是一款最接近原生APP體驗的高性能前端框架,它的比較重要的功能是:下拉刷新、側滑導航、滑動觸發操作菜單和頂部(底部)選項卡等 最近用MUI做手機app應用的時候,遇到的小bug。順便研究了一下這個tab-top-webview-main,這裡給大家分享一下。 1主頁代碼 2子頁代碼 3 ...
  • jquery ajax調用webservice(C#)要註意的幾個事項: 1、web.config里需要配置2個地方 <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" validate="false ...
  • 原文鏈接:http://www.zhangxinxu.com/wordpress/?p=466 以上代碼在IE10中測試與張老師文章中的效果有些出入,希望在以後的工作學習中引起註意,並且進行深度研究哈哈~ ...
  • 前端開發工具 1.1、 WebStorm介紹和下載 l 介紹 WebStorm是JetBrains 推出的一款強大的HTML5編輯工具,擁有豐富的代碼快速編輯,可以智能的補全代碼、代碼格式化、html提示以及代碼檢查和快速修複等,支持不同瀏覽器的提示,同時也是一款JavaScript 開發工具,擁有 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...