vue框架本身好像沒有彈出框,而vuetify有彈出框v-dialog,沒有確認框confirm,雖然確認框自己就是彈出框,可是彈出框的功能有個特色,就是肯定作一件事情,而取消了就是作另外一件事情,相似一個Promise要作的事情。javascript
今天主要就是要自定義一個確認框,咱們利用組件的思惟,先定義組件結構,而後定義組件如何配合文檔document工做,最後聲明和調用。按照這個思路,咱們分以下幾步:html
一、定義組件結構體src/components/Confirm.vuevue
<template> <div class="dialogwrapper" v-if="show"> <div class="overlay"></div> <v-card class="dialog"> <v-card-title>提示</v-card-title> <v-card-text> 您肯定這麼作嗎? </v-card-text> <v-card-actions> <v-btn @click="ok">肯定</v-btn> <v-btn @click="cancel">取消</v-btn> </v-card-actions> </v-card> </div> </template> <script> export default { data() { return { promiseStatus: null, show: false } }, methods: { confirm() { let _this = this; this.show = true; return new Promise(function (resolve,reject){ _this.promiseStatus = {resolve,reject}; }); }, ok(){ this.show = false; this.promiseStatus && this.promiseStatus.resolve(); }, cancel(){ this.show = false; this.promiseStatus && this.promiseStatus.reject(); } } } </script> <style> .dialogwrapper{ align-items: center; display: flex; height: 100%; justify-content: center; left: 0px; pointer-events: none; position: fixed; top: 0px; width: 100%; z-index: 6; transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1) 0s, z-index 1ms ease 0s; outline: none; } .dialog{ overflow-y: auto; pointer-events: auto; width: 100%; z-index: inherit; box-shadow: rgba(0, 0, 0, 0.2) 0px 11px 15px -7px, rgba(0, 0, 0, 0.14) 0px 24px 38px 3px, rgba(0, 0, 0, 0.12) 0px 9px 46px 8px; border-radius: 4px; margin: 24px; transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) 0s; max-width:290px; } .overlay{ align-items: center; border-radius: inherit; display: flex; justify-content: center; position: fixed; top: 0; left: 0; right: 0; bottom: 0; pointer-events: auto; background:#000; opacity:0.46; } </style>
二、定義插件src/plugins/confirm.jsjava
import Vue from 'vue' import Confirm from '@/components/Confirm.vue' const VueComponent = Vue.extend(Confirm) const vm = new VueComponent().$mount() let init = false; let defaultOptions = { } const confirm = function(options){ Object.assign(vm,defaultOptions,options,{ type:"confirm" }) if(!init){ document.body.appendChild(vm.$el) init = true; } return vm.confirm(); }; export default confirm;
三、全局聲明組件src/main.jspromise
import Vue from 'vue' import App from './App' import router from './router' import vuetify from '@/plugins/vuetify' import confirm from '@/plugins/confirm' Vue.config.productionTip = false Vue.prototype.$confirm = confirm /* eslint-disable no-new */ new Vue({ el: '#app', router, vuetify, components: { App }, template: '<App/>' })
四、調用src/components/TestPage.vueapp
<template> <v-card> <v-btn @click="confirm">open</v-btn> </v-card> </template> <script> export default { methods: { confirm(){ this.$confirm({ }).then(()=>{ console.log("ok"); }).catch(()=>{ console.log("cancel"); }) } } } </script>
五、效果圖:框架
以上是一個簡單的示例,咱們在須要使用的地方直接經過this.$confirm().then().catch()就能夠把邏輯所有設置好,能夠看出this.$confirm是一個Promise,而這個Promise是經過定義組件結構的時候confirm方法返回的。以下所示:flex
confirm() { let _this = this; this.show = true; return new Promise(function (resolve,reject){ _this.promiseStatus = {resolve,reject}; }); }
咱們在src/plugins/confirm.js中經過了一些方法找到了組件掛載點,組件元素,組件中的方法。this
這個組件不比vuetify自帶的v-dialog一開始就是長在文檔中的,而是須要咱們手動appendChild的方式將元素插入文檔中。prototype