HyperJSON 跨框架通用的布局描述协议

广告位招租
扫码页面底部二维码联系

用JSON描述布局,是低代码热潮下的大势本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net所趋。通过http传输一段JSON,就可著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。以在前端基于一套引擎代码,渲染出完全不同著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】的界面和交互,这是低代码分发的一种重要形转载请注明出处:www.tangshuang.net【未经授权禁止转载】式。这一背景下,JSON Schema原创内容,盗版必究。被委以重任,被广泛采用。但在尝试使用之后未经授权,禁止复制转载。【作者:唐霜】,我发现JSON Schema只适合描述【未经授权禁止转载】原创内容,盗版必究。数据结构(如后端的数据模型),而不适合描本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net述布局。而结合现代前端开发范式,我提出了【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】一种HyperJSON,即HyperSc本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。ript的JSON表达,更适合用来让JS未经授权,禁止复制转载。【转载请注明来源】ON描述布局。

原创内容,盗版必究。【转载请注明来源】【转载请注明来源】【本文受版权保护】原创内容,盗版必究。

HyperScript本文作者:唐霜,转载请注明出处。

本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】

在react、vue中被广泛使用,未经授权,禁止复制转载。hyperscript【本文首发于唐霜的博客】是用javascript描述hypert本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.netext(超文本)的一种方式。

【作者:唐霜】【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net
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实现这一效果,并进行了【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】内部约束。

【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】未经授权,禁止复制转载。

HyperJSON著作权归作者所有,禁止商业用途转载。

转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。【作者:唐霜】【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。

为了用JSON描述布局,可将HyperS转载请注明出处:www.tangshuang.net原创内容,盗版必究。cript的表达形式进行转化,并再进一步【版权所有,侵权必究】原创内容,盗版必究。进行内部规范。例如,我们将下面的jsx用【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。JSON来表达:

原创内容,盗版必究。转载请注明出处:www.tangshuang.net原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。
function MyComponent() {
  return (
    <div className="hyperjson-container">
      <h3>HyperJSON</h3>
      <p>HyperJSON is a schema for discribing JSX</p> 
    </div>
  )
}

用JSON描述就是:著作权归作者所有,禁止商业用途转载。

本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】
["div", { "className": "hyperjson-container" },
    ["h3", null, "HyperJSON"],
    ["p", null, "HyperJSON is a schema for describing JSX."]
]

简单说,就是将createElement【作者:唐霜】未经授权,禁止复制转载。的参数用嵌套(递归)的JSON来表示。数【转载请注明来源】转载请注明出处:www.tangshuang.net组的第一个值代表要使用的组件,第二个值代【版权所有,侵权必究】【未经授权禁止转载】表渲染组件时使用的props,后面剩下的本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】值表示组件的children,child【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】ren部分将会作为hyperjson递归【作者:唐霜】【原创内容,转载请注明出处】处理。

【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】

HyperJSON就是基于这样的表达方式转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。,增加了一些语法规则:

【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net
  • 动态语法: 【本文受版权保护】
    • 表达式:在JSON中使用特殊的标记 原创内容,盗版必究。{} 指定该标记内的内容为动态语法表达式著作权归作者所有,禁止商业用途转载。
    • 未经授权,禁止复制转载。未经授权,禁止复制转载。【本文首发于唐霜的博客】【转载请注明来源】
    • 作用域:作用域中只能读取该作用域内预设的【原创内容,转载请注明出处】【未经授权禁止转载】变量,预设变量由props指定
    • 【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】
    • 函数式:属性名以 【未经授权禁止转载】()【原创内容,转载请注明出处】(p1,p2,p3) 的形式结尾的,表示这是一个函数,函数体【版权所有,侵权必究】【原创内容,转载请注明出处】为动态语法表达式
    • 【作者:唐霜】【本文首发于唐霜的博客】未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。
  • 【本文受版权保护】本文作者:唐霜,转载请注明出处。原创内容,盗版必究。
  • 宏:属性末尾以【访问 www.tangshuang.net 获取更多精彩内容】!结尾,表示这是一个需要使用解析器再次解析【本文首发于唐霜的博客】原创内容,盗版必究。的jsx表达体
  • 【作者:唐霜】未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】

一个简单的HyperJSON示例:转载请注明出处:www.tangshuang.net

著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。
{
  "props": ["value", "onChange"],
  "render!": [
    "input,
    { "value": "{ value }", "onChange(e)": "{ onChange(e.target.value) }" }
  ]
}

下面我会详细解释其中的每一部分。本文作者:唐霜,转载请注明出处。

【版权所有,侵权必究】【本文受版权保护】著作权归作者所有,禁止商业用途转载。

动态语法【本文受版权保护】

【版权所有,侵权必究】【转载请注明来源】【本文受版权保护】

HyperJSON表达和JSX一致的布局【版权所有】唐霜 www.tangshuang.net【作者:唐霜】描述,但是我们都知道,JSX是给视图框架著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。实时运算的材料,要得到结果,往往依赖一些【作者:唐霜】【原创不易,请尊重版权】变量(状态)才能算出实时的布局。因此,在【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.netHyperJSON中,需要添加一些动态语【作者:唐霜】【本文受版权保护】法来支持这种计算。

未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】

表达式本文版权归作者所有,未经授权不得转载。

【原创内容,转载请注明出处】【未经授权禁止转载】【原创不易,请尊重版权】

动态语法表达式以 著作权归作者所有,禁止商业用途转载。{} 为标记,例如:【本文首发于唐霜的博客】

【版权所有】唐霜 www.tangshuang.net转载请注明出处: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本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。

作用域著作权归作者所有,禁止商业用途转载。

【转载请注明来源】【本文首发于唐霜的博客】【原创内容,转载请注明出处】

在JSX中,我们习惯使用如下语法:【版权所有】唐霜 www.tangshuang.net

【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。
function MyComponent(props) {
  return <input value={props.value} onChange={props.onChange} placeholder="请输入..." />
}

通过 {} 来表达值是动态值,̶原创内容,盗版必究。【转载请注明来源】1;” 表达静态值。它的作用本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。域就是组件所在的作用域,具体到上面这段代【本文受版权保护】转载请注明出处:www.tangshuang.net码,就是指 with(props) 这个未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。作用域。

未经授权,禁止复制转载。原创内容,盗版必究。本文作者:唐霜,转载请注明出处。【本文受版权保护】【原创不易,请尊重版权】

而在HyperJSON中,由于一段Hyp【未经授权禁止转载】转载请注明出处:www.tangshuang.neterJSON只描述一个组件的内容,因此,【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】它需要有一个前置的描述,也就是对 pro转载请注明出处:www.tangshuang.net【未经授权禁止转载】ps 的描述:

转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】
{
  "props": ["value", "onChange"],
  "render!": [ ... ]
}

上面的代码中,”props&【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。#8221;指明了当前作用域可以使用那些【未经授权禁止转载】【本文受版权保护】从props上读取的属性值。它相当于真实【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】js代码:

【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】
function Component(props) {
  const { value, onChange } = props
  ...
}

“props”的【原创内容,转载请注明出处】【原创内容,转载请注明出处】形式有三种:

转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。【本文受版权保护】未经授权,禁止复制转载。
  • "props": "$props" 字符串,这种形式表示在内部用`$pro【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。ps`表示props本身
  • 【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】
  • "props": ["onSubmit"] 字符串数组,这种形式表示从 props未经授权,禁止复制转载。【本文首发于唐霜的博客】 读取 onSubmit 属性后,传入内【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】部,内部使用 onSubmit
  • 未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。
  • "props": { "name": "$name" } 对象,这种形式是给属性取一个别名,这里【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net的意思是用$name代表props.na转载请注明出处:www.tangshuang.net【转载请注明来源】me,在内部直接使用$name
  • 本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】未经授权,禁止复制转载。

例如:【版权所有】唐霜 www.tangshuang.net

【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net
{
  "props": {
    "value": "$value"
  },
  "render!": [
    "input",
    { "value": "{ $value }" }
  ]
}

通过在顶层的props属性中规定,我们给著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net予了一个HyperJSON对象作用域。

【原创不易,请尊重版权】【作者:唐霜】本文版权归作者所有,未经授权不得转载。

函数式【访问 www.tangshuang.net 获取更多精彩内容】

本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。

上面示例代码中已经出现了函数式:【本文受版权保护】

本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。
["input", { "onChange(e)": "{ onChange(e) }" }]

函数式中的参数,会覆盖上一级作用域中的变【本文受版权保护】未经授权,禁止复制转载。量。

【未经授权禁止转载】【原创内容,转载请注明出处】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。

原创内容,盗版必究。

【原创不易,请尊重版权】未经授权,禁止复制转载。未经授权,禁止复制转载。【本文受版权保护】

默认情况下props部分表达的是值或函数【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net,但有的时候,你需要让它赋予新的含义,比【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。如当你需要接收一个jsx作为props的【未经授权禁止转载】【原创不易,请尊重版权】一部分的时候:

【转载请注明来源】【转载请注明来源】【本文受版权保护】著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。
<SomeItem
  title={<h3>title</h3>}
  content={<div>content</div>}
/>

这种时候,HyperJSON通过宏来定义原创内容,盗版必究。【版权所有,侵权必究】这种特殊需求。

【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】【原创不易,请尊重版权】
["SomeItem", {
  "title!": ["h3", null, "title"],
  "content!": ["div", null, "content"]
}]

通过在属性的末尾加一个 ! 来表达这是一【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。个特殊的props属性,需要用特殊的解释著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。器来执行它的值。

【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】未经授权,禁止复制转载。

其他方面【转载请注明来源】

本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。【转载请注明来源】

Fragment【转载请注明来源】

本文版权归作者所有,未经授权不得转载。【作者:唐霜】原创内容,盗版必究。【转载请注明来源】【转载请注明来源】

内置的组件,等于React.Fragme原创内容,盗版必究。【原创内容,转载请注明出处】nt,例如:

著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net
["Fragment", {}, 
  ["div"],
  ["div"]
]

null【未经授权禁止转载】

【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。

在jsx中是支持null的,同时,基于某【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。些特定的语法,也需要null支持。例如:

转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。未经授权,禁止复制转载。
<div>
  {v === 1 ? <div>1111</div> : null}
  {v === 2 ? <div>222</div> : null}
</div>

在HyperJSON中如下表达:未经授权,禁止复制转载。

原创内容,盗版必究。原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】【本文首发于唐霜的博客】
["div", {}, 
  ["{ v === 1 ? 'div' : null }", {}, "1111"],
  ["{ v === 2 ? 'div' : null }", {}, "2222"]
]

当HyperJSON中的第一个值为nul【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】l时,表示这一句将不被渲染。

【本文受版权保护】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。

结语【未经授权禁止转载】

【原创不易,请尊重版权】【原创内容,转载请注明出处】【未经授权禁止转载】【原创内容,转载请注明出处】

HyperJSON是一种新的协议,面对新【本文受版权保护】【关注微信公众号:wwwtangshuangnet】事物,不同的人接受程度不同。目前 Hyp【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。erJSON 已经在腾讯内源项目 For原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】mast 和前端框架 Nautil【本文首发于唐霜的博客】 中使用。如果你觉得这种协议有助于你的项【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】目,不妨和我一起探讨。

转载请注明出处:www.tangshuang.net【未经授权禁止转载】【作者:唐霜】【作者:唐霜】

2021-03-01 5300

为价值买单,打赏一杯咖啡

本文价值53RMB
已有4条评论
  1. blesstosam 2021-05-17 11:31

    市面上很多低代码平台都说用json schema协议来表达视图,但是我发现其实都是用json;我们现在的json目前来说都是到组件级别的,还没到html标签级别

    • 否子戈 2021-05-17 11:33

      是的,在真实的场景下面,肯定是以组件为单位,不可能细到一个单个html标签为单位

      • blesstosam 2021-05-17 11:37

        老哥,你是作者吗?可以加个微信方便后面交流哇!805902285

        • 否子戈 2021-05-17 12:14

          你可以扫博客地下的二维码关注我和我聊天哦