1、需求:
用vue 正常写一个弹窗组件想必大家都会,但是如果你想像Mintui 通过以下方式调用, 该如何开发呢?
let options = {
content: '展示的内容',
}
this.$alert(options).then(() => {
this.changeStatus("save", true);
}).catch(e => {
console.log("取消", e)
})
2、思路:
2.1 那我们倒着想:要想this.$alert的使用,说明$alert是插件
。main.js
main.js 中一定是Vue.use(Alert) 或者Vue.prototype.$alert = Alert;
Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
// main.js 中
import Alert from "./components/alert/index"
Vue.use(Alert);
2.2 那么如何开发一个Vue.use的插件呢?index.js
import confirmDialog from './confirmDialog.vue'; // 引入弹窗组件样式i
Alert.install = function (Vue) {
let ConfirmVue = Vue.extend(confirmDialog); // 创建一个构造器
ConfirmVue.prototype.callBack = defaultCallBack; //添加实例方法
let container = null;
Vue.prototype.$alert = (params = {}) => { //添加实例方法
if (!container) {
container = new ConfirmVue().$mount() //创建ConfirmVue实例
document.body.appendChild(container.$el) //挂载到body上
}
}
}
export default Alert;
2.3 处理确认后走进.then()函数
如果想要.then 调用, 说明点击确定按钮的时候一定返回了一个promise,那么这里的核心就在于, 你在index.js中的resolve状态不要调用, 要先保存起来, 放在原型方法上, 等到点击确定按钮的时候再去调用this.callBack()
function defaultCallBack(action) {
if (!action) currentMsg.reject()
currentMsg.resolve()
}
ConfirmVue.prototype.callBack = defaultCallBack;
return new Promise((resolve, reject) => {
currentMsg = {
resolve,
reject
}
})
confirmHandle() { // 点击确认按钮
this.callBack(true);
this.isShow = false;
},
总结:
大概思路如下:
步骤1 :
- 首先新建一个文件夹Alert: 包含 样式组件dialog.vue + index.js(最主要的)
- 编写一个dialog.vue组件并传入一个options
- 编写index.js 开发插件(install)
- main.js中Vue.use(插件)
- 组件中使用this.$alert插件
index.js详情:
大概思路:
- 引入dialog.vue组件
- Alert.install=function(){} 为了之后使用Vue.use()
- Vue.prototype.alert
- ConfirmVue = Vue.extend(dialog) 创建构造器
- new ConfirmVue() 并appendChild挂载到body中
- return 一个new promise ,把resolve状态存起来
- 点击弹窗按钮的时候 调用原型上的回调函数callback
代码:
dialog.vue
<template>
<div class="confirm-dialog-wrap" @touchmove.prevent v-if="isShow">
<div class="dialog-box" ref="dialogBox">
<div class="confirm-header"></div>
<div class="confirm-content">{{options.content}}</div>
<div class="button-group">
<span class="cancel-btn" @click.stop="cancelHandle">{{options.cancelText}}</span>
<span class="confirm-btn" @click.stop="confirmHandle">{{options.confirmText}}</span>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
options: {
cancelText: 'Cancel',
confirmText: 'Confirm',
content: '这里是内容',
},
isShow: false
}
},
methods: {
show(params) {
Object.assign(this.options, params) //合并参数
this.isShow = true;
},
cancelHandle() {
this.callBack(false);
this.isShow = false;
},
confirmHandle() {
this.callBack(true);
this.isShow = false;
}
},
}
</script>