好家伙,
完整代码已开源
https://github.com/Fattiger4399/ph-questionnaire.git
本片我们来讲述
如何将dsl的数据渲染为视图
1.数据格式
dsl: {
component: 'div',
wid: 0,
props: {
},
style: { background: ' #FFF8DC' },
children: [
{
wid: 1,//序号
component: 'ph-radio', //组件名
props: { //组件数据接口
No: 1,
title: "我是输入框",
options_1: "选项一一",
options_2: "选项二二"
},
style: { top: '300px', left: '300px', zIndex: '1', border: "2px dashed red" },//组件配置项
attrs: {
},
events: {
}
},
]
2.vue的h函数
h
函数是 Vue.js 中的一个辅助函数,通常用于创建虚拟 DOM 元素(VNode)。
在 Vue.js 中,h
函数实际上是 createElement
函数的别名
createElement
函数是 Vue.js 内部用来创建虚拟 DOM 元素(VNode)的核心函数。
h
函数接收三个参数
- 第一个参数:表示要创建的元素的标签名、组件或者函数。
- 第二个参数:是一个包含元素属性、样式、事件等信息的对象。
- 第三个参数:是元素的子元素,可以是一个数组或者单个元素。
3.编辑器代码解释
代码如下:
<script>
export default {
data() {
return {
a: true
}
},
props: ['dsl', 'model'],
render(h) {
let dsl = this.dsl;
return this.generator(h, dsl);
},
methods: {
adddraggable() {
},
select(e) {
console.log(e);
},
generator(h, dsl) {
//h(tagName,props,children)
//当前元素,元素属性,子元素
return h(dsl.component, this.generateProps(h, dsl), this.generateChildren(h, dsl));
},
generateProps(h, dsl) {
let self = this;
let result = {
}
result.props = {
...dsl.props
}
result.attrs = {
...dsl.attrs
}
result.style = { ...dsl.style }
if (self.model.selected) {
if (self.model.selected.wid == dsl.wid) {
// 获取所有的按钮元素
const allElements = document.getElementById('editor.div')
console.log(allElements)
}
}
if (dsl.events) {
result.on = {
click: function (e) {
// console.log(e, dsl.wid, this);
e.preventDefault();
self.$emit('select', { e, dsl });
},
};
}
return result;
},/**
* 该函数用于生成child节点
* @param {*} h
* @param {*} dsl
*/
generateChildren(h, dsl) {
let result = dsl.children &&
dsl.children.map((child) => this.generator(h, child))
|| [];
// (A&&B)||C
if (dsl.text) result.push(dsl.text)
// console.log(result)
return result;
}
},
mounted() {
}
}
</script>
解释
本质上是对props属性递归处理后,使用vue的h函数将dsl全部渲染出来
让我们把重点放在这句上
return h(dsl.component, this.generateProps(h, dsl), this.generateChildren(h, dsl));
-
generator
方法用于生成 Vue 元素,根据传入的dsl
配置信息,设置元素的属性、样式、事件等,并返回生成的元素。 -
generateProps
方法用于生成元素的属性,包括props
、attrs
和style
,同时根据条件判断是否添加事件监听器。 -
generateChildren
方法用于生成元素的子元素,遍历dsl
中的children
,对每个子元素调用generator
方法生成对应的 Vue 元素,并返回所有子元素的数组。
最终效果如下: