日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

modal vue 关闭_Vue弹出框的优雅实践

發(fā)布時間:2023/12/20 vue 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 modal vue 关闭_Vue弹出框的优雅实践 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言

頁面引用彈出框組件是經(jīng)常碰見的需求,如果強(qiáng)行將彈出框組件放入到頁面中,雖然功能上奏效但沒有實現(xiàn)組件與頁面間的解耦,非常不利于后期的維護(hù)和功能的擴(kuò)展.下面舉個例子來說明一下這種做法的弊端.

@click="openModal()">點擊 :is_open="is_open" @close="close()"/> import Modal from "../components/Modal/Modal";//外部引入的彈出框組件export default { components: { Modal, }, data(){ return { is_open:false //控制彈出框關(guān)閉或打開 } }, methods: { openModal() { //顯示彈出框 this.is_open = true; }, close(){ //子組件觸發(fā)的事件,關(guān)閉彈出框 this.is_open = false; } },};

Modal是外部引入的彈出框組件,父組件通過is_open來控制彈出框的隱藏和顯示.仔細(xì)分析上述結(jié)構(gòu)存在的問題如下.

?Modal組件被硬編碼,強(qiáng)行在父組件的components里面注冊并在父組件的模板中渲染.設(shè)想一下,一個彈出框組件就需要在父組件中寫一次,5個彈出框也都要在父組件的模板里寫五個.這樣會讓父組件的頁面結(jié)構(gòu)變的復(fù)雜不利于閱讀,其次彈出框組件應(yīng)該與父組件解耦,它不應(yīng)該寫死在父組件的模板中.?父組件需要單獨設(shè)置一個狀態(tài)is_open來控制彈出框的顯示和隱藏,假如父組件需要引入多個彈出框,那勢必也要定義多個狀態(tài)來對彈出框進(jìn)行控制.

為了實現(xiàn)彈出框和父組件的解耦,最理想的方式是運用函數(shù)式編程的思想,在父組件內(nèi)只需要調(diào)用一個函數(shù)就可以讓彈出框顯示出來,接下來看一下如何實現(xiàn).

彈出框組件的處理

我們接下來實現(xiàn)一個代碼十分簡單但功能強(qiáng)大的工具函數(shù),借助它就可以將彈出框組件封裝起來.如果父組件需要使用哪個彈出框組件直接調(diào)用函數(shù)就能輕松顯示或者隱藏.

實現(xiàn)

import Vue from 'vue';export const createModal = (Component, props) => { const vm = new Vue({ render: (h) => h(Component, { props, }), }).$mount(); document.body.appendChild(vm.$el); const ele = vm.$children[0]; ele.destroy = function() { vm.$el.remove(); ele.$destroy(); vm.$destroy(); }; return ele;};

?Component就是父組件調(diào)用的彈出框組件,在這里作為參數(shù)傳入.props是最終傳遞給彈出框組件內(nèi)部的props?new?一個?Vue實例,render屬性對應(yīng)的函數(shù)里,h的作用是將彈出框組件變成虛擬dom?$mount一定要調(diào)用,它會將虛擬dom轉(zhuǎn)換成真實的dom元素?vm.$el就是對應(yīng)到傳入的彈出框組件Component所渲染的真實dom,將它掛載到body下面,此時頁面就會顯示出彈出框?光顯示出彈出框還不夠,我們還需要給彈出框組件創(chuàng)建一個銷毀方法destroy,其中vm.$children[0]對應(yīng)的就是彈出框組件的vue實例,可以調(diào)用destroy方法銷毀.最后將該實例返回供外部調(diào)用,外部通過該實例就可以調(diào)用彈出框組件內(nèi)部的屬性和方法.

應(yīng)用

作為測試Demo,彈出框組件結(jié)構(gòu)如下,模板內(nèi)容十分簡單.渲染一個頭部標(biāo)題title和內(nèi)容content.定義兩個方法show()和hide()來操作is_open狀態(tài)來控制彈出框的顯示和隱藏.

class="modal" v-if="is_open"> class="content">

class="close" @click="hide()">close

class="title">{{ title }}

{{ content }} export default { props: ["title", "content"], data() { return { is_open: false, }; }, methods: { show() { this.is_open = true; }, hide() { this.is_open = false; }, },};lang="scss" scoped>.modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.6); .content { width: 200px; height: 200px; background-color: #fff; margin: 0px auto; margin-top: 200px; text-align: center; font-size: 14px; color: #333; padding: 5px; .title { margin-bottom: 20px; font-size: 16px; } .close { text-align: right; } }}

頁面組件

class="test-v2"> @click="openModal()">點擊 import Modal from "../../components/Modal/Modal";import { createModal } from "../../util/Modal";export default { methods: { openModal() { this.ele = createModal(Modal, { title: "彈出框", content: "內(nèi)容", }); this.ele.show(); } },};

頁面父組件通過調(diào)用createModal方法能獲取到彈出框組件Modal的實例this.ele.通過this.ele就可以拿到彈出框組件內(nèi)部的所有屬性和方法,包括顯示show()和隱藏hide().

?經(jīng)過上方一改造,實現(xiàn)了彈出框組件和父組件之間的解耦.彈出框組件不需要在父組件中注冊和模板內(nèi)渲染.?如果父組件需要傳遞數(shù)據(jù)給彈出框組件,可以借助createModal第二個參數(shù)對象,它最終會以props的形式注入到彈出框組件的內(nèi)部.?show()和hide()方法都是彈出框內(nèi)部定義的,父組件可以直接調(diào)用控制其顯示隱藏.另外頁面銷毀時要調(diào)用一次this.ele.destroy(),防止內(nèi)存泄漏.

頁面效果

在這里插入圖片描述

從最終的dom結(jié)構(gòu)圖可以清晰的看到彈出框掛載在body的下面,而非頁面組件內(nèi)部.這樣在對彈出框定義一些與css定位相關(guān)的樣式時就輕松方便的多,不會受到頁面組件的影響和干擾.

延伸

通過上面對彈出框的講解我們還可以在此基礎(chǔ)做很多其他的事情,比如對消息提示框的處理.

消息提示框也屬于彈出框.最好的實踐方式是,只需要寫一行代碼?Alert("Hello world"),頁面上就會立馬彈出消息提示?Hello world.效果如下.

在這里插入圖片描述

實現(xiàn)

父頁面結(jié)構(gòu)如下,調(diào)用Alert()函數(shù),頁面就會顯示提示框.

class="test-v2"> @click="alert()">Alert import { Alert } from "../../util/Modal";export default { methods: { alert() { Alert("Hello world"); }, },};

Alert函數(shù)實現(xiàn)如下.

const alert_array = []; //用來存儲彈出框的實例export const Alert = (msg, duration = 3000) => { let top = 100; //默認(rèn)距離頂部100px if (alert_array.length > 0) { const index = alert_array.length; top = top + index * 50; } const ele = createModal(AlertComponent, { title: msg, top, }); alert_array.push(ele); const timer = setTimeout(() => { clearTimeout(timer); const index = alert_array.indexOf(ele); index !== -1 && alert_array.splice(index, 1); ele.destroy(); }, duration);};

?AlertComponent是自定義的消失提示框組件(需要引入),調(diào)用createModal()獲取每個提示框的實例存儲在數(shù)組alert_array中.?點擊一次按鈕出現(xiàn)一個消息提示框,點擊第二次按鈕時,第二個提示框應(yīng)該出現(xiàn)在第一個框的下面,因此需要根據(jù)數(shù)組alert_array動態(tài)計算絕對定位的top值,在創(chuàng)建彈出框?qū)嵗龝r作為參數(shù)傳進(jìn)去.?定時器控制默認(rèn)3秒后移除彈出框.

AlertComponent消息提示框組件內(nèi)容如下.初始給top_value賦值this.top - 30,后來在mounted中再將this.top賦值一次,就是為了實現(xiàn)提示框出現(xiàn)時從上往下滑動的動畫效果.

class="alert-component" :style="{ top: `${top_value}px`, opacity: opacity }" > {{ title }} export default { props: ["title", "top"], data() { return { top_value: this.top - 30, opacity: 0, }; }, mounted() { const timer = setTimeout(() => { clearTimeout(timer); this.top_value = this.top; this.opacity = 1; }); },};.alert-component { height: 20px; border-radius: 4px; position: absolute; min-width: 300px; left: 50%; transform: translateX(-50%); background-color: #f0f9eb; color: #67c23a; align-items: center; padding: 10px 16px; transition: all 0.25s linear; opacity: 0;}

結(jié)尾

借助createModal工具函數(shù),不僅可以做消息提示框,另外包括消息確認(rèn)框,動態(tài)的表單模態(tài)框都可以實現(xiàn)進(jìn)一步的封裝簡化處理.當(dāng)彈出框與頁面實現(xiàn)解耦后,整體的代碼邏輯會變得更加清晰,對后期維護(hù)和擴(kuò)展都有巨大的好處.

總結(jié)

以上是生活随笔為你收集整理的modal vue 关闭_Vue弹出框的优雅实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。