2019独角兽企业重金招聘Python工程师标准>>>

 “React 和 Vue 哪个更好?” 论坛上经常看到这样的问题,然后评论区就直接开战了。也有朋友转行做前端,问我该学React还是Vue。几年前,可能确实有必要考虑下到底该选择哪一个,毕竟前端圈子这么乱,谁又知道Vue能走多远?React会不会不维护了呢?可现在两者生态都很不错,Vue确实好用,React学习成本也没有传闻中那么高,template很好用,jsx也更灵活。可以两者都去玩玩,根据个人喜好和项目需要来选择用哪个。而如果能够结合两者的优点,那岂不是很有趣?

 我刚转前端的时候,用的是vue版本好像还是1.0,那时候的感觉就是数据绑定比jquery操作dom省事儿太多了。后来又接触了React,之后的项目大部分用React写的,现在偶尔也用vue,总体感觉就是vue单文件组件结构比较清晰,模板指令也很好用,而jsx更加灵活,之前有在react状态管理部分做一些尝试,可以像普通function一样去更新状态,也一直想在jsx中加上类似vue里面的模板指令,直到前几天比较闲,总算实现了 “条件渲染”和 “列表渲染”,结果还算不错,过程也挺有趣。

 先来看看结果吧,以前要根据不同状态来控制模块是否显示,我们大概要写这样的代码:

render(){const visible = truereturn(<div>{visible ? <div>content<div>: ''}</div>)
}

 现在可以这么玩:

render(){const visible = truereturn(<div><div r-if = {visible}>content</div></div>)
}

 另一种常见的场景就是根据一个数组来渲染出一个列表,一般是这么写:

render(){const list = [1, 2, 3, 4, 5]return(<div>{list.map((item,index)=>(<div key={index}>{item}</div>))}</div>)
}

 现在可以更简洁:

render(){const list = [1, 2, 3, 4, 5]return(<div><div r-for = {item in list}>{item}</div></div>)
}

 以上代码会自动设置key,值为当前元素的索引。如果你想要自定义key,也可以加上,改成

<div r-for = {(item,index) in list} key = {index+1}>{item}</div>

 结果还算不错吧,代码更简短,语义也比较明确,体验也不必vue里面的模板指令差,个人感觉在“”里面写js有点奇怪。而在{}里面写就很自然,就是普通的js代码块嘛。

 至于实现方法嘛,其实很简单,总共才几十行代码,就是写了一个babel插件。

 我们写的jsx也是通过babel转译成普通js代码的,然后才能在浏览器中运行,而babel编译主要分为三个阶段:解析、转换、生成目标代码。解析部分就是将源代码解析成抽象语法树ast,转换过程是对ast做一些处理,而生成目标代码部分就是将ast再转换成js代码。babel-plugin就是在转换部分做一些工作。

 比如对于以下jsx:

<div r-if = { visible }>{content}</div>

 转换成的ast结构大概是:

{type: 'CallExpression',callee: {},arguments: {properties: []}
}

 目标代码为:

React.createElement('div',{'r-if': visible},content
)

 React.createElement()方法调用对应ast中的CallExpression, React和createElement在callee中可以找到,可以以此来找出createElement(), r-if 等属性以及第三个参数content在arguments的properties数组中能找到。有了这些信息,我们就可以遍历ast,找到那些callee为React.createElement的CallExpression, 然后判断arguments中如果出现了r-if, 就对ast做以下修改:首先移除r-if属性,避免死循环;然后在CallExpression对应的节点外面再套一层ifStatement, 如此一来,转换后的ast生成的目标代码大致如下:

if(visible){React.createElement('div',{'r-if': visible},content)
}

 至此,我们的目标就已经达到了,至于r-for列表渲染,原理类似,先找出有r-for属性的CallExpression, 然后构造一个map方法对应的CallExpression, 当前CallExpression作为参数传给map方法即可。需要注意的是,在同一次遍历中解析出 r-if 和 r-for 的话,需要把map放在外层,ifStatement放在里面,如果觉得这样做结构比较混乱,可以拆分成不同的插件。

 最后再说一下babel-plugin的写法,其实也就是一个方法:

module.exports = function ({ types: t }) {return {visitor: {CallExpression(path) {// 在这里通过修改path来修改ast。},Identifier(path) {}}}
}

 types类型为babel-types, 提供了一些类似loadash的操作方法,比如做一些判断、构造节点。visitor里面写对应类型节点的遍历方法, 比如遍历标识符类型的就写在Identifier中,方法调用就写在CallExpression中。

 本文中提到的r-if 和 r-for 已经写成了一个插件,可以在github仓库中找到:https://github.com/evolify/babel-plugin-react-directive 同时也发布到了npm仓库,可以直接安装:

yarn add --dev babel-plugin-react-directive

 然后在.babelrc中配置即可:

{"plugins": ["react-directive"]
}

 我想要的目的已经达到了,但这并未结束,才刚刚开始,还可以实现其他的一些指令,比如r-if 是模块渲染或者不渲染的,我们经常也会遇到这种需求:只是单纯的控制元素可见或者不可见,但元素还是占用空间的,也就是控制visibility, 这也可以写成一个指令。而babel能做的远远不止如此,无聊的时候可以好好玩一玩。

转载于:https://my.oschina.net/evolify/blog/1936279

React骚操作——jsx遇到template-directive相关推荐

  1. 学习React从接受JSX开始

    详情参考官方JSX规范 虽然JSX是扩展到ECMAScript的类XML语法,但是它本身并没有定义任何语义.也就是说它本身不在ECMAScript标准范围之内.它也不会被引擎或者浏览器直接执行.通常会 ...

  2. 骚操作!有了这款神器,轻轻松松用Python写APP!(文末彩蛋)

    本文转自机器之心  作者:Adrien Treuille 机器之心编译 参与:魔王.一鸣 机器学习开发者想要打造一款 App 有多难?事实上,你只需要会 Python 代码就可以了,剩下的工作都可以交 ...

  3. Element-UI中关于table表格的那些骚操作

    最近的项目中使用到element-ui组件库,由于做的是后台管理系统,所以经常需要操作表格,编辑样式的过程中遇到一些问题,官网针对table给出了很多的api,自己可以自定义,基本能满足产品需求,但是 ...

  4. React简介、虚拟DOM、Diff算法、创建React项目、JSX语法、组件、组件声明方式、组件传值props和state、组件的生命周期

    React简介: 前面只是简单介绍移动APP开发,后面还会继续深入介绍移动app开发:其中想要用ReactNative开发出更出色的应用,那么就得学好React,下面将介绍React: React 是 ...

  5. 数据库的 N 多骚操作了解一下?

    作者 | zone7 责编 | 郭   芮 本文来介绍一下 Python 与 MongoDB 数据库的使用,走起! MongoDB GUI 工具 首先介绍一款 MongoDB 的 GUI 工具 Rob ...

  6. vue列表项吸顶 js+css两种 骚操作

    demo需求:vue项目中,在列表里,滑动到哪个日期的时候,哪个日期就吸顶显示: js方法: 用js的方法思路:获取每一项item的底部距离顶部的高度,把所有的高度放在一个数组里面,在去循环比对,在使 ...

  7. 各种骚操作试试 V7变回V5试试,直接变胖FAT,刷。。。2020-10-26

    本文稿原创,未经许可授权,不得转载!!!! 机器买回来还是很兴奋的... 查资料,看说明,学技术....终于!从廋变成胖的了....兴奋! 买了二个,一个胖一个廋,两全了,接入AC,配置,一开始不成功 ...

  8. React教程(二)——jsx语法、条件渲染、列表渲染

    1.JSX 语法 在react中,就是使用jsx的语法,来实现DOM元素的展示.一个基本的jsx语法的react模板如下: <div>{this.props.title}</div& ...

  9. React 简介 及 JSX语法

    文章目录 React 简介 React 概述及特点 React 虚拟DOM React 渲染机制 React 基本使用 JSX 语法 createElement()方法深究 JSX语法规则 React ...

  10. 五分钟没有操作自动退出_这又是什么骚操作??5只蚂蚁战略配售基金拟增设B类份额,自动赎回退出!!...

    他来了,他来了,这又是什么骚操作??昨天,五只创新未来18个月封闭运作混合型证券投资基金发布联合声明,会为这个战略配售基金安排一个月的退出选择期. 5只创新未来18个月封闭运作混合型证券投资基金发布联 ...

最新文章

  1. matlab读取一个文件的图片大小,Matlab读取文件夹中子文件夹中的图片并修改尺寸...
  2. 自动sqlldr脚本
  3. 生日快乐的代码_生日快乐,我的上电!
  4. Centos7手动安装OpenStack Mitaka版本--KeyStone安装
  5. Python二十个小技巧
  6. smarty课程---最最最简单的smarty例子
  7. 流量控制与拥塞控制区别
  8. python3 gui tk代码_【基础】学习笔记30-python3 tkinter GUI编程-实操12
  9. html vba 单元格 格式,VBA设置单元格格式之——字体
  10. Java使用独立数据库连接池(DBCP为例)
  11. 转:iPhone官换机和新机的区别
  12. 25个创新的仪表板(管理面板)设计示例
  13. Add NIC to Openfiler 2.3
  14. 如何利用 HBuilderX 制作图文混排的网页
  15. 快速入门学习qt5--mian主函数代码详解
  16. 留人间多少爱,迎浮世千重变;和有情人,做快乐事, 别问是劫是缘
  17. 百度谷歌雅虎三大搜索引擎本土功能大PK
  18. Stata数据统计分析软件v16.0版本更新
  19. 粉丝投稿!分享自己的携程后台一面+二面+HR面,希望对大家有帮助!
  20. Python OpenCV 修改一寸照片底色,图像处理取经之旅第 20 天

热门文章

  1. java 30天之前,Java获取当前时间30天之前的时间
  2. 4种方案,帮你解决Maven创建项目过慢问题
  3. 用python爬取图片和搞笑段子
  4. Android TV开发总结(二)构建一个TV Metro界面(仿泰捷视频TV版)
  5. Linux系统kill端口占用简书,MAC/Linux解决端口占用
  6. append()方法_python之append方法容易踩的坑
  7. 朗逸机器人_几张动图告诉你,工业机器人无所不能!
  8. Java数组--数组常用的办法;
  9. 创建crawlspider爬虫 学习笔记
  10. crontab关于 >/dev/null 2>1输出重定向问题