溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在前端編碼時實(shí)現(xiàn)人肉雙向編譯

發(fā)布時間:2021-11-17 10:14:13 來源:億速云 閱讀:146 作者:柒染 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)如何在前端編碼時實(shí)現(xiàn)人肉雙向編譯,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

如何在前端編碼時實(shí)現(xiàn)人肉雙向編譯

React+flux是目前最火的前端解決方案之一,但flux槽點(diǎn)頗多,例如store比較混亂,使用比較繁瑣等,于是出現(xiàn)了很多第三方的基于flux優(yōu)化的架構(gòu)。

如何在前端編碼時實(shí)現(xiàn)人肉雙向編譯

有人統(tǒng)計(jì)了目前主流的flux實(shí)現(xiàn)方案,感興趣的可以看這里:Which Flux implementation should I use?

其中redux是目前githubstar最多的一個方案,該方案完全獨(dú)立于react,意味著這套理念可以作為架構(gòu)層應(yīng)用于其他的組件化方案。同時官方也提供了react-redux庫,幫助開發(fā)者直接使用react+redux快速開發(fā)。

個人理解它的主要特性體現(xiàn)在以下幾點(diǎn):

  1. 強(qiáng)制使用一個全局的store,store只提供了幾個簡單的api(實(shí)際上應(yīng)該是4個),如subscribe/dispatch(訂閱、發(fā)布),getState,replaceReducer

  2. store負(fù)責(zé)維護(hù)一個唯一的叫做state樹的對象,其中state存儲了應(yīng)用需要用到的所有數(shù)據(jù)。

  3. store和頂層組件使用connect方法綁定,并賦給props一個dispatch方法,可以直接在組件內(nèi)部this.props.dispatch(action)。 簡單一點(diǎn)說,就是去掉了flux中組件和storeunbind/bind環(huán)節(jié)。當(dāng)state變化時,自動更新components,不需要手動操作。

  4. 提供了applyMiddleware方法用于異步的action,并且提供了加入中間件的能力,例如打印日志追蹤應(yīng)用的所有狀態(tài)變化。

  5. 對全局的數(shù)據(jù)state的操作,由多個reducer完成。每個reducer都是一個純函數(shù),接收兩個參數(shù)stateaction,返回處理后的state。這點(diǎn)類似管道的操作。

接下來我們可以回答標(biāo)題的問題了,即:如何在前端編碼時實(shí)現(xiàn)人肉雙向編(zi)譯(can)。

其實(shí)就是使用coffee來編寫react+redux應(yīng)用。

我們來寫個簡單的hello world玩玩。

view部分

這部分和redux/flux無關(guān),純粹react的實(shí)現(xiàn),使用jsx的話,render部分的代碼大概長這樣:

render:function(){     return (         <div>             <div class="timer">定時器:{interval}</div>             <div>{title}</div>             <input ref="input"><button>click it.</button>         </div>     ) }

那如何使用coffee寫這段代碼呢? 我們需要先將jsx編譯這類似這樣的js代碼,請注意是用大腦編譯:

render:function(){     return React.createElement('div',null,         React.createElement('div',{className:'timer'},'定時器'+this.props.interval),         React.createElement('div',null,this.props.title),         React.createElement('input',{ref:'input'}),         React.createElement('button',null,'click it.')     ); }

然后將js代碼逆向編譯為coffee。

這里我們可以用$代替React.createElement簡化代碼(終于可以用jQuery的坑位了),得益于coffee的語法,借助React.DOM可以用一種更簡單的方式實(shí)現(xiàn):

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

這里就不單獨(dú)放render部分,直接看完整代碼:

{Component,PropTypes} = React = require 'react' $ = React.createElement {div,input,button} = React.DOM  class App extends Component     clickHandle:->         dom = this.refs.input.getDOMNode()         this.props.actions.change(dom.value)         dom.value = ''     render:->         {title,interval} = this.props         div className:'timer',             div null,'定時器:' + interval             div null,title             input ref:'input'             button onClick:@clickHandle.bind(this),'click it.'  App.propTypes =     title: PropTypes.string     actions: PropTypes.object     interval: PropTypes.number  module.exports = App

如果你能看到并看懂這段coffee,并在大腦里自動編譯成js代碼再到j(luò)sx代碼,恭喜你。

連接store

這個環(huán)節(jié)的作用,主要是實(shí)現(xiàn)view層和store層的綁定,當(dāng)store數(shù)據(jù)變化時,可自動更新view。

這里需要使用redux提供的createStore方法創(chuàng)建一個store,該方法接受2個參數(shù),reducer和初始的state(應(yīng)用初始數(shù)據(jù))。

store.coffee的代碼如下:

{createStore} = require 'redux' reducers = require './reducers' # reducer state = require './state' # 應(yīng)用初始數(shù)據(jù)  module.exports = createStore reducers,state

然后我們在應(yīng)用的入口將store和App綁定,這里使用了redux官方提供的react-redux庫。

{Provider,connect} = require 'react-redux' store = require './store' $ = React.createElement mapState = (state)->     state rootComponent = $ Provider,store:store,->     $ connect(mapState)(App) React.render rootComponent,document.body

可能有人會問,mapState和Provider是什么鬼?

mapState提供了一個類似選擇器的效果,當(dāng)一個應(yīng)用很龐大時,可以選擇將state的某一部分?jǐn)?shù)據(jù)連接到該組件。我們這里用不著,直接返回state自身。

Provider是一個特殊處理過的react component,官方文檔是這樣描述的:

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

所以,放心的用就好了。

connect方法用于連接state和App,之后即可在App組件內(nèi)部使用this.props.dispatch()方法了。

添加action和reducer

***我們添加一個按鈕點(diǎn)擊的事件和定時器,用于觸發(fā)action,并編寫對應(yīng)的reducer處理數(shù)據(jù)。

在前面的App內(nèi)部已經(jīng)添加了this.props.actions.change(dom.value),這里看下action.coffee的代碼:

module.exports =     change:(title)->         type:'change'         title: title     timer:(interval)->         type:'timer'         interval:interval

再看reducer.coffee

module.exports = (state,action)->     switch action.type         when 'change'             Object.assign {},state,title:'hello ' + action.title         when 'timer'             Object.assign {},state,interval:action.interval         else             state

至此,代碼寫完了。

一些其他的東西

這里只介紹一個中間件的思想,其他的特性例如異步action,或者dispatch一個promise等原理基本類似:

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

由于時間關(guān)系,redux的一些特性和設(shè)計(jì)原理沒有展現(xiàn)出來,以后有時間再單獨(dú)講,完整的項(xiàng)目代碼,感興趣的同學(xué)可以看這里:請點(diǎn)我,或者直接找我聊。

項(xiàng)目用到了fis3作為構(gòu)建工具,使用fis3 release即可在本地查看效果。

關(guān)于如何在前端編碼時實(shí)現(xiàn)人肉雙向編譯就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI