好家伙,
完整代码已开源
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 元素,并返回所有子元素的数组。
最终效果如下:
