投身烈火
Keep Walking

一种实现弹窗组件的方法

看到标题就应该知道,我又来水了……话说最近真是太忙,以至于读源码的事情被无限期搁置了(其实还不是你懒)……咳咳……言归正传,因为要做了个移动的项目,团队成员又大多是新手,所以选了vue作为基础框架。这周的工作中顺手封装了一些常用的组件,在这里记录下自己的想法,省的之后忘了,哈哈……

说到组件,最常用的应该就是弹窗组件了,而我们在使用vue或者react等框架渲染界面的时候,一般都需要事先将组件实例显示的写在render函数里面,而且需要配合一个标记组件是否显示的变量一起使用。

以vue为例,一般平时我们使用组件一般写成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<!-- ... -->
<dialog v-show="showDialog1">msg1</dialog>
<!-- ... -->
<dialog v-show="showDialog2">msg2</dialog>
<!-- ... -->
</template>
<script>
export default {
//...
data() {
return {
showDialog1: false,
showDialog2: false,
};
},
//...
}
</script>

有些组件这样使用没问题,但是有些组件,比如dialog组件,这样使用起来虽然也说不上不方便,但是与我们平时使用组件的习惯,还是有一定差异的。一般我们都是这样调用组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
let dialog1 = new Dialog('msg1');
let dialog2 = new Dialog('msg2');
export default {
//...
methods: {
fn1() {
dialog1.show();
},
fn2() {
dialog1.close();
dialog2.show();
},
},
//...
}
</script>

那么这样的调用方式是否能实现呢?答案是肯定的。以vue为例,需要用到Vue.extend方法创建子类来实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 首先简单定义一个组件选项
let dialogOptions = {
template: '<div v-show="show">{{msg}}</div>',
props: {
msg: String,
},
data() {
return {
show: false,
};
},
};
// 然后创建组件的构造函数
const DialogConstructor = Vue.extend(dialogOptions);
DialogConstructor.prototype.show = function() {
this.show = true;
};
DialogConstructor.prototype.close = function() {
this.show = false;
document.body.removeChild(this.$el);
this.$destroy();
};
// 最后组织自己的调用方法
const Dialog = (msg = '') => {
const instance = new DialogConstructor({
el: document.createElement('div')
});
instance.msg = msg;
document.body.appendChild(instance.$el);
return instance;
}

总的来说原则就是独立于当前应用,构建另一套数据结构。对于react,也应该可以使用类似的方案来实现组件。虽然这与官方文档中推荐的,一个应用使用一套数据结构的实现方案有冲突,但是这样就能够使用我们熟悉的方式去开发应用了。具体如何使用还是看个人喜好吧~~

好的那么由于时间不足,本期的博客就先写到这里,如果不出意外的话,maybe可能也许大概下周五会更新吧,能不能准时更新,就全看米娜桑点赞转发安利留言的热情了~!

白了个白~!