无代码平台就是一个一个的组件当成积木,通过拖拉拽的方式搭建起来,构建自己的应用。前端有前端组件,如果不够自己增加组件,后端有后端的组件,如果不够自己增加组件,用统一的组件间传参、组件穿透、前后端穿透等技术,组建出自己希望的个性化功能,和复杂的业务场景。
今天我们将自定义组件的源码分享出来,大家可以共同验证一下。
先看源码,很简单一共127行:
1、template就是一个很简单的component组件
使用div包装起来,主要是为了v-if的重新刷新,如果自定义组件内容发生变化,或者父窗体中存在多个diy组件时,可以通过resetConfigData后重新渲染自定义组件的内容。
2、props定义了一个config参数,作为对象参数,其下可以传递很多很多参数,其中最重要的参数就是id和sjxdm,因为自定义组件是通过我的无代码平台传递参数的,无代码平台任何元素都会有id,对于select、checkbox、radio、diycom等组件都会有sjxdm,所以使用这两个参数作为定义一个自定义组件的标识。
props: {
config: {
type: Object,
default: ''
}
},
3、data中定义了两个参数:diycomponet和reloadPage
diycomponet是存储组件的对象,其中key为组件的id,value为组件DOM
reloadPage是用于在resetConfigData后二次刷新自定义组件内容的v-if变量
data() {
return {
diycomponet: {},
reloadPage: true
};
},
4、methods函数体中定义了getConfigData、resetConfig、init、comChange、reloadDiyCom五个函数
getConfigData函数是父组件获取当前自定义组件的参数内容的函数,其中直接调用了自己编写的自定义代码中的getConfigData函数,想给父组件返回什么结果,自己定义即可。
getConfigData(id) {
if (this.$refs[this.config.id]) {
if (this.$refs[this.config.id][0]) {
if (this.$refs[this.config.id][0].getConfigData) {
return this.$refs[this.config.id][0].getConfigData(id);
}
} else {
if (this.$refs[this.config.id].getConfigData) {
return this.$refs[this.config.id].getConfigData(id);
}
}
}
return null;
},
resetConfig函数是父组件向当前自定义组件赋值的函数,其中直接调用了自己编写的自定义代码中的resetConfig函数,想根据父组件传递的config参数为自己的组件设置什么结果和央视,自己定义即可。
resetConfig(config) {
if (this.$refs[this.config.id]) {
if (this.$refs[this.config.id][0]) {
if (this.$refs[this.config.id][0].resetConfig) {
this.$refs[this.config.id][0].resetConfig(config);
}
} else {
if (this.$refs[this.config.id].resetConfig) {
this.$refs[this.config.id].resetConfig(config);
}
}
}
},
init函数是ajax请求服务器自定义组件的编写内容,获取成功后,调用reloadDiyCom进行渲染自定义组件。
init() {
this.gyservice({
gzuuid: '14e7ddfbf6084114a22ee151f9b697ca',
comuuid: this.config.sjxdm
}).then((res) => {
if (res && res.code) {
if (res.code !== '200' || res.msg != 'success') {
this.$message.error(res.msg);
return;
}
this.reloadDiyCom(res);
}
});
},
reloadDiyCom函数是重点:
1)获取到自定义编写的组件内容字符串后,将其重新组装到一个函数字符串中
2)通过eval函数将函数字符串加载到内存中变为一个函数变量diycomDef
3)通过调用这个内存函数,将字符串中定义的内容变成实实在在的js变量diyCom
4)重新组装一个vue的模版,将自己编写的字符串函数和变量组装到对应的vue模版中的data、props、methods等等
5)将重新组装的这个vue模版放入diycomponet变量中,同时也就是给component组件做了渲染
6)为了保险起见,通过reloadPage对组件进行二次刷新
reloadDiyCom(res) {
if (res.result.diycom) {
let content = res.result.diycom.component_content;
let func = '( function(_this){\r\n';
func = func + content + '\r\n';
func = func + 'let diycom = {};\r\n';
func = func + 'if (template){\r\n';
func = func + ' diycom["template"] = template;';
func = func + '}\r\n';
func = func + 'if (data){\r\n';
func = func + ' diycom["data"] = data;';
func = func + '}\r\n';
func = func + 'if (props){\r\n';
func = func + ' diycom["props"] = props;';
func = func + '}\r\n';
func = func + 'if (methods){\r\n';
func = func + ' diycom["methods"] = methods;';
func = func + '}\r\n';
func = func + 'return diycom;\r\n';
func = func + '}\r\n';
func = func + ')';
let diycomDef = {};
diycomDef['diycom'] = eval(func);
let diyCom = diycomDef['diycom'](this);
this.diycomponet[this.config.sjxdm] = {
template: diyCom.template ? diyCom.template : '未配置template',
props: {
config: {
type: Object,
default: {}
}
},
data() {
return diyCom.data ? diyCom.data : {};
},
created() {
if (this.created) {
this.created();
}
},
mounted() {
if (this.mounted) {
this.mounted();
}
},
methods: diyCom.methods ? diyCom.methods : {}
};
this.reloadPage = false;
this.$nextTick(() => {
this.reloadPage = true;
});
}
}
5、comChange函数是将自定义组件发生的change事件传递给父组件,让父组件自己区编写代码接收,在自定义组件的编写中,在任何函数中都可以通过this.$emit('change',val,action)的方式向父组件传递消息,触发父组件的响应。
其中val是要给父组件传递的参数
action可以来区分想要父组件做什么动作。
搞定!!
感谢关注!!