参考平台:
(开源版本的拖拽生成H5平台,类似易企秀、人人秀、夸克h5的可视化搭建系统)
具体技术介绍和内容:
基于Vue2.0开发,通过拖拽的形式,生成页面的工具,类似易企秀、百度 H5 等工具的可视化搭建系统
核心原理解析:
借助vue的createElement以及render函数将JSON转换为H5,以下是借助vue官方的事例整理转换的一套代码:
// 以下代码来自:https://cn.vuejs.org/v2/guide/render-function.html#createElement-参数
// @returns {VNode}
createElement(
// {String | Object | Function}
// An HTML tag name, component options, or async
// function resolving to one of these. Required.
'div',
// {Object}
// A data object corresponding to the attributes
// you would use in a template. Optional.
{
// (see details in the next section below)
},
// {String | Array}
// Children VNodes, built using `createElement()`,
// or using strings to get 'text VNodes'. Optional.
[
'Some text comes first.',
createElement('h1', 'A headline'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
抽象化
1.移除注释
2.把 createElement(tagName || componentOptions, {data}, children) 对应到上面的代码中,把 children 部分单独抽象成一个数组
3.整理之后的代码如下:
// a component options demo:
const MyComponent = {
props:['someProp'],
render(h) {
return h('span', this.someProp)
},
}
new Vue({
el: '#app',
// 这里的 render(createElement) 我们更常见的写法是:render(h)
// 关于这部分的解释,可以参见: https://segmentfault.com/q/1010000007130348?_ea=17466196
render(createElement) {
const pageJSON = [
'Some text comes first.',
createElement('h1', 'A headline'),
createElement(MyComponent /** component options */, {
props: {
someProp: 'foobar'
}
})
]
return h('div', {}, pageJSON)
}
})
// 再抽象一步
new Vue({
el: '#app',
render(h) {
const pageJSON = [
{component: 'span', text: 'Some text comes first.'},
{component: 'h1', text: 'A headline'},
{component: 'MyComponent', data: {props: {someProp: 'foobar'}} }
]
return h('div', {}, pageJSON.map(ele => {
return h(ele.component, ele.text ? ele.text : ele.data)
}))
}
})
// 再抽象一步(哎,不对啊,作者,我咋感觉你这一步啥都没做啊,你说对了)
const PageJSON = [
{component: 'span', text: 'Some text comes first.'},
{component: 'h1', text: 'A headline'},
{component: 'MyComponent', data: {props: {someProp: 'foobar'}} }
]
new Vue({
el: '#app',
render(h) {
return h('div', {}, pageJSON.map(ele => {
return h(ele.component, ele.text ? ele.text : ele.data)
}))
}
})
// 再抽象一步
const WorkJSON = {
title: '我是作品标题',
description: '我是作品描述',
created_time: '2019-09-01',
updated_time: '2019-09-01',
pages: [
elements: [
{component: 'span', text: 'Some text comes first.'},
{component: 'h1', text: 'A headline'},
{component: 'MyComponent', data: {props: {someProp: 'foobar'}} }
],
],
}
new Vue({
el: '#app',
render(h) {
return h('div', {}, WorkJSON.pages[0].elements.map(ele => {
return h(ele.component, ele.text ? ele.text : ele.data)
}))
}
})