国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

利用vue實(shí)現(xiàn)模態(tài)框組件

2019-11-19 18:23:56
字體:
供稿:網(wǎng)友

基本上每個(gè)項(xiàng)目都需要用到模態(tài)框組件,由于在最近的項(xiàng)目中,alert組件和confirm是兩套完全不一樣的設(shè)計(jì),所以我將他們分成了兩個(gè)組件,本文主要討論的是confirm組件的實(shí)現(xiàn)。

組件結(jié)構(gòu)

<template> <div class="modal" v-show="show" transition="fade">  <div class="modal-dialog">   <div class="modal-content">    <!--頭部-->    <div class="modal-header">     <slot name="header">      <p class="title">{{modal.title}}</p>     </slot>     <a v-touch:tap="close(0)" class="close" href="javascript:void(0)"></a>    </div>    <!--內(nèi)容區(qū)域-->    <div class="modal-body">     <slot name="body">      <p class="notice">{{modal.text}}</p>     </slot>    </div>    <!--尾部,操作按鈕-->    <div class="modal-footer">     <slot name="button">      <a v-if="modal.showCancelButton" href="javascript:void(0)" class="button {{modal.cancelButtonClass}}" v-touch:tap="close(1)">{{modal.cancelButtonText}}</a>      <a v-if="modal.showConfirmButton" href="javascript:void(0)" class="button {{modal.confirmButtonClass}}" v-touch:tap="submit">{{modal.confirmButtonText}}</a>     </slot>    </div>   </div>  </div> </div> <div v-show="show" class="modal-backup" transition="fade"></div></template> 

模態(tài)框結(jié)構(gòu)分為三部分,分別為頭部、內(nèi)部區(qū)域和操作區(qū)域,都提供了slot,可以根據(jù)需要定制。

樣式

.modal { position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 1001; -webkit-overflow-scrolling: touch; outline: 0; overflow: scroll; margin: 30/@rate auto;}.modal-dialog { position: absolute; left: 50%; top: 0; transform: translate(-50%,0); width: 690/@rate; padding: 50/@rate 40/@rate; background: #fff;}.modal-backup { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1000; background: rgba(0, 0, 0, 0.5);}

這里只是一些基本樣式,沒什么好說的,這次項(xiàng)目是在移動(dòng)端,用了淘寶的自適應(yīng)布局方案,@rate是切稿時(shí)候的轉(zhuǎn)換率。

接口定義

/** * modal 模態(tài)接口參數(shù) * @param {string} modal.title 模態(tài)框標(biāo)題 * @param {string} modal.text 模態(tài)框內(nèi)容 * @param {boolean} modal.showCancelButton 是否顯示取消按鈕 * @param {string} modal.cancelButtonClass 取消按鈕樣式 * @param {string} modal.cancelButtonText 取消按鈕文字 * @param {string} modal.showConfirmButton 是否顯示確定按鈕 * @param {string} modal.confirmButtonClass 確定按鈕樣式 * @param {string} modal.confirmButtonText 確定按鈕標(biāo)文字 */props: ['modalOptions'],computed: { /**  * 格式化props進(jìn)來的參數(shù),對(duì)參數(shù)賦予默認(rèn)值  */ modal: {  get() {   let modal = this.modalOptions;   modal = {    title: modal.title || '提示',    text: modal.text,    showCancelButton: typeof modal.showCancelButton === 'undefined' ? true : modal.showCancelButton,    cancelButtonClass: modal.cancelButtonClass ? modal.showCancelButton : 'btn-default',    cancelButtonText: modal.cancelButtonText ? modal.cancelButtonText : '取消',    showConfirmButton: typeof modal.showConfirmButton === 'undefined' ? true : modal.cancelButtonClass,    confirmButtonClass: modal.confirmButtonClass ? modal.confirmButtonClass : 'btn-active',    confirmButtonText: modal.confirmButtonText ? modal.confirmButtonText : '確定',   };   return modal;  }, },},

這里定義了接口的參數(shù),可以自定義標(biāo)題、內(nèi)容、是否顯示按鈕和按鈕的樣式,用一個(gè)computed來做參數(shù)默認(rèn)值的控制。

模態(tài)框內(nèi)部方法

data() { return {  show: false, // 是否顯示模態(tài)框  resolve: '',  reject: '',  promise: '', // 保存promise對(duì)象 };},methods: { /**  * 確定,將promise斷定為完成態(tài)  */ submit() {  this.resolve('submit'); }, /**  * 關(guān)閉,將promise斷定為reject狀態(tài)  * @param type {number} 關(guān)閉的方式 0表示關(guān)閉按鈕關(guān)閉,1表示取消按鈕關(guān)閉  */ close(type) {  this.show = false;  this.reject(type); }, /**  * 顯示confirm彈出,并創(chuàng)建promise對(duì)象  * @returns {Promise}  */ confirm() {  this.show = true;  this.promise = new Promise((resolve, reject) => {   this.resolve = resolve;   this.reject = reject;  });  return this.promise; //返回promise對(duì)象,給父級(jí)組件調(diào)用 },},

在模態(tài)框內(nèi)部定義了三個(gè)方法,最核心部分confirm方法,這是一個(gè)定義在模態(tài)框內(nèi)部,但是是給使用模態(tài)框的父級(jí)組件調(diào)用的方法,該方法返回的是一個(gè)promise對(duì)象,并將resolve和reject存放于modal組件的data中,點(diǎn)擊取消按鈕時(shí),斷定為reject狀態(tài),并將模態(tài)框關(guān)閉掉,點(diǎn)確定按鈕時(shí),斷定為resolve狀態(tài),模態(tài)框沒有關(guān)閉,由調(diào)用modal組件的父級(jí)組件的回調(diào)處理完成后手動(dòng)控制關(guān)閉模態(tài)框。

調(diào)用

<!-- template --><confirm v-ref:dialog :modal-options.sync="modal"></confirm><!-- methods -->this.$refs.dialog.confirm().then(() => { // 點(diǎn)擊確定按鈕的回調(diào)處理 callback(); this.$refs.dialog.show = false; }).catch(() => { // 點(diǎn)擊取消按鈕的回調(diào)處理 callback();});

用v-ref創(chuàng)建一個(gè)索引,就很方便拿到模態(tài)框組件內(nèi)部的方法了。這樣一個(gè)模態(tài)框組件就完成了。

其他實(shí)現(xiàn)方法

在模態(tài)框組件中,比較難實(shí)現(xiàn)的應(yīng)該是點(diǎn)擊確定和取消按鈕時(shí),父級(jí)的回調(diào)處理,我在做這個(gè)組件時(shí),也參考了一些其實(shí)實(shí)現(xiàn)方案。

使用事件轉(zhuǎn)發(fā)

這個(gè)方法是我的同事實(shí)現(xiàn)的,用在上一個(gè)項(xiàng)目,采用的是$dispatch和$broadcast來派發(fā)或廣播事件。

首先在根組件接收dispatch過來的transmit事件,再將transmit事件傳遞過來的eventName廣播下去

events: { /**  * 轉(zhuǎn)發(fā)事件  * @param {string} eventName 事件名稱  * @param {object} arg  事件參數(shù)  * @return {null}  */ 'transmit': function (eventName, arg) {  this.$broadcast(eventName, arg); }},

其次是模態(tài)框組件內(nèi)部接收從父級(jí)組件傳遞過來的確定和取消按鈕所觸發(fā)的事件名,點(diǎn)擊取消和確定按鈕的時(shí)候觸發(fā)

// 接收事件,獲得需要取消和確定按鈕的事件名events: { 'tip': function(obj) {  this.events = {   cancel: obj.events.cancel,   confirm: obj.events.confirm  } }}// 取消按鈕cancel:function() { this.$dispatch('transmit',this.events.cancel);}// 確定按鈕submit: function() { this.$dispatch('transmit',this.events.submit);}

在父級(jí)組件中調(diào)用模態(tài)框如下:

this.$dispatch('transmit','tip',{ events: {  confirm: 'confirmEvent' }});this.$once('confirmEvent',function() { callback();}

先是傳遞tip事件,將事件名傳遞給模態(tài)框,再用$once監(jiān)聽確定或取消按鈕所觸發(fā)的事件,事件觸發(fā)后進(jìn)行回調(diào)。

這種方法看起來是不是很暈?所以vue 2.0取消了$dispatch和$broadcast,我們?cè)谧罱捻?xiàng)目中雖然還在用1.0,但是也不再用$dispatch和$broadcast,方便以后的升級(jí)。

使用emit來觸發(fā)

這種方法來自vue-bootstrap-modal,點(diǎn)擊取消和確定按鈕的時(shí)候分別emit一個(gè)事件,直接在組件上監(jiān)聽這個(gè)事件,這種做法的好處是事件比較容易追蹤。

// 確定按鈕ok () { this.$emit('ok'); if (this.closeWhenOK) {  this.show = false; }},// 取消按鈕cancel () { this.$emit('cancel'); this.show = false;},

調(diào)用:

<modal title="Modal Title" :show.sync="show" @ok="ok" @cancel="cancel"> Modal Text</modal>

但是我們?cè)谑褂玫臅r(shí)候經(jīng)常會(huì)遇到這樣的場(chǎng)景,在一個(gè)組件的內(nèi)部,經(jīng)常會(huì)用到多個(gè)對(duì)話框,對(duì)話框可能只是文字有點(diǎn)區(qū)別,回調(diào)不同,這時(shí)就需要在template中為每個(gè)對(duì)話框都寫一次,有點(diǎn)麻煩。

參考資料

vue.js dynamic create nest modal
es6 Promise對(duì)象
vue-bootstrap-modal

本文已被整理到了《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。

關(guān)于vue.js組件的教程,請(qǐng)大家點(diǎn)擊專題vue.js組件學(xué)習(xí)教程進(jìn)行學(xué)習(xí)。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 遵义县| 庄河市| 邳州市| 宣汉县| 泰和县| 舒城县| 正定县| 香河县| 全南县| 乌兰浩特市| 沈阳市| 垦利县| 宝兴县| 宜君县| 通山县| 宜黄县| 宝清县| 梁平县| 根河市| 岳西县| 织金县| 吉木萨尔县| 师宗县| 修水县| 屏东县| 马龙县| 西峡县| 沈丘县| 凉城县| 天等县| 嫩江县| 腾冲县| 皮山县| 聂拉木县| 高唐县| 英超| 武威市| 岐山县| 屯留县| 沽源县| 剑阁县|