jsx转为html,实战json、html、jsx的互转

场景

将下面的jsx转换为htmlconst items = ['one', 'two', 'three'];const SearchData = ({ data = [] }) => {  let list = null;  if (data.length) {

list = data.map((l, k) => (

{l}

));

} else {

list = (

暂无数据

);

}  return (    

匹配的员工:

{list}

);

};const jsx = (  

列表展示 {items.length} 项:

SEARCH DATA:

);

方案

方案一:自己遍历

所有的jsx你拿到的时候,都已经是 Babel 帮你转义过的了。所以,你其实拿到的是转义后的对象。所以你只需要将这对象转成你想要的结果。我们知道 Props 除了 key、ref、children 这几个特殊的,剩下的都对应到 dom 的 attribute。

做法

1、获取 displayName 作为 Tag

2、处理 props 作为 attribute

3、如果有children,则重复1、2、3、4,遍历 children,作为子元素

4、拼装 html 字符串

代码function getDisplayName(ele) {  if (typeof ele.type === 'string') {    return ele.type;

}  return ele.type.name || ele.type.displayName || 'No Name';

}function getAttrs(attrs) {  return Object.keys(attrs).map(attr => (attr === 'children' ? '' : `${attr}="${attrs[attr]}"`)).join('');

}function transfer(ele) {  if (typeof ele === 'string' || typeof ele === 'number') {    return ele;

}  const props = ele.props || {};  const children = React.Children.toArray(props.children || []);  const html = children.map(transfer);  const tag = getDisplayName(ele);  return `${html.join('')}${tag}>`;

}console.log(transfer(jsx));// 如果函数式的组件你也需要解析的话,则需要执行这个函数// congsole.log(transfer(SearchData({items: data})))

类库

方案二:通过 Babel 直接转

我们可以指定 Babel 在编译的时候调用某个函数。我们可以通过这个函数来生成我们需要的操作。

做法方法一 配置 .babelrcjson { "plugins": [ ["transform-react-jsx", { "pragma": "dom" // default pragma is React.createElement }] ] }

但是这种方法修改全部的 babel 转换行为。非常不推荐方法二

在代码中加一个注释/** @jsx h */,告诉 Babel ,用 h 函数处理 Babel 编译后的行为。参考WTF is JSX

代码/** @jsx h */function getDisplayName(ele) {  if (typeof ele === 'string') {    return ele;

}  return ele.name || ele.displayName || 'No Name';

}function h(name, attrs, ...children) {  const html = Array.isArray(children) ? children.join('') : children;  console.log('###################################');  console.log('name:', name);  console.log('attrs:', attrs);  console.log('children:', children);  const attr = Object.keys(attrs || {}).map(a => `${a}='${attrs[a]}'`).join(' ');  return `${html}${name}>`;

}console.log(jsx);

类库

与上面的情况了类似,如果我们要将那部分 jsx 转换为 json 格式的怎么办呢?答案很简单,不用刻意去转(?!)。因为 Babel 已经帮你转过了。你需要做的是把 Babel 编译后的 json 转成你想要的格式。此外,刚才的两种方案也是生效的。不同的是,之前的返回值是一段 html 文本,现在需要返回 json 格式的。我们以上面的方案二举例:/** @jsx h */function h(name, attrs, ...children) {  /*

// 函数式的组件(functional component)请根据需要转换

if (typeof name === 'function') {

return name(attrs);

}

*/

return {

tag: name,

attrs,

children,

};

}

console.log(jsx);html2jsx

场景

将下面的 html 转换为 jsx:const html = `  

Hi!

Here is a list of 3 items:

  • one
  • two
  • three
`;

方案

将 html 转为 jsx,实际上就是用 React.createElement 将 html 的结构重新生成一下,做到without jsx

做法

1、将 html 片段转成 dom

2、读取 dom 的 attributes, 处理特殊的 attribute,作为 ReactElement 的 props

3、读取 dom 的 tagName, 作为 ReactElement 的 type

4、如果 dom 有 children,则重复 2、3、5步,将返回值作为 ReactElement 的 children

5、返回 React.createElement(type, props, children)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值