最近在寫項目的時候需要“在vue中動態(tài)生成一個彈出層”耸弄,查找資料的時候偶然發(fā)現(xiàn)了一個關(guān)于Promise的用法郊闯,如下:
showPopupFrame(){
this.showPopupFrameBtnDisable = true
this.$loginFrame().then(res=>{
// resolve時執(zhí)行
console.log(res)
}).catch(err=>{
// reject時執(zhí)行
console.log(err)
}).finally(()=>{
// 無論結(jié)果如何都執(zhí)行
this.showPopupFrameBtnDisable = false
})
}
生成組件以后肌幽,調(diào)用組件的地方可以監(jiān)聽組件動向舌涨,并根據(jù)此做出不同的操作糯耍,非常適用于各種需要交互的彈窗
一、 Promise
??Promise是在es6(ECMAScript 6.0
)中的新特性囊嘉,它是異步編程的一種解決方案谍肤。基本使用方法如下:
// 定義一個Promise對象
const wait = ms => {
return new Promise((resolve,reject)=>{
if(ms>10000){
// 如果ms大于10000則提交錯誤哗伯,執(zhí)行catch
reject(ms+'毫秒太多了荒揣!')
}else{
// 否則執(zhí)行then
setTimeout(()=>{resolve(ms+'毫秒過去了...')},ms)
}
})
}
// 執(zhí)行catch
wait(15000).then((res)=>{
console.log('then')
console.log(res)
}).catch((err)=>{
console.log('catch')
console.log(err)
})
// 執(zhí)行then
wait(2000).then((res)=>{
console.log('then')
console.log(res)
}).catch((err)=>{
console.log('catch')
console.log(err)
})
二、Vue動態(tài)加載組件
??先定義好template.vue前端文件焊刹,然后在一個js文件中封裝一些方法將它實例化為Vue.Component系任,就可以進(jìn)行動態(tài)加載了。
三虐块、demo
點擊按鈕俩滥,出現(xiàn)彈出層,同時將按鈕禁用
demo-彈出框示意
輸入數(shù)據(jù)贺奠,點擊提交霜旧,觸發(fā)提交事件,同時調(diào)用組件的方法也接收到了數(shù)據(jù)
demo-提交示意
點擊取消
demo-取消示意
四儡率、簡要實現(xiàn)
組件代碼
// component/dialog/login.vue
<template>
<div class="login-frame">
<div class="login-form">
<label>
賬號:<input v-model="account" type="text" placeholder="用戶名">
</label><br/>
<label>
密碼:<input v-model="pwd" type="password">
</label><br/>
<button @click="cancel">取消</button>
<button @click="submit">提交</button>
</div>
</div>
</template>
<script>
export default {
name: "login.vue",
data(){
return {
account:'',
pwd:''
}
},
methods:{
cancel(){
console.log('點擊了取消')
//取消登錄 執(zhí)行fail
this.$emit('fail')
this.destroy()
},
submit(){
console.log('點擊了登錄')
//提交登錄 執(zhí)行success
this.$emit('success',{
account:this.account,
password:this.pwd
})
this.destroy()
},
show(){
document.body.append(this.$el)
},
destroy(){
// 從頁面移除
if (document.body.contains(this.$el)){
document.body.removeChild(this.$el)
}
}
}
}
</script>
<style scoped>
.login-frame{
position: fixed;
top: 180px;
width: 100%;
margin: 0;
padding: 0;
}
.login-form{
width: 200px;
margin: 0 auto;
border: 1px solid red;
background: #eee;
}
</style>
組件封裝代碼
// component/dialog/loginFrame.js
import vue from 'vue'
import loginComponent from './login'
// 生成構(gòu)造方法
const loginConstructor = vue.extend(loginComponent)
let loginDom = null
const login = () => {
if (loginDom!==null){
loginDom.destroy()
loginDom = null
}
// 創(chuàng)建
loginDom = new loginConstructor({
el:document.createElement('div')
})
// 附加到頁面
loginDom.show()
return new Promise((resolve,reject) => {
// 若login.vue執(zhí)行success
loginDom.$on('success',(form)=>{
resolve(form)
})
// 若login.vue執(zhí)行fail
loginDom.$on('fail',()=>{
reject('用戶取消登錄')
})
})
}
export default login
在main.js中定義
import loginFrame from "@/components/dialog/loginFrame"
Vue.prototype.$loginFrame = loginFrame
如有錯誤挂据,歡迎指出,謝謝