modal vue 關閉_Vue彈出框的優雅實踐

引言

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

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

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

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

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

彈出框組件的處理

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

實現

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

應用

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

  
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: "內容", }); this.ele.show(); } },};

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

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

頁面效果

73a3cbfaf6bc66f623ebc59e6156b104.png
在這里插入圖片描述

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

延伸

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

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

d957223d1348c4de5de29fa86f110cbe.gif
在這里插入圖片描述

實現

父頁面結構如下,調用Alert()函數,頁面就會顯示提示框.

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

Alert函數實現如下.

const alert_array = []; //用來存儲彈出框的實例export const Alert = (msg, duration = 3000) => {  let top = 100; //默認距離頂部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是自定義的消失提示框組件(需要引入),調用createModal()獲取每個提示框的實例存儲在數組alert_array中.?點擊一次按鈕出現一個消息提示框,點擊第二次按鈕時,第二個提示框應該出現在第一個框的下面,因此需要根據數組alert_array動態計算絕對定位的top值,在創建彈出框實例時作為參數傳進去.?定時器控制默認3秒后移除彈出框.

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

  
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;}

結尾

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453855.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453855.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453855.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python 第三方模塊之 lxml - 解析 HTML 和 XML 文件

lxml是python的一個解析庫,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 XPath,全稱XML Path Language,即XML路徑語言,它是一門在XML文檔中查找信息的語言,它最初是用來搜尋XML文…

(轉)Linux下PS1、PS2、PS3、PS4使用詳解

Linux下PS1、PS2、PS3、PS4使用詳解 原文:http://www.linuxidc.com/Linux/2016-10/136597.htm 1、PS1——默認提示符 如下所示,可以通過修改Linux下的默認提示符,使其更加實用。在下面的例子中,默認的PS1的值是“\s-\v\$”,顯示出…

開放平臺大抉擇

開放平臺大抉擇之新浪SAE:為個人應用開發帶來福音 導讀:繼上期淘寶網副總裁王文彬從平臺功能特色、運營狀況等多方面分享了淘寶開放平臺的歷程和挑戰之后。國內另一家云平臺服務方的典型代表——Sina App Engine(簡稱SAE),作為新浪研發中心于…

ip68級防水可以泡多久_iPhone8防水級別升級至IP68:能在1.5米深水中堅持30分鐘

1月15日,業界最新的泄密消息顯示,蘋果擬在今年推出的“iPhone 8”智能手機會是一款革命性的手機,功能和配置就不多說了。蘋果還將解決iPhone 7的一個重要缺陷,就是大大增強iPhone 8的防水性能,防水級別達IP68。《韓國先…

HTTP POST 發送數據的參數 application/x-www-form-urlencoded、multipart/form-data、text/plain

HTTP 簡介 HTTP/1.1 協議規定的 HTTP 請求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 這幾種。 其中 POST 一般用來向服務端提交數據,本文主要討論 POST 提交數據的幾種方式。 我們知道,HTTP 協議是以 ASCII 碼傳輸,建…

vue 二進制文件的下載(解決亂碼和解壓報錯)

問題描述:項目中使用的是vue框架進行開發,因為文件下載存在權限問題,所以并不能通過 a 鏈接的 href 屬性直接賦值 URL進行下載, (如果你的文件沒有下載權限,可以直接通過href屬性賦值URL的方法進行文件下載…

Python 第三方模塊之 psutil - 獲取系統運行的進程和系統利用率信息

一、psutil模塊: 官方網址:http://pythonhosted.org/psutil/ 1.psutil是一個跨平臺庫(http://pythonhosted.org/psutil/)能夠輕松實現獲取系統運行的進程和系統利用率(包括CPU、內存、磁盤、網絡等)信息。它主要用來做系統監控,…

石頭機器人紅燈快閃_機器人集體“快閃”活動爆紅網絡 “我是AI”與您相約智能新時代...

原標題:機器人集體“快閃”活動爆紅網絡 “我是AI”與您相約智能新時代3月10日下午,天津科學技術館內,悠揚美妙的歌聲《我和我的祖國》突然響起,隨后50個身形矯健的阿爾法機器人伴隨著歌聲翩翩起舞,動作整齊、科技感十…

淺談云計算與數據中心計算

文/林仕鼎 云計算概念發端于Google和Amazon等超大規模的互聯網公司,隨著這些公司業務的成功,作為其支撐技術的云計算也得到了業界的高度認可和廣泛傳播。時至今日,云計算已被普遍認為是IT產業發展的新階段,從而被賦予了很多產業和…

無線網絡實體圖生成工具airgraph-ng

無線網絡實體圖生成工具airgraph-ngairgraph-ng是aircrack-ng套件提供的一個圖表生成工具。該工具可以根據airodump工具生成的CSV文件繪制PNG格式的圖。繪制的圖有兩種類型,分別為AP-客戶端關聯圖和通用探測圖。通過AP-客戶端關聯圖,可以更為直觀的了解無…

高等代數期末考試題庫及答案_數學類高等代數期末考試試題A卷(含答案)

數學類高等代數期末考試試題A卷(含答案)課程編號MTH17063 北京理工大學2010-2011學年第一學期2009級數學類高等代數期末考試試題A卷班級 學號 姓名 成績 一、(25分)設表示域上的所有階矩陣構成的上的線性空間。取定,對于任意的,定義。(1)證明為上的一個線…

cocos2d-lua3.7組件篇(三)-http通信demo

客戶端使用lua、服務端使用QT做為服務器。 步驟: 客戶端 -----------Post 用戶名和密碼 服務端接受Post請求,讀取數據,返回response一、客戶端代碼 loadingImg require"app.scenes.LoadingLayer"local LoginScene class(&qu…

數據挖掘:如何尋找相關項

導讀:隨著大數據時代浪潮的到來數據科學家這一新興職業也越來越受到人們的關注。本文作者Alexandru Nedelcu就將數學挖掘算法與大數據有機的結合起來,并無縫的應用在面臨大數據浪潮的網站之中。 數據科學家需要具備專業領域知識并研究相應的算法以分析對…

Python 第三方模塊之 selenium - 模擬操作 Chrome 瀏覽器

1、安裝selenium 1.1、Python 安裝 selenium 模塊 pip install selenium1.2、下載驅動 選擇和自己chrom版本相對應的驅動到本地,下載地址 http://npm.taobao.org/mirrors/chromedriver/2、Python 操作 from selenium import webdriver import time import json…

jupyter notebook代碼導出_Jupyter Notebook導出包含中文的pdf_親測有效

Jupyter Notebook是很好的數據科學創作環境,是非常方便的Python代碼編輯器。jupyter提供導出的格式有.py、.html、.md、.pdf等。目前用其導出包含中文的pdf會遇到很多坑,網上也有一些解決方案,大致分為兩種方式,一是安裝 pandoc并…

前端之使用 POST 提交數據并跳轉

GET 方式 window.location.href是我們常用來在js中實現頁面跳轉的方法,這是使用get方式發送請求,示例如下 window.location.href url;優點是簡單易用,缺點是如果有參數的話,參數會暴露在url地址中,這降低了系統的安…

cef js返回c++的代碼_CEF3開發者系列之外篇——IE中JS與C++交互

使用IE內核開發客戶端產品,系統和前端頁面之間的交互,通常給開發和維護帶來很大的便利性。但操作系統和前端之間的交互卻是比較復雜的。具體來說就是腳本語言和編譯語言的交互。在IE內核中html和css雖然不兼容,但是IE編程接口是完全一樣的,這得益于微軟的…

多線程編程指南 part 2

多線程編程指南Sun Microsystems, Inc.4150 Network CircleSanta Clara, CA95054U.S.A.文件號碼819–7051–102006 年10 月版權所有2005 Sun Microsystems, Inc. 4150 Network Circle, Santa Clara, CA95054 U.S.A. 保留所有權利。本文檔及其相關產品的使用、復制、分發和反編譯…

00030_ArrayList集合

1、數組可以保存多個元素,但在某些情況下無法確定到底要保存多少個元素,此時數組將不再適用,因為數組的長度不可變 2、JDK中提供了一系列特殊的類,這些類可以存儲任意類型的元素,并且長度可變,統稱為集合 3…

1.3tf的varible\labelencoder

1.tf的varible變量 import tensorflow as tf #定義變量--這里是計數的變量 statetf.Variable(0,namecounter) print (state.name) #輸出變量值 onetf.constant(1) #常量new_valuetf.add(state,one) updatetf.assign(state,new_value)#初始化所有變量 inittf.initialize_all_var…