VUE2實(shí)現(xiàn)事件驅(qū)動彈窗示例
前幾天想了解vue如何寫彈窗組件
有以下兩種可取的寫法:
1.狀態(tài)管理 如果彈窗組件放在根組件,使用vuex來管理組件的show和hide。放在組件內(nèi),通過增加v-show或v-if來控制,可結(jié)合slot,定義不同需求的彈窗
2.事件管理 注冊一個(gè)全局事件來打開彈窗,傳入需展示的文字和相關(guān)的邏輯控制,可結(jié)合promise,實(shí)現(xiàn)異步
覺得對用像confirme和propmt這類彈窗,還是事件驅(qū)動的好。最好就是能使用promise回調(diào)。
于是手癢就寫了一個(gè)。下面是代碼。
propmt.js
import Vue from 'vue' import promptComponent from './prompt.vue' // 引入彈窗的vue文件 const promptConstructor = Vue.extend(promptComponent); // 注冊組件 let instance = new promptConstructor().$mount(''); // 獲得組件的實(shí)例 document.body.appendChild(instance.$el); // 將組件的element插入到body中 const Alert = (text,okText)=>{ if(instance.show === true) { //防止多次觸發(fā) return; } // 為彈窗數(shù)據(jù)賦值 instance.show = true; instance.isAlert = true; instance.okText = okText||'確定'; instance.message = text; //返回一個(gè)promise對象,并為按鈕添加事件監(jiān)聽 return new Promise(function(resolve,reject) { instance.$refs.okBtn.addEventListener('click',function() { instance.show = false; resolve(true); }) }) }; const Confirm = (text,okText,cancelText)=>{ if(instance.show === true) { return; } instance.show = true; instance.okText = okText||'確定'; instance.cancelText = cancelText||'取消'; instance.message = text; return new Promise(function(resolve,reject) { instance.$refs.cancelBtn.addEventListener('click',function() { instance.show = false; resolve(false); }); instance.$refs.okBtn.addEventListener('click',function() { instance.show = false; resolve(true); }) }) }; const Prompt = (text,okText,inputType, defaultValue)=>{ if(instance.show === true) { return; } instance.show = true; instance.isPrompt = true; instance.okText = okText||'確定'; instance.message = text; instance.inputType = inputType || 'text'; instance.inputValue = defaultValue || ''; return new Promise(function(resolve,reject) { instance.$refs.okBtn.addEventListener('click',function() { instance.show = false; resolve(instance.inputValue); }) }) }; export {Alert,Confirm,Prompt}
prompt.vue
<style lang="less" scoped> .confirm-enter-active { transition: all .2s; } .confirm-leave-active { transition: opacity .2s; } .confirm-leave-to { opacity: 0; } .confirm-enter { opacity: 0; } .confirm { position: relative; font-family: PingFangSC-Regular; font-size: 17px; -webkit-user-select: none; user-select: none; // 遮罩層樣式 .masker { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, .4); -webkit-transition: opacity .1s linear; transition: opacity .1s linear; z-index: 100; } // 入庫數(shù)據(jù)錯誤樣式 .box { position: absolute; top: 50%; left: 50%; width: 72%; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); text-align: center; border-radius: 12px; background-color: #fff; .message { height: 97px; line-height: 24px; font-family: PingFangSC-Regular; font-size: 17px; vertical-align: middle; color: #999; letter-spacing: -0.41px; p { margin: 20px auto 0 auto; vertical-align: middle; } &::after { content: ''; height: 100%; } } .prompt { margin: 20px 0; width: 100%; p { margin: 5px auto; font-size: 17px; line-height: 24px; } input { margin: 5px auto; border: 1px solid #333; border-radius: 6px; width: 100px; height: 30px; font-size: 14px; line-height: 20px; text-align: center; } } .button-group { a { width: calc(50% - 0.5px); text-align: center; font-size: 17px; line-height: 43px; color: blue; } .max-width { width: 100% !important;; } } } } </style> <template> <transition name="confirm"> <div class="confirm" v-show="show"> <div class="masker" @touchmove.prevent> <div class="box"> <div class="message" v-if="!isPrompt"> <p>{{message}}</p> </div> <div class="prompt" v-if="isPrompt"> <p>{{message}}</p> <input type="text" v-model="inputValue" v-if="inputType === 'text'" ref="inputEl"> <input type="tel" v-model.number="inputValue" @keydown="enterCheck" v-if="inputType === 'tel'" ref="inputEl"> </div> <div class="button-group clearfix bd-top"> <a class="bd-right fl" ref="cancelBtn" v-show="!isAlert && !isPrompt">{{cancelText}}</a> <a class="fr" ref="okBtn" :class="{'max-width': isAlert || isPrompt}">{{okText}}</a> </div> </div> </div> </div> </transition> </template> <script type="text/ecmascript-6"> import {mapState} from 'vuex' export default{ data() { return { show: false, message: '請輸入提示語', okText: '確定', cancelText: '取消', isAlert: false, isPrompt: false, inputValue: '', inputType: '' } }, methods: { // 金額輸入框校驗(yàn) enterCheck(event) { // 只允許輸入數(shù)字,刪除鍵,11位數(shù)字 if (event.keyCode === 46 || event.keyCode === 8) { return; } if (event.keyCode < 47 || event.keyCode > 58 || event.keyCode === 190) { event.returnValue = false; } }, }, watch: { show(){ if (this.show) { this.$nextTick(() => { console.log(this.$refs.inputEl); console.log(this.inputType); this.$refs.inputEl.focus(); }); } } } } </script>
main.js
import {Alert,Prompt,Confirm} from '../lib/components/prompt/prompt.js' Vue.prototype.Alert = function(text,okText) { return Alert(text,okText) }; Vue.prototype.Confirm = function(text,okText,cancelText) { return Confirm(text,okText,cancelText) }; Vue.prototype.Prompt = function(text,okText,inputType, defaultValue) { return Prompt(text,okText,inputType, defaultValue) }; component.vue: inputName() { this.Prompt('請輸入名稱','確認(rèn)','text').then(res =>{ // do something use res }); },
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
在vue項(xiàng)目中,將juery設(shè)置為全局變量的方法
今天小編就為大家分享一篇在vue項(xiàng)目中,將juery設(shè)置為全局變量的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09vuex state及mapState的基礎(chǔ)用法詳解
這篇文章主要介紹了vuex state及mapState的基礎(chǔ)用法詳解,本文通過實(shí)例代碼相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-04-04defineProperty和Proxy基礎(chǔ)功能及性能對比
這篇文章主要為大家介紹了defineProperty和Proxy基礎(chǔ)功能及性能對比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08基于elementUI使用v-model實(shí)現(xiàn)經(jīng)緯度輸入的vue組件
這篇文章主要介紹了基于elementUI使用v-model實(shí)現(xiàn)經(jīng)緯度輸入的vue組件,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05Vue后臺中優(yōu)雅書寫狀態(tài)標(biāo)簽的方法實(shí)例
在Vue中,我們可以非常便捷地通過標(biāo)簽實(shí)現(xiàn)狀態(tài)的保存,這篇文章主要給大家介紹了關(guān)于Vue后臺中如何優(yōu)雅的書寫狀態(tài)標(biāo)簽的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08vue watch內(nèi)部調(diào)用methods方法報(bào)錯的解決方案
這篇文章主要介紹了vue watch內(nèi)部調(diào)用methods方法報(bào)錯的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04