用JSON描述布局,是低代码热潮下的大势本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。所趋。通过http传输一段JSON,就可【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】以在前端基于一套引擎代码,渲染出完全不同【本文受版权保护】【版权所有】唐霜 www.tangshuang.net的界面和交互,这是低代码分发的一种重要形【本文首发于唐霜的博客】【原创不易,请尊重版权】式。这一背景下,JSON Schema未经授权,禁止复制转载。被委以重任,被广泛采用。但在尝试使用之后原创内容,盗版必究。【版权所有,侵权必究】,我发现JSON Schema只适合描述【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。数据结构(如后端的数据模型),而不适合描【本文首发于唐霜的博客】【未经授权禁止转载】述布局。而结合现代前端开发范式,我提出了未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】一种HyperJSON,即HyperSc【未经授权禁止转载】【本文首发于唐霜的博客】ript的JSON表达,更适合用来让JS【转载请注明来源】【原创不易,请尊重版权】ON描述布局。
【本文受版权保护】【原创不易,请尊重版权】【作者:唐霜】HyperScript【版权所有】唐霜 www.tangshuang.net
【原创内容,转载请注明出处】【未经授权禁止转载】【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】在react、vue中被广泛使用,未经授权,禁止复制转载。hyperscript【未经授权禁止转载】是用javascript描述hypert未经授权,禁止复制转载。【转载请注明来源】ext(超文本)的一种方式。
未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。【转载请注明来源】本文版权归作者所有,未经授权不得转载。var h = require('hyperscript')
h('div#page',
h('div#header',
h('h1.classy', 'h', { style: {'background-color': '#22f'} })),
h('div#menu', { style: {'background-color': '#2f2'} },
h('ul',
h('li', 'one'),
h('li', 'two'),
h('li', 'three'))),
h('h2', 'content title', { style: {'background-color': '#f22'} }),
h('p',
"so it's just like a templating engine,\n",
"but easy to use inline with javascript\n"),
h('p',
"the intention is for this to be used to create\n",
"reusable, interactive html widgets. "))
在react中,通过React.crea转载请注明出处:www.tangshuang.net【转载请注明来源】teElement实现这一效果,并进行了【转载请注明来源】本文版权归作者所有,未经授权不得转载。内部约束。
著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。HyperJSON本文版权归作者所有,未经授权不得转载。
【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【原创不易,请尊重版权】为了用JSON描述布局,可将HyperS【转载请注明来源】本文版权归作者所有,未经授权不得转载。cript的表达形式进行转化,并再进一步【转载请注明来源】著作权归作者所有,禁止商业用途转载。进行内部规范。例如,我们将下面的jsx用【本文首发于唐霜的博客】【原创不易,请尊重版权】JSON来表达:
【版权所有】唐霜 www.tangshuang.net【转载请注明来源】【作者:唐霜】转载请注明出处:www.tangshuang.netfunction MyComponent() {
return (
<div className="hyperjson-container">
<h3>HyperJSON</h3>
<p>HyperJSON is a schema for discribing JSX</p>
</div>
)
}
用JSON描述就是:【本文首发于唐霜的博客】
转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】原创内容,盗版必究。["div", { "className": "hyperjson-container" },
["h3", null, "HyperJSON"],
["p", null, "HyperJSON is a schema for describing JSX."]
]
简单说,就是将createElement【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net的参数用嵌套(递归)的JSON来表示。数【转载请注明来源】本文版权归作者所有,未经授权不得转载。组的第一个值代表要使用的组件,第二个值代【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net表渲染组件时使用的props,后面剩下的【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。值表示组件的children,child【作者:唐霜】原创内容,盗版必究。ren部分将会作为hyperjson递归原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。处理。
【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。HyperJSON就是基于这样的表达方式【本文受版权保护】本文作者:唐霜,转载请注明出处。,增加了一些语法规则:
【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。- 动态语法:
转载请注明出处:www.tangshuang.net
- 表达式:在JSON中使用特殊的标记 【访问 www.tangshuang.net 获取更多精彩内容】
{}指定该标记内的内容为动态语法表达式著作权归作者所有,禁止商业用途转载。 【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。【本文受版权保护】【原创不易,请尊重版权】
- 作用域:作用域中只能读取该作用域内预设的【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。变量,预设变量由props指定 【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】【未经授权禁止转载】
- 函数式:属性名以 【访问 www.tangshuang.net 获取更多精彩内容】
()或 【版权所有】唐霜 www.tangshuang.net(p1,p2,p3)的形式结尾的,表示这是一个函数,函数体本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。为动态语法表达式 本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】原创内容,盗版必究。
著作权归作者所有,禁止商业用途转载。【转载请注明来源】【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】
- 表达式:在JSON中使用特殊的标记 【访问 www.tangshuang.net 获取更多精彩内容】
- 宏:属性末尾以著作权归作者所有,禁止商业用途转载。
!结尾,表示这是一个需要使用解析器再次解析本文作者:唐霜,转载请注明出处。【本文受版权保护】的jsx表达体 【未经授权禁止转载】【本文受版权保护】【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。
一个简单的HyperJSON示例:原创内容,盗版必究。
原创内容,盗版必究。【原创不易,请尊重版权】【版权所有,侵权必究】{
"props": ["value", "onChange"],
"render!": [
"input,
{ "value": "{ value }", "onChange(e)": "{ onChange(e.target.value) }" }
]
}
下面我会详细解释其中的每一部分。著作权归作者所有,禁止商业用途转载。
【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。动态语法【原创内容,转载请注明出处】
原创内容,盗版必究。【作者:唐霜】本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】HyperJSON表达和JSX一致的布局未经授权,禁止复制转载。原创内容,盗版必究。描述,但是我们都知道,JSX是给视图框架【转载请注明来源】【原创内容,转载请注明出处】实时运算的材料,要得到结果,往往依赖一些【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】变量(状态)才能算出实时的布局。因此,在转载请注明出处:www.tangshuang.net【版权所有,侵权必究】HyperJSON中,需要添加一些动态语【本文首发于唐霜的博客】【原创不易,请尊重版权】法来支持这种计算。
本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】表达式本文版权归作者所有,未经授权不得转载。
未经授权,禁止复制转载。【未经授权禁止转载】转载请注明出处:www.tangshuang.net动态语法表达式以 本文版权归作者所有,未经授权不得转载。{} 为标记,例如:【本文首发于唐霜的博客】
["input", {
"value": "{ value }"
}]
其中 未经授权,禁止复制转载。value 的值 【版权所有,侵权必究】"{ value }" 中的 原创内容,盗版必究。value 部分就是表达式。表达式和javascr本文版权归作者所有,未经授权不得转载。【转载请注明来源】ipt表达式非常像,你可以在表达式中使用著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net一些运算符。例如
value + 1
ie ? '1' : '0'
parent.child // 返回一个子属性的值
{ a: 1 } // 返回一个对象
表达式不能有js中常见的语句,不支持复杂【转载请注明来源】【版权所有】唐霜 www.tangshuang.net表达式。
【本文受版权保护】【作者:唐霜】未经授权,禁止复制转载。作用域【版权所有,侵权必究】
【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】在JSX中,我们习惯使用如下语法:【原创不易,请尊重版权】
【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.netfunction MyComponent(props) {
return <input value={props.value} onChange={props.onChange} placeholder="请输入..." />
}
通过 {} 来表达值是动态值,̶本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。1;” 表达静态值。它的作用【转载请注明来源】【原创不易,请尊重版权】域就是组件所在的作用域,具体到上面这段代本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net码,就是指 with(props) 这个【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】作用域。
【未经授权禁止转载】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。而在HyperJSON中,由于一段Hyp【关注微信公众号:wwwtangshuangnet】【转载请注明来源】erJSON只描述一个组件的内容,因此,【作者:唐霜】原创内容,盗版必究。它需要有一个前置的描述,也就是对 pro著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】ps 的描述:
【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net{
"props": ["value", "onChange"],
"render!": [ ... ]
}
上面的代码中,”props&本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net#8221;指明了当前作用域可以使用那些本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net从props上读取的属性值。它相当于真实本文版权归作者所有,未经授权不得转载。【作者:唐霜】js代码:
本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】function Component(props) {
const { value, onChange } = props
...
}
“props”的著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net形式有三种:
【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。【转载请注明来源】"props": "$props"字符串,这种形式表示在内部用`$pro【原创不易,请尊重版权】【作者:唐霜】ps`表示props本身 本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。【原创不易,请尊重版权】
"props": ["onSubmit"]字符串数组,这种形式表示从 props转载请注明出处:www.tangshuang.net原创内容,盗版必究。 读取 onSubmit 属性后,传入内【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net部,内部使用 onSubmit 【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】
"props": { "name": "$name" }对象,这种形式是给属性取一个别名,这里【转载请注明来源】著作权归作者所有,禁止商业用途转载。的意思是用$name代表props.na【作者:唐霜】未经授权,禁止复制转载。me,在内部直接使用$name 【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【作者:唐霜】
例如:本文作者:唐霜,转载请注明出处。
本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。{
"props": {
"value": "$value"
},
"render!": [
"input",
{ "value": "{ $value }" }
]
}
通过在顶层的props属性中规定,我们给【作者:唐霜】【版权所有,侵权必究】予了一个HyperJSON对象作用域。
【原创内容,转载请注明出处】【本文受版权保护】原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net函数式【原创内容,转载请注明出处】
本文版权归作者所有,未经授权不得转载。【本文受版权保护】【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net【转载请注明来源】上面示例代码中已经出现了函数式:【本文受版权保护】
【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。["input", { "onChange(e)": "{ onChange(e) }" }]
函数式中的参数,会覆盖上一级作用域中的变【转载请注明来源】【关注微信公众号:wwwtangshuangnet】量。
【原创不易,请尊重版权】【原创不易,请尊重版权】【本文受版权保护】本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】宏【作者:唐霜】
著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。默认情况下props部分表达的是值或函数原创内容,盗版必究。【未经授权禁止转载】,但有的时候,你需要让它赋予新的含义,比本文版权归作者所有,未经授权不得转载。【本文受版权保护】如当你需要接收一个jsx作为props的【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。一部分的时候:
【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】<SomeItem
title={<h3>title</h3>}
content={<div>content</div>}
/>
这种时候,HyperJSON通过宏来定义【原创内容,转载请注明出处】【本文受版权保护】这种特殊需求。
【本文首发于唐霜的博客】【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】["SomeItem", {
"title!": ["h3", null, "title"],
"content!": ["div", null, "content"]
}]
通过在属性的末尾加一个 ! 来表达这是一著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。个特殊的props属性,需要用特殊的解释本文作者:唐霜,转载请注明出处。【未经授权禁止转载】器来执行它的值。
本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】其他方面本文作者:唐霜,转载请注明出处。
本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【作者:唐霜】著作权归作者所有,禁止商业用途转载。Fragment【版权所有】唐霜 www.tangshuang.net
未经授权,禁止复制转载。原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net内置的组件,等于React.Fragme本文版权归作者所有,未经授权不得转载。【本文受版权保护】nt,例如:
【原创不易,请尊重版权】【版权所有,侵权必究】转载请注明出处:www.tangshuang.net原创内容,盗版必究。["Fragment", {},
["div"],
["div"]
]
null【原创不易,请尊重版权】
【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。在jsx中是支持null的,同时,基于某【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】些特定的语法,也需要null支持。例如:
【原创内容,转载请注明出处】未经授权,禁止复制转载。【本文受版权保护】本文作者:唐霜,转载请注明出处。<div>
{v === 1 ? <div>1111</div> : null}
{v === 2 ? <div>222</div> : null}
</div>
在HyperJSON中如下表达:【未经授权禁止转载】
转载请注明出处:www.tangshuang.net【作者:唐霜】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。["div", {},
["{ v === 1 ? 'div' : null }", {}, "1111"],
["{ v === 2 ? 'div' : null }", {}, "2222"]
]
当HyperJSON中的第一个值为nul转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】l时,表示这一句将不被渲染。
【原创不易,请尊重版权】【本文首发于唐霜的博客】【作者:唐霜】转载请注明出处:www.tangshuang.net结语【原创内容,转载请注明出处】
【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】HyperJSON是一种新的协议,面对新【本文受版权保护】转载请注明出处:www.tangshuang.net事物,不同的人接受程度不同。目前 Hyp【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】erJSON 已经在腾讯内源项目 For【转载请注明来源】【本文首发于唐霜的博客】mast 和前端框架 Nautil【版权所有,侵权必究】 中使用。如果你觉得这种协议有助于你的项【本文受版权保护】【版权所有,侵权必究】目,不妨和我一起探讨。
未经授权,禁止复制转载。【未经授权禁止转载】【原创不易,请尊重版权】未经授权,禁止复制转载。2021-03-01 5245



市面上很多低代码平台都说用json schema协议来表达视图,但是我发现其实都是用json;我们现在的json目前来说都是到组件级别的,还没到html标签级别
是的,在真实的场景下面,肯定是以组件为单位,不可能细到一个单个html标签为单位
老哥,你是作者吗?可以加个微信方便后面交流哇!805902285
你可以扫博客地下的二维码关注我和我聊天哦