摘要:明明如日中天,把它與倒過來,給加點(diǎn)東西或可與抗衡。在之后,大版本有十?dāng)?shù)個(gè),只有最近推的才回歸正常等后人總結(jié)歷史,無疑會把與之間的所有都稱為垃圾。讓網(wǎng)頁支持所見即得的可視化設(shè)計(jì),是框架的最高形態(tài),以前沒有類似工具,主要因?yàn)榧夹g(shù)做不到。
好吧,我承認(rèn)我是標(biāo)題黨。React 明明如日中天,把它與 Vue 倒過來,給 Vue 加點(diǎn)東西或可與 React 抗衡。不過,這兩年 Vue 干的正是這事,不斷加?xùn)|西,不斷優(yōu)化,按它現(xiàn)有發(fā)展速度超越 React 或在情理之中。如果我有一項(xiàng)技術(shù),能讓 React 克服短板、維持長板,Vue 再怎么追都趕不上呢?
這項(xiàng)技術(shù)就是 Shadow Widget,開源的,入口在這里(github/rewgt)。
?
1. 若無來處便剩歸途前些天讀過一篇文章,某專家推薦新手入門人工智能最便捷的途徑,不是仿 AlphaGo 開發(fā)個(gè)程序,而是找到十年前、二十年前人工智能領(lǐng)域關(guān)鍵的幾篇論文,把經(jīng)典文章吃透,然后再去編程。知道了每項(xiàng)技術(shù)怎么來的,解決了什么問題,又引發(fā)了什么新問題,把一步步演化過程梳理清楚,就能更清晰的把握下一步工作重點(diǎn)與發(fā)展方向。
反推一下 Windows 的來處吧,從 Win3.1、3.2,Win95、98、NT 等,一路疊代到現(xiàn)在的 Window10,如果你是比爾.蓋茲,會不會覺得砍掉一半版本 Windows 將發(fā)展更好?尤其近十年推出那么多殘次品,在 XP 之后,只有 Win7 與 Win10 產(chǎn)生市場價(jià)值。這家公司純粹為推產(chǎn)品而推產(chǎn)品,忘記為什么做產(chǎn)品了,在 IE 產(chǎn)品線這點(diǎn)表現(xiàn)更明顯。
在 IE6 之后,大版本有十?dāng)?shù)個(gè),只有最近推的 Edge 才回歸正常(等后人總結(jié)歷史,無疑會把 IE6 與 Edge 之間的所有 IE 都稱為垃圾)。對前端開發(fā)人員而言,他面對的瀏覽器就兩類,一類叫 IE,另一類叫其它,MS 自擼了這么多年,才忽然發(fā)現(xiàn)跟他身后一起擼的小弟一個(gè)都沒了,整整齊齊排到另一條隊(duì)列,而且合伙把自己落下老遠(yuǎn)。于是收起老大心態(tài),老老實(shí)實(shí)做一款“不隔路”的,叫 Edge 的產(chǎn)品。IE 產(chǎn)品團(tuán)隊(duì)未必全都低能,但產(chǎn)品經(jīng)理絕對例外,從根子上他就沒想明白開發(fā)這款產(chǎn)品給誰用,怎么用,沒了初心,就剩末路了,當(dāng)所有前端開者都心生厭惡乃至鄙視時(shí),再強(qiáng)勢的市場地位也是白搭。
那么,現(xiàn)在前端開發(fā)的初心是什么?是由 DOM 描述器疊加 JS 控制嗎?顯然不是,早期的網(wǎng)頁很簡單,前端開發(fā)的任務(wù)也很純粹,用 "html + CSS" 描述界面節(jié)點(diǎn),再用 JS 搞點(diǎn)交互控制,就夠用了?,F(xiàn)在情況有變,前端開發(fā)應(yīng)歸類到完整的、具備完全能力的 GUI 開發(fā)。上世紀(jì)末,我們只把類似 Delphi、MFC、WxWidget 之類的開發(fā)稱為界面開發(fā),前端實(shí)施的是網(wǎng)頁開發(fā)(相關(guān)工具并不叫作 GUI 工具),網(wǎng)頁能力與常規(guī) GUI 差出一大截,為了彌補(bǔ)能力缺失,于是有出各種插件技術(shù)發(fā)展出來,比如借助 java、ActionScript 工具等補(bǔ)上短板。現(xiàn)在,有了 HTML5、CSS3,不借助插件的網(wǎng)頁表現(xiàn)力與平臺原生的 GUI 差距不大了,網(wǎng)站開發(fā)更適合看作 GUI 開發(fā),加上移動端設(shè)備興起,java 與 ActionScript 不再有效,尤其出現(xiàn) Angular、React、Vue 等新興框架后,大型、復(fù)雜的前端開發(fā)也能輕松應(yīng)對了,“網(wǎng)頁開發(fā)” 應(yīng)回歸到常規(guī)的 “GUI 開發(fā)” 主線上來。GUI 開發(fā)更初始,更反映本質(zhì)需求,瀏覽器出現(xiàn)之前已廣泛存在。
2. 網(wǎng)頁可視化開發(fā)趨勢我用 Delphi 做開發(fā)早于用 MFC,Delphi 1.1 剛推出就開始用了,當(dāng)時(shí) MFC 代表了先進(jìn)生產(chǎn)力,當(dāng)我熟悉 Delphi 后,改用 MFC 感覺異常痛苦。之后 20 年里我還用過 VB、WxWidget、PythonTk、Qt、C#、XCode 等 GUI 開發(fā)工具,整體觀感是:Delphi 確立的開發(fā)方式仍是最佳,盡管 Delphi 日漸式微,以至現(xiàn)在很少有人提到它了。但那套 RAD (Rapid Application Develop) 開發(fā)模式并未過時(shí),一些新興工具,如 XCode,仍繼承它的做法。
拿 MFC 與 Delphi 對比前端開發(fā)工具,像 MFC 的有一堆,凡沒支持所見即所得可視化設(shè)計(jì)的,像 Angular、Vue 等都應(yīng)歸入此類,像 Delphi 的幾乎沒有,該補(bǔ)課了,Shadow Widget 是例外,但 Shadow Widget 新近推出,應(yīng)用效果有待檢驗(yàn)。
通用的可視化設(shè)計(jì),在前端開發(fā)中那么難出現(xiàn),我猜主要有兩點(diǎn)原因:
為網(wǎng)頁提供可視化設(shè)計(jì)的難度高于傳統(tǒng) GUI 工具,如 Delpphi、Qt、XCode 等
傳統(tǒng) GUI 工具只需為有限元素提供可視化設(shè)計(jì)封裝,網(wǎng)頁的可視化則不同,它面對各種標(biāo)簽,量大而且富于變化,增加控制屬性很隨意,擴(kuò)展也隨意,使用大量自定義標(biāo)簽是現(xiàn)代框架的重要設(shè)計(jì)手段。標(biāo)簽化描述類似于命令行,把海量命令行轉(zhuǎn)為可視化設(shè)計(jì)并不容易。
受限于網(wǎng)頁技術(shù)發(fā)展水平
在 Html5 與 Css3 出現(xiàn)之前,原生網(wǎng)頁的表現(xiàn)力很有限,相比 Qt 所能實(shí)現(xiàn) GUI 效果,相差了一大截。Html5 與 Css3 補(bǔ)上這個(gè)短板后,javascript 不適合模塊化、工程化、規(guī)?;_發(fā)的短板突顯出來,于是業(yè)界有 ES6、ES7、Babel 等新生事物冒出,借助 nodeJS 整合工具鏈,這個(gè)進(jìn)程現(xiàn)已完成,盡管還留點(diǎn)缺陷。同時(shí),Angular、React、Vue 等框架也在新興的前端技術(shù)條件下,不斷嘗試最優(yōu)開發(fā)方法,主流框架還都在快速疊代、演化中,MVC、MVVM、FRP 等方法不斷推陳出新,最優(yōu)的、達(dá)成共識的開發(fā)方法尚未形成。
總之,網(wǎng)頁開發(fā)正從當(dāng)前的陳述方式(書寫 HTML 的 tag 標(biāo)簽,或使用 JSX 定義界面),逐步走向 陳述與可視化并重 的方式。Shadow Widget 順應(yīng)了這個(gè)趨勢,時(shí)機(jī)正好,若過早發(fā)展,估計(jì)會像 QML 那樣淪為無名,當(dāng) JS 語言與框架還在快速變化中,嘗試規(guī)范并簡化界面的表達(dá)形式是徒勞的。
盡管 React 核心庫只在虛擬 DOM 層面提供方案,但它強(qiáng)烈的函數(shù)式風(fēng)格,影響了其工具鏈上各工具的方向性選擇,都對標(biāo)到函數(shù)式開發(fā)上來了。這也導(dǎo)致 React 工具的易用性要比 Vue 差出不少,Vue 基于 MVVM 框架,很契合可視形態(tài)(也就是頁面跑起來的樣子)的界面開發(fā)方式。另外,當(dāng) Vue 也引入虛擬 DOM、store、action 等機(jī)制后,React 引以為傲的功能 Vue 里慢慢都會有,Vue 趕超 React 似乎指日可待。
上述提法,基于我對前端開發(fā)場景的一個(gè)認(rèn)知:趨向靜態(tài)的 MVVM 優(yōu)于趨向動態(tài)的 FRP 架構(gòu),當(dāng)然,F(xiàn)RP 自有優(yōu)勢,如果二選一,寧選 MVVM,如果兩者均可選,也應(yīng)以 MVVM 為主,F(xiàn)RP 為輔,至少整體設(shè)計(jì)時(shí)如此(兩者實(shí)際上處于不同層次,為主、為輔是相對的,下文還有介紹)。
讓網(wǎng)頁支持所見即得的可視化設(shè)計(jì),是 MVVM 框架的最高形態(tài),以前沒有類似工具,主要因?yàn)榧夹g(shù)做不到。Shadow Widget 在設(shè)計(jì)之初就著手解決可視化設(shè)計(jì)的問題,立足點(diǎn)高于 Vue,這種優(yōu)勢正如 Vue 比 React 晚推出,可以大量借鑒 React 一樣,Shadow Widget 也晚推出,可以吸取 Vue 優(yōu)點(diǎn)。不同的是,支持可視化需在頂層做設(shè)計(jì),改造已定形的 MVVM 框架來支持可視化并不容易。
3. 回歸本原之一:jQuery 用得爽如何繼續(xù)爽下去?考慮一種應(yīng)用場景,用戶要開發(fā)一個(gè)網(wǎng)頁,主體是展示一些文字與圖片,也有少量交互控制的內(nèi)容,比如輸入反饋信息后點(diǎn) “提交” 按鈕。如果用 jQuery 開發(fā),代碼不足百行,如果用 React 會很麻煩,工具鏈很繁重,遠(yuǎn)沒有用 jQuery 那么簡單直接,或干脆什么庫都不用,什么框架都不用,裸寫 JS 都簡化很多。
現(xiàn)實(shí)開發(fā)中,此類場景經(jīng)常遇到,產(chǎn)品開發(fā)并不總在處理復(fù)雜頁面的。雖說裸寫 JS 能減少麻煩,但經(jīng)常不受控,有時(shí)與別人對接或合入別人的代碼,別人用了 React,你不得不被同化;有時(shí)開始時(shí)簡單,后來需求變了,網(wǎng)頁越做越復(fù)雜,你不得不往框架遷移;還有時(shí),為方便項(xiàng)目統(tǒng)一維護(hù),上頭要求所有 JS 都往 React 里塞。
Shadow Widget 強(qiáng)調(diào)實(shí)用重于形式,它推薦的開發(fā)方式是:能用 ES5 編程盡量用 ES5,用 標(biāo)簽把 react 與 shadow-widget 庫導(dǎo)入進(jìn)來后,在網(wǎng)頁文件中直接寫 JS 腳本就能做開發(fā)。這就像以往 jQuery 編程那樣,用 導(dǎo)入庫,然后直接用 ES5 編碼。
如果按 React 官方推薦的方式,定義一個(gè) Component 類樣式如下:
class RedFlower extends React.Component { constructor(props) { // ... } componentDidMount() { // ... } render() { // ... } }
如果這么開啟編程之旅,你就被 React 工具鏈綁架了,小紅帽套上,你不要也得要。
Shadow Widget 內(nèi)部一律改用 React.createClass() 引入 Component 行為定義,因?yàn)橹苯又С?ES5 規(guī)格的代碼,不必經(jīng) Babel 轉(zhuǎn)譯,這看上去很土,卻很實(shí)用。例如:
main[".body.top.p.tool"] = { getDefaultProps: function() { var props = T.Button.getDefaultProps(); // props.attr = value; return props; }, getInitialState: function() { var state = this._getInitialState(this); // ... return state; }, $onClick: function(event) { alert("clicked"); }, };
不過 Shadow Widget 不排斥用 ES6 編程,自定義一個(gè) Component 類可以用 ES6+ 語法,只需從已有的,符合 Shadow Widget 規(guī)格的 Component 類開始繼承,不能從 React.Component 繼承,例如:
class MyButton_ extends T.Button_ { constructor(name,desc) { super(name,desc); } getDefaultProps() { var props = super.getDefaultProps(); // props.attr = value; return props; } getInitialState() { var state = super.getInitialState(); // ... return state; } $onClick: function(event) { alert("clicked"); } } // convert to React class var AbstractButton = new MyButton_(); var MyButton = AbstractButton._createClass({}); var jsx =test ; var MyButton2 = AbstractButton._createClass( { $onClick: function(event) { alert("another onClick"); } }); var jsx2 =test2 ;
注意到了嗎?上面代碼沒有直接定義 React class,而是加了一層抽象,AbstractButton 是類的類,用 AbstractButton._createClass() 才實(shí)例化成 React class。這么設(shè)計(jì),一方面讓 Component 定義正常使用類繼承,另一方面讓 Component 的界面表現(xiàn)能有選擇的與行為定義分離,這是在線支持可視化設(shè)計(jì)的基礎(chǔ)。
4. 回歸本原之二:不要一上來就讓我陷入抽象!撇開網(wǎng)頁設(shè)計(jì)的專有屬性,任何產(chǎn)品開發(fā)都要求設(shè)計(jì)者先考慮用戶怎么操作,UI 可視化設(shè)計(jì)過程,也就是定義用戶需求,并把需求往各層設(shè)計(jì)分解的過程。所以,界面設(shè)計(jì)是承上啟下的,它應(yīng)在編碼之前進(jìn)行,而不是與編碼混雜同步進(jìn)行,也不是先寫底層代碼,被動的跟隨變化。對于網(wǎng)頁產(chǎn)品更如此,只要不拿網(wǎng)頁開發(fā)命令行程序,網(wǎng)頁就是用戶交互操作最直接的媒介。
React 的 JSX 設(shè)計(jì)方式讓 GUI 設(shè)計(jì)混合于編碼之中,未保證界面設(shè)計(jì)的第一性,其主流的 Flux 工具,均強(qiáng)化了數(shù)據(jù)傳遞如何設(shè)計(jì),讓開發(fā)者一上來就思考 action 與 store 怎么設(shè)計(jì),而非界面該如何表現(xiàn)。react-route 更為極端,它鼓勵(lì)大家第一步就思考路由,并以此為提綱展開各項(xiàng)設(shè)計(jì),很不人性。Shadow Widget 第一步就要求考慮界面如何表現(xiàn),而且只在 UI 設(shè)計(jì)想清楚后再做別的,然后第二步、第三步才考慮數(shù)據(jù)如何流動、路由如何規(guī)劃等,讓 “網(wǎng)頁開發(fā)” 回歸常規(guī) GUI 開發(fā),這才是正確的姿勢。
Vue 易用性勝過 React,很大程度上是因?yàn)?MVVM 中的 component 定義與界面表現(xiàn)一一對應(yīng),思考很直接。Shadow Widget 則在 MVVM 基礎(chǔ)上增強(qiáng)了即時(shí)可視化能力,以所見即所得的方式讓每次閉環(huán)疊代的周期縮短,從而讓開發(fā)更加敏捷。
拿具體例子解釋上面意思,比方設(shè)計(jì)一個(gè)播放器,有兩種思考方式,第一種,先理清界面交互方式,是否為了區(qū)分連接播放與只播放單個(gè)音頻,在界面設(shè)計(jì)兩個(gè)播放按鈕,還是共用一個(gè)按鈕(但另加 “是否連續(xù)播放” 選項(xiàng)框)?要不要提供暫停按鈕?暫停按鈕是否與播放按鈕并合?第二種思考方式,先確定用到哪些數(shù)據(jù),數(shù)據(jù)又由哪些 action 驅(qū)動,比如要有播放器與播放列表,要定義一個(gè)狀態(tài)屬性表示暫?;虿シ胖?,驅(qū)動它變更的 action 有 play, pause, stop 等,還要有一個(gè) “是否連續(xù)播放” 屬性,與播放列表一起作為 payload 附在 play action 上傳遞,播放列表還有增刪改 action,等等。
雖然這兩種思考方式都能達(dá)到目的,但從嚴(yán)格意義上講,選擇哪一種是工作方法對錯(cuò)的問題,而不是個(gè)人風(fēng)格喜好的問題。第二種思考方式錯(cuò)誤在于,“容易偏離需求” 與 “喪失需求分解層次感”,至于 “設(shè)計(jì)過程欠直觀” 還是次要的、附帶的。容易偏離需求,比如你為手表設(shè)計(jì)播放器,增加的 “是否連續(xù)播放” 選項(xiàng)在界面擺不下,若采用第二種思考方式你很容易忽略這個(gè)限制。另外,設(shè)計(jì)過程是有層次的,自頂向下,由粗入細(xì),需求在各層設(shè)計(jì)逐步分解,上一層操作方式變化會影響下一層如何設(shè)計(jì),如果以數(shù)據(jù)與 action 為思考出發(fā)點(diǎn),很容易喪失設(shè)計(jì)層次感,沒有前置思考界面如何交互,上層如何表現(xiàn)對下層設(shè)計(jì)的影響也容易被延后思考,甚至扭曲了。
5. 引入 MVVM 并與 Flux 框架協(xié)作共存支持可視化設(shè)計(jì)的第一步,分離 Component 的界面表現(xiàn)與它的行為定義,即,在設(shè)計(jì)態(tài)我們在可視設(shè)計(jì)器中只展示各 Componet 的可視特征,而不捆綁它的行為定義(比如 onClick 事件處理),當(dāng)產(chǎn)品正式運(yùn)行時(shí),即,非設(shè)計(jì)態(tài),各 Component 的行為定義將在初始化時(shí)正常捆綁。Shadow Widget 可視設(shè)計(jì)的輸出是 “轉(zhuǎn)義標(biāo)簽”,保存在當(dāng)前 *.html 文件中,行為定義則記錄在 js 文件,這兩者類似于 Delphi 的 *.frm 界面定義文件與 *.pas 代碼實(shí)現(xiàn)文件。
可視化設(shè)計(jì)第二步,引入 MVVM 架構(gòu)。
Shadow Widget 內(nèi)部采用 Object.defineProperty() 定義雙源屬性,使得類似 comp.duals.attr = value 的賦值語句能自動觸發(fā)預(yù)設(shè)的 setter 函數(shù)。之后再對雙源屬性增加偵聽機(jī)制,凡被 listen 的 duals.attr,其值變化會按事件方式被訂閱,進(jìn)而構(gòu)造聯(lián)動觸發(fā)機(jī)制。
雙源屬性解決了類似 Vue 中數(shù)據(jù)雙向綁定的需求,ViewModel 建立在數(shù)據(jù)流自動傳遞基礎(chǔ)上,Shadow Widget 為此還增加 $if, $elif, $else, $for 等控制指令,讓界面能按特定規(guī)則由數(shù)據(jù)驅(qū)動自動生成,再有 trigger 機(jī)制、可計(jì)算屬性、棧式調(diào)用空間等設(shè)計(jì),讓數(shù)據(jù)傳遞、組裝、條件控制等變得靈活、強(qiáng)大??傊?,Shadow Widget 的 MVVM 機(jī)制與 Vue 基本類似,限于篇幅本文不展開介紹。
支持可視化設(shè)計(jì)第三步,讓 MVVM 架構(gòu)與 Flux 單向數(shù)據(jù)流協(xié)同工作。
這里只扼要解釋,以后還會專門寫文章介紹。在 Shadow Widget 中,各 Component 若未按編程方式參與行為定制(專指在 main[sPath] 定義投影類,或用 idSetter[sId] 實(shí)現(xiàn)定義),就視作 View 節(jié)點(diǎn),凡參與定制的 Component 視作 ViewModel,各 ViewModel 節(jié)點(diǎn)使用的 props.attr 與 duals.attr 屬于 Model。這是一種通過擴(kuò)展虛擬 DOM 節(jié)點(diǎn)的能力而實(shí)現(xiàn)的機(jī)制,并不直接干擾 Flux 單向數(shù)據(jù)流機(jī)制,有影響的是,我們要采用多 Store 而非單 Store 機(jī)制,另外還要把 Component 節(jié)點(diǎn)復(fù)用為 Store 節(jié)點(diǎn),用雙源屬性支持 action 分發(fā)(dispatch)與觸發(fā)(trigger)。
可視化設(shè)計(jì)與 MVVM 架構(gòu)密不可分,React 技術(shù)棧與 Flux 機(jī)制密不可分,它的 Functional React Programming 理念與可視化編程可以兼容,MVVM 主導(dǎo)上層些、粗粒度的設(shè)計(jì),細(xì)粒度與橫向聯(lián)系由 FRP 主導(dǎo)。兩者交匯點(diǎn)就是參與行為定制的、可視的 Component 節(jié)點(diǎn),也就是 ViewModel 節(jié)點(diǎn)。雙源屬性同時(shí)支撐 MVVM 框架與 FRP 框架,兩種框架分別主管 “縱向嵌套定義界面” 與 “橫向消息聯(lián)系”,處理過程非常自然。
6. 工程化開發(fā)的必然需求:技術(shù)分層與人員分工各個(gè)主流前端框架都使用 NodeJS 集結(jié)工具鏈,它們都考慮了規(guī)范化、工程化開發(fā)的需求,都用 NPM 包管理各層庫的依賴關(guān)系,但它們普遍沒為技術(shù)分層帶來的人員分工,在框架層面提供有效支持。
無論 Angular,React,還是 Vue,都是重框架,輕不起來,快速入門不能算輕,要以真正能開發(fā)產(chǎn)品、獨(dú)立解決問題為準(zhǔn),學(xué)透這些框架都要花不少時(shí)間?;叵胧昵?,前端開發(fā)是一個(gè)實(shí)習(xí)生簡單翻翻參考書就能做的,現(xiàn)在要有一年以上經(jīng)驗(yàn)才算入門,而且,不同素質(zhì)的人產(chǎn)出代碼的質(zhì)量相差很遠(yuǎn)。前端開發(fā)該對人員分層管理了,這是既是工程化開發(fā)的需求,也是產(chǎn)品開發(fā)趨于復(fù)雜化必然提出的要求。
Shadow Widget 所構(gòu)筑的技術(shù)體系,將前端開發(fā)劃分為兩大部分:構(gòu)件(Widget)開發(fā)與界面(GUI)開發(fā)。前者要求分發(fā)者具備完整技能,后者則只需簡單技能,即:會用 html、css、javascript,掌握 react 入門知識,借助界面可視化設(shè)計(jì)器很快就能勝任工作。也就是說,我們預(yù)想前端開發(fā)人員至少可分兩類,一類是入門級的,實(shí)習(xí)生水準(zhǔn),他主要工作是拿別人已開發(fā)好的構(gòu)件搭積木,另一類是高級工程師,他為前一類開發(fā)者開發(fā)構(gòu)件。
相信所有老板都喜歡這么分工,能省錢!專業(yè)化分工后,整體開發(fā)效率與質(zhì)量都會提升。
(本文完)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83385.html
摘要:本篇解釋中類的控制指令,與指令式界面設(shè)計(jì)相關(guān)。本專欄歷史文章介紹一項(xiàng)讓可以與抗衡的技術(shù)可視化開發(fā)工具非正經(jīng)入門之一三宗罪可視化開發(fā)工具非正經(jīng)入門之二分離界面設(shè)計(jì)可視化開發(fā)工具非正經(jīng)入門之三雙源屬性與數(shù)據(jù)驅(qū)動可視化開發(fā)工具非正經(jīng)入門之四 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計(jì)要點(diǎn)。本篇解釋 Shadow Widget 中類 Vue 的控制指令,與指令式界面...
摘要:前言非正經(jīng)入門是相對正經(jīng)入門而言的。不過不要緊,正式學(xué)習(xí)仍需回到正經(jīng)入門的方式??焖偃腴T建議先學(xué)會用拼文寫文檔注冊一個(gè)賬號,把庫到自己名下,然后用這個(gè)庫寫自己的博客,參見這份介紹。會用拼文寫文章,相當(dāng)于開發(fā)已入門三分之一了。 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計(jì)要點(diǎn),既作為用戶手冊的補(bǔ)充,也從更本質(zhì)角度幫助大家理解 Shadow Widget 為什么這...
閱讀 2933·2021-11-23 09:51
閱讀 1587·2021-11-15 11:36
閱讀 3047·2021-10-13 09:40
閱讀 2022·2021-09-28 09:35
閱讀 13172·2021-09-22 15:00
閱讀 1398·2019-08-29 13:56
閱讀 2955·2019-08-29 13:04
閱讀 2725·2019-08-28 18:06