如何在前端编码时实现人肉双向编译

简介:

如何在前端编码时实现人肉双向编译

React+flux是目前最火的前端解决方案之一,但flux槽点颇多,例如store比较混乱,使用比较繁琐等,于是出现了很多第三方的基于flux优化的架构。

有人统计了目前主流的flux实现方案,感兴趣的可以看这里:Which Flux implementation should I use?

其中redux是目前githubstar最多的一个方案,该方案完全独立于react,意味着这套理念可以作为架构层应用于其他的组件化方案。同时官方也提供了react-redux库,帮助开发者直接使用react+redux快速开发。

个人理解它的主要特性体现在以下几点:

  1. 强制使用一个全局的storestore只提供了几个简单的api(实际上应该是4个),如subscribe/dispatch(订阅、发布),getState,replaceReducer

  2. store负责维护一个唯一的叫做state树的对象,其中state存储了应用需要用到的所有数据。

  3. store和顶层组件使用connect方法绑定,并赋给props一个dispatch方法,可以直接在组件内部this.props.dispatch(action)。 简单一点说,就是去掉了flux中组件和storeunbind/bind环节。当state变化时,自动更新components,不需要手动操作。

  4. 提供了applyMiddleware方法用于异步的action,并且提供了加入中间件的能力,例如打印日志追踪应用的所有状态变化。

  5. 对全局的数据state的操作,由多个reducer完成。每个reducer都是一个纯函数,接收两个参数stateaction,返回处理后的state。这点类似管道的操作。

接下来我们可以回答标题的问题了,即:如何在前端编码时实现人肉双向编(zi)译(can)。

其实就是使用coffee来编写react+redux应用。

我们来写个简单的hello world玩玩。

view部分

这部分和redux/flux无关,纯粹react的实现,使用jsx的话,render部分的代码大概长这样:


    
    
  1. render:function(){ 
  2.     return ( 
  3.         <div> 
  4.             <div class="timer">定时器:{interval}</div> 
  5.             <div>{title}</div> 
  6.             <input ref="input"><button>click it.</button> 
  7.         </div> 
  8.     ) 

那如何使用coffee写这段代码呢? 我们需要先将jsx编译这类似这样的js代码,请注意是用大脑编译:


    
    
  1. render:function(){ 
  2.     return React.createElement('div',null
  3.         React.createElement('div',{className:'timer'},'定时器'+this.props.interval), 
  4.         React.createElement('div',null,this.props.title), 
  5.         React.createElement('input',{ref:'input'}), 
  6.         React.createElement('button',null,'click it.'
  7.     ); 

然后将js代码逆向编译为coffee。

这里我们可以用$代替React.createElement简化代码(终于可以用jQuery的坑位了),得益于coffee的语法,借助React.DOM可以用一种更简单的方式实现:

{div,input,button,span,h1,h2,h3} = React.DOM

这里就不单独放render部分,直接看完整代码:


    
    
  1. {Component,PropTypes} = React = require 'react' 
  2. $ = React.createElement 
  3. {div,input,button} = React.DOM 
  4.  
  5. class App extends Component 
  6.     clickHandle:-> 
  7.         dom = this.refs.input.getDOMNode() 
  8.         this.props.actions.change(dom.value) 
  9.         dom.value = '' 
  10.     render:-> 
  11.         {title,interval} = this.props 
  12.         div className:'timer'
  13.             div null,'定时器:' + interval 
  14.             div null,title 
  15.             input ref:'input' 
  16.             button onClick:@clickHandle.bind(this),'click it.' 
  17.  
  18. App.propTypes = 
  19.     title: PropTypes.string 
  20.     actions: PropTypes.object 
  21.     interval: PropTypes.number 
  22.  
  23. module.exports = App 

如果你能看到并看懂这段coffee,并在大脑里自动编译成js代码再到jsx代码,恭喜你。

连接store

这个环节的作用,主要是实现view层和store层的绑定,当store数据变化时,可自动更新view。

这里需要使用redux提供的createStore方法创建一个store,该方法接受2个参数,reducer和初始的state(应用初始数据)。

store.coffee的代码如下:


    
    
  1. {createStore} = require 'redux' 
  2. reducers = require './reducers' # reducer 
  3. state = require './state' # 应用初始数据 
  4.  
  5. module.exports = createStore reducers,state 

然后我们在应用的入口将store和App绑定,这里使用了redux官方提供的react-redux库。


    
    
  1. {Provider,connect} = require 'react-redux' 
  2. store = require './store' 
  3. $ = React.createElement 
  4. mapState = (state)-> 
  5.     state 
  6. rootComponent = $ Provider,store:store,-> 
  7.     $ connect(mapState)(App) 
  8. React.render rootComponent,document.body 

可能有人会问,mapState和Provider是什么鬼?

mapState提供了一个类似选择器的效果,当一个应用很庞大时,可以选择将state的某一部分数据连接到该组件。我们这里用不着,直接返回state自身。

Provider是一个特殊处理过的react component,官方文档是这样描述的:


    
    
  1. This makes our store instance available to the components below. 
  2. (Internally, this is done via React undocumented “context” feature,  
  3. but it’s not exposed directly in the API so don’t worry about it.) 

所以,放心的用就好了。

connect方法用于连接state和App,之后即可在App组件内部使用this.props.dispatch()方法了。

添加action和reducer

最后我们添加一个按钮点击的事件和定时器,用于触发action,并编写对应的reducer处理数据。

在前面的App内部已经添加了this.props.actions.change(dom.value),这里看下action.coffee的代码:


    
    
  1. module.exports = 
  2.     change:(title)-> 
  3.         type:'change' 
  4.         title: title 
  5.     timer:(interval)-> 
  6.         type:'timer' 
  7.         interval:interval 

再看reducer.coffee


    
    
  1. module.exports = (state,action)-> 
  2.     switch action.type 
  3.         when 'change' 
  4.             Object.assign {},state,title:'hello ' + action.title 
  5.         when 'timer' 
  6.             Object.assign {},state,interval:action.interval 
  7.         else 
  8.             state 

至此,代码写完了。

一些其他的东西

这里只介绍一个中间件的思想,其他的特性例如异步action,或者dispatch一个promise等原理基本类似:


    
    
  1. dispatch = store.dispatch 
  2. store.dispatch = (action)-> 
  3.     console.log action # 打印每一次action 
  4.     dispatch.apply store,arguments 


作者:yisbug

来源:51CTO

相关文章
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
前端大模型入门(三):编码(Tokenizer)和嵌入(Embedding)解析 - llm的输入
本文介绍了大规模语言模型(LLM)中的两个核心概念:Tokenizer和Embedding。Tokenizer将文本转换为模型可处理的数字ID,而Embedding则将这些ID转化为能捕捉语义关系的稠密向量。文章通过具体示例和代码展示了两者的实现方法,帮助读者理解其基本原理和应用场景。
830 1
|
3月前
|
前端开发 JavaScript API
2025年前端框架是该选vue还是react?有了大模型-例如通义灵码辅助编码,就不用纠结了!vue用的多选react,react用的多选vue
本文比较了Vue和React两大前端框架,从状态管理、数据流、依赖注入、组件管理等方面进行了详细对比。当前版本和下载量数据显示React更为流行,但Vue在国内用户量增长迅速。Vue 3通过组合式API提供了更灵活的状态管理和组件逻辑复用,适合中小型项目;React则更适合大型项目和复杂交互逻辑。文章还给出了选型建议,强调了多框架学习的重要性,认为技术问题已不再是选型的关键,熟悉各框架的最佳实践更为重要。
361 0
|
8月前
|
资源调度 前端开发
编译第三方前端项目时候出现Syntax Error: TypeError: Cannot set properties of undefined (setting ‘parent‘)
编译第三方前端项目时候出现Syntax Error: TypeError: Cannot set properties of undefined (setting ‘parent‘)
534 0
|
5月前
|
JavaScript 前端开发 编译器
TypeScript:一场震撼前端开发的效率风暴!颠覆想象,带你领略前所未有的编码传奇!
【8月更文挑战第22天】TypeScript 凭借其强大的静态类型系统和丰富的工具支持,已成为前端开发的优选语言。它通过类型检查帮助开发者早期发现错误,显著提升了代码质量和维护性。例如,定义函数时明确参数类型,能在编译阶段捕获类型不匹配的问题。TypeScript 还提供自动补全功能,加快编码速度。与 Angular、React 和 Vue 等框架的无缝集成进一步提高了开发效率,使 TypeScript 成为现代前端开发中不可或缺的一部分。
53 1
|
5月前
|
资源调度 前端开发 JavaScript
前端 nodejs 命令行自动调用编译 inno setup 的.iss文件
前端 nodejs 命令行自动调用编译 inno setup 的.iss文件
|
5月前
|
前端开发 开发者
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。本文阐述 DefinePlugin 的原理、用法及案例,包括安装配置、具体示例(如动态加载资源、配置接口地址)和注意事项,帮助开发者更好地利用此插件优化项目。
162 0
|
5月前
|
开发框架 前端开发 API
使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理
使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理
|
8月前
|
前端开发 JavaScript 安全
【网络安全/前端XSS防护】一文带你了解HTML的特殊字符转义及编码
【网络安全/前端XSS防护】一文带你了解HTML的特殊字符转义及编码
471 0
|
7月前
|
前端开发 Java Serverless
阿里云云效产品使用问题之前端流水线部署时,在构建环节,编译和打包要分开还是放在一起
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
Rust 前端开发 JavaScript
Rust 编译为 WebAssembly 在前端项目中使用(二)
Rust 编译为 WebAssembly 在前端项目中使用(二)
265 0

热门文章

最新文章