接上一篇《vue 开发插件 一》
完善插件交互逻辑
插件讲究高度配置化,弹框提示的插件要始终保持一个,并且要保证上一个弹框已经关闭
处理配置参数
定义一个方法来接受弹框内容和配置进行处理参数,并且有默认的参数,同时判断显示隐藏,
如果只是传入一个字符串,那就是直接作为弹框提示内容
// 记录最后一个弹框
let lastAlert = null;
function alert(config) {
// 默认的参数 和 组件的属性要同步
const defaultConfig = {
title: '',
useHtml: false,
button: '确定',
cusClass: '',
message: ''
};
// 保存最终配置
let _config = null;
// 参数处理
if(typeof config ==='sring'){
_config = Object.assign(defaultConfig,{message: config});
}else {
_config = Object.assign(defaultConfig,config);
}
return lastAlert;
}
es6 中 Object.assign 合并两个对象,如果合并的不是对象就会转化为对象;2、源对象的参数如果和合并目标参数重复就覆盖,第一个参数是目标,第二个参数是源对象,可以有很多源对象
展示和关闭的方法用异步处理完成时候的回调,点击按钮关闭用vue的once方法,点击事件将只会触发一次
async function show(config) {
return new Promise(resolve =>{
for(const key of Object.keys(config)){
$alert[key] = config[key];
}
// 组件提供的监听方法,点击确定的时候
$alert.$once('but-click',()=>{
// 控制显示隐藏
$alert.visible = false;
// 关闭之后的回调
resolve(undefined);
})
$alert.visible = true;
})
}
Object.keys 返回一个数组
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]
打开 app.vue 调用插件的入口页面看一下代码:
直接调用
tFn (){
// 插件可以直接this 调用
this.$alert();
}
目前可以正常打开和关闭弹框。在加入内容试试
tFn (){
// 插件可以直接this 调用
this.$alert('木子聊前端测试弹框');
}
发现没有内容弹框。原因是
if(typeof config ==='sring'){
这段代码,预期想判断是否是 字符串类型结果发现写错,结果走到了下一个判断,由于Object.assign 可以吧源对象转化为对象,但是组件没有预定义,参数导致没有办法显示
改一下
if(typeof config ==='string'){
在运行 npm run dev 浏览器打开,弹框正常运行。
为了校验代码的完整性,对照需求依次测试一下,回调方法
点击关闭的时候,在控制台打印,来证明证明回调方法可行
this.$alert('木子聊前端测试弹框').then(()=>{
console.log('控制台打印。。');
});
依据 返回 Promise 可以用then来回调,npm run dev 运行成功,
看一下自定义div标签,同时添加一个class
this.$alert({useHtml:true,
message:'<div>我是标签内容</div>',
cusClass:'testClass'
})
npm run dev 看效果
和预期一样;
完整插件代码:
import Alert from '../component/alert/index.vue'; // 引入组建
// 保存当前对象流程
let $alert = null;
// 记录最后一个弹框
let lastAlert = null;
function alert(config) {
// 默认的参数 和 组件的属性要同步
const defaultConfig = {
title: '',
useHtml: false,
button: '确定',
cusClass: '',
message: ''
};
// 保存最终配置
let _config = null;
// 参数处理
if(typeof config ==='string'){
_config = Object.assign(defaultConfig,{ message: config});
}else {
_config = Object.assign(defaultConfig,config);
}
// 展示弹框
lastAlert=show(_config);
return lastAlert;
}
async function show(config) {
return new Promise(resolve =>{
for(const key of Object.keys(config)){
$alert[key] = config[key];
}
// 组件提供的监听方法,点击确定的时候
$alert.$once('but-click',()=>{
// 控制显示隐藏
$alert.visible = false;
// 关闭之后的回调
resolve(undefined);
})
$alert.visible = true;
})
}
export default {
install (Vue,props = { visible: false }){
const AlertComponent = Vue.extend(Alert); //构造器创建子类
$alert = new AlertComponent({
el: document.createElement('div'),
propsData: {
...props
}
});
document.body.appendChild($alert.$el);
Vue.mixin({
created() {
},
methods: {
$alert(config) {
return alert(config);
}
},
});
}
}
如果你喜欢 欢迎关注留言。。谢谢