成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React 可視化開發(fā)工具 Shadow Widget 非正經(jīng)入門(之二:分離界面設(shè)計)

Carl / 1553人閱讀

摘要:本篇講解轉(zhuǎn)義標(biāo)簽投影定義,這幾項與如何分離界面設(shè)計有關(guān)。找一個替代品如上一篇非正經(jīng)入門之一所述,要克服漿糊的不利影響,要找一個替代品。本文完本專欄歷史文章介紹一項讓可以與抗衡的技術(shù)可視化開發(fā)工具非正經(jīng)入門之一三宗罪

本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計要點。本篇講解轉(zhuǎn)義標(biāo)簽、json-x、投影定義,這幾項與 "如何分離界面設(shè)計" 有關(guān)。

?

1. 找一個 JSX 替代品

如上一篇 "非正經(jīng)入門(之一)" 所述,Shadow Widget 要克服 "JSX漿糊" 的不利影響,要找一個 JSX 替代品。

比如下面 JSX 表達方式:

  return 

Dear {user.name}, {welcomeMsg(user)}

;

等效于:

  return React.createElement( H1, {id:user.id},
    "Dear ", user.name, ", ", welcomeMsg(user)
  );

創(chuàng)建一個 Element,需傳遞三項信息:ReactClassprops,children 列表。我們把這三項改造成一個 array 數(shù)組格式:

  [ [ReactClass, props],
    child1, child2...
  ]

其中,child1, child2 是子節(jié)點定義,格式是 string 字串,或 array 數(shù)組。這種以 array 數(shù)組表達一個 Element 節(jié)點的格式叫 json-x 描述方式,與 JSX 完全等效。

2. 轉(zhuǎn)義標(biāo)簽

為了方便在 html 網(wǎng)頁文件中描述用戶界面,我們定義 "轉(zhuǎn)義標(biāo)簽" 的表達方式,如下:

  
Referece: example.com

轉(zhuǎn)義標(biāo)簽無非將所有 HTML 標(biāo)簽劃分為行內(nèi)標(biāo)簽與 block 標(biāo)簽,前者用 表達,后者用

表達,各標(biāo)簽中用 $=XXX 屬性定義的方式指示實際使用哪個 React Class,如 $=Panel 表示用 T.Panel,$=P 表示用 T.P。所有經(jīng) Shadow Widget 擴展出的構(gòu)件模板類(也稱 WTC,Widget Template Class)都應(yīng)注冊到 T 之下,這樣,網(wǎng)頁剛打開時,由轉(zhuǎn)義標(biāo)簽中 $=XXX 指示,能找到相應(yīng)的 React class,實現(xiàn)正常掛載。

在轉(zhuǎn)義標(biāo)簽中定義的屬性,比如上面的 src="http://example.com",在掛載前先整理出 props 表(如 {src:"http://example.com"}),而轉(zhuǎn)義標(biāo)簽的上下級節(jié)點的從屬關(guān)系,以及同級節(jié)點之間的前后關(guān)系,指明了 json-x 數(shù)據(jù)中的 children 定義。所以,ReactClass,props,children 三項信息都有了,轉(zhuǎn)義標(biāo)簽?zāi)苻D(zhuǎn)換成 json-x,所以它與 JSX 也是等效的。

轉(zhuǎn)義標(biāo)簽具有良好可讀性,所以,它在 *.html 文件中可以直接書寫。另外,這種格式對搜索引擎也友好,若依賴 JSX 定義界面,搜索引擎無法分析 html 文件中定義了什么信息。

3. 第一眼是妖孽,多半就是妖孽

React 支持服務(wù)側(cè)渲染,這個特性似乎鼓勵了其生態(tài)鏈上若干工具額外拓展服務(wù)側(cè)功能。比如 react-router 中 Router 組件的 history 屬性,既可以是 browserHistory,也可以是 hashHistory。對于前者,客戶側(cè)路由(即 URL 路徑)決定服務(wù)側(cè)如何實現(xiàn),將兩側(cè)的設(shè)計捆綁起來的,后者 hashHistory(即 #/some/path)完全在客戶側(cè)自主決定,與服務(wù)側(cè)無關(guān)。很顯然,后一方式優(yōu)于前者,前者違背了軟件設(shè)計的 "關(guān)注點分離"(Separation of concerns, SOC)原則,并且在實踐上,服務(wù)側(cè)只有用 webpack-dev-server (加 --history-api-fallback 參數(shù))才能玩得好,不只綁架用 JS 語言,而且綁架用特定工具。要命的是,react-router 官方居然推薦大家首選 browserHistory。

這個 browserHistory 就是充滿妖氣的特性,怪里怪氣,表面看起來有用,實則禁不起推敲。React 的 propTypes 也很妖,官方讓它存活了這么久,最終決定在 v15.5 之后棄用,連 context 也不建議用了,context 本是 React 為緩解跨節(jié)點數(shù)據(jù)共享不便,弄出的不倫不類的東西。

某種程度上 React 的服務(wù)側(cè)渲染也多少沾點 "妖氣",有些人僅為了解決 SEO 優(yōu)化用它,仔細想想有點本末倒置了。它的初始需求源于 google 之類的搜索引擎不認 JSX,因為 JSX 服務(wù)于編程,編程腳本原不該由搜索引擎關(guān)注的,該關(guān)注的只是一些靜態(tài)文本。處理靜態(tài)文本沒必要拉上 React 一家子吧?但事實卻是,我們非得套用一個客戶側(cè)編程風(fēng)格,用 JS 開發(fā)的服務(wù)側(cè)渲染工具,你說妖不妖?

4. 分離界面設(shè)計

在分離界面之前,我們還需建立路徑索引機制。

Shadow Widget 通過一顆樹(Widget 樹,R 樹)管理由它定義的界面,各節(jié)點都有 key 值作標(biāo)識,既可以顯示指定一個 key 值,也可以缺省,缺省時由系統(tǒng)自動生成一個數(shù)字來表示。這果顆樹的根節(jié)點是 ".body",如果根節(jié)點下有一個 key 值為 "toolbar" 的 Panel 節(jié)點,它的絕對路徑就是 ".body.toolbar"。

有了路徑索引機制,我們能將界面描述與它的行為定義分離開了。比如這么定義界面:

Test

這么定義 Test 按鈕的行為:

main[".body.toolbar.p.btn1"] = {
  $onClick: function(event) {
    alert("clicked");
  },
};

界面的轉(zhuǎn)義標(biāo)簽在 *.html 文件中書寫,界面元素的行為定義在 *.js 文件進行,如此,界面設(shè)計分離出來了,界面描述與相關(guān)元素的行為定義通過該元素的絕對路徑實現(xiàn)關(guān)聯(lián)。如上例,用 javascript 編寫某元素的行為定義,也稱 "投影定義"。

5. 表達復(fù)雜的 props 數(shù)據(jù)

json-x 數(shù)據(jù)與轉(zhuǎn)義標(biāo)簽都與 JSX 對等,但傳遞 props 數(shù)據(jù)有若干限制,比如轉(zhuǎn)義標(biāo)簽不支持傳遞函數(shù)對象,json-x 可傳函數(shù)對象,但也不鼓勵(主要因為不規(guī)范)。函數(shù)定義應(yīng)在投影類中定義,就像上面舉例的 $onClick 函數(shù),不通過轉(zhuǎn)義標(biāo)簽的屬性來傳遞,只在轉(zhuǎn)義標(biāo)簽掛載時,到 main 下找到相應(yīng)投影定義,然后捆綁相應(yīng)的函數(shù)定義。

除了函數(shù),描述復(fù)雜的 props 數(shù)據(jù)時,json-x 的表達能力是完整的,因為它本來就是 javascript 數(shù)據(jù),但轉(zhuǎn)義標(biāo)簽受 html 標(biāo)簽格式的影響,要改用 JSON 字串來表示,比如:

  

屬性值用 "{""}" 括起來,表示它是 JSON 字串,用 JSON.parse 前要先刪掉首尾兩個花括號,如上面 width 值為 JSON.parse("400")。另外,對于 string 類型的屬性值,可以直接傳遞(避開字串首尾是花括號的情形),不必按 JSON 字串的方式,如上面 title 屬性。

6. idSetter 函數(shù)

實施界面與底層分離除了投影定義,還有一種指定 idSetter 函數(shù)的方式,若簡單去理解,該方式是投影定義的一個變種,同樣實現(xiàn)特定界面元素的行為定義的動態(tài)綁捆。

舉例來說,界面這么描述:

Test

Javascript 這么定義:

idSetter["btn1"] = function(value,oldValue) {
  if (value <= 2) {
    if (value == 1) {      // init process
      this.setEvent( {
        $onClick: function(event) {
          alert("clicked");
        },
      });
      // ...
    }
    else if (value == 2) { // did mount
      // ...
    }
    else if (value == 0) { // will unmount
      // ...
    }
    return;
  }

  // render process ...
};

這種書寫方式與上面投影定義的方式是等效的,投影類中該在 getInitialState() 中書寫的代碼,要挪到 idSetter 函數(shù)的 if (value == 1) 分支中,該在 componentDidMount() 中書寫的代碼移到 if (value == 2) 的分支中,該在 componentWillUnmount() 中書寫的代碼移到 if (value == 0) 的分支中。

使用 idSetter 函數(shù)的優(yōu)點是,相應(yīng)界面節(jié)點的絕對路徑不必完整定義,即路徑上各段不必顯式給出 key 值,系統(tǒng)由 $id__="xxx" 屬性值,自動找出 idSetter 函數(shù)。另一個優(yōu)點是,編程風(fēng)格更加函數(shù)式。

7. 建立 W 樹供隨時節(jié)點定位

Flux 框架要求節(jié)點間數(shù)據(jù)流向要遵守嚴(yán)格的約束,React 不惜犧牲編程便利性,刻意隱藏了內(nèi)建的那顆虛擬 DOM 樹,導(dǎo)致編程中跨節(jié)點調(diào)用非常不便,各節(jié)點都被一層黑墻包裹,無法探知周圍都有哪些節(jié)點存在,好在 React 為這個黑墻開了一扇單向玻璃窗:refs,讓父節(jié)點可以引用子節(jié)點,子節(jié)點引用不了父節(jié)點??朔貌槐愕慕馑幨且?redux 那樣的框架,把存在交叉影響的兩個或多個節(jié)點中的數(shù)據(jù),提升到一個公共區(qū)域去編程。

既然 Shadow Widget 引入 MVVM 框架,在 Component 的 API 層面限制節(jié)點間互通已不合時宜,單向數(shù)據(jù)流應(yīng)該在更高層面的設(shè)計去保證。所以,Shadow Widget 引入了 "W 樹" 的概念,也就是,所有符合規(guī)格的 Component 節(jié)點(即源于 WTC 類創(chuàng)建的節(jié)點)都串接在一顆樹上。樹中各節(jié)點都有唯一 "路徑" 標(biāo)示,節(jié)點之間還可以用 "相對路徑" 或 "絕對路徑" 引用,比如:

  this.componentOf("http://")   // get parent component
  this.componentOf("http://brother")   // brother node
  this.componentOf("sub.child")   // child node
  this.componentOf("./seg.child") // by relative path
  this.componentOf(".body.top.toolbar") // by absolute path

有了 W 樹設(shè)計,router 規(guī)劃將變得簡單明了,比方下圖界面,把兩個可切換的頁 ArticleTalk 裝到一個導(dǎo)航面板(NavPanel)中,若想切換到 Article 頁,按 "/article" 導(dǎo)航,切換另一頁用 "/talk" 導(dǎo)航。

?

(本文完)

本專欄歷史文章:

介紹一項讓 React 可以與 Vue 抗衡的技術(shù)

React 可視化開發(fā)工具 Shadow Widget 非正經(jīng)入門(之一:React 三宗罪)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87046.html

相關(guān)文章

  • React 可視開發(fā)工具 Shadow Widget 正經(jīng)入門(之一:React 三宗罪)

    摘要:前言非正經(jīng)入門是相對正經(jīng)入門而言的。不過不要緊,正式學(xué)習(xí)仍需回到正經(jīng)入門的方式。快速入門建議先學(xué)會用拼文寫文檔注冊一個賬號,把庫到自己名下,然后用這個庫寫自己的博客,參見這份介紹。會用拼文寫文章,相當(dāng)于開發(fā)已入門三分之一了。 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計要點,既作為用戶手冊的補充,也從更本質(zhì)角度幫助大家理解 Shadow Widget 為什么這...

    dongxiawu 評論0 收藏0
  • React 可視開發(fā)工具 Shadow Widget 正經(jīng)入門(之五:指令式界面設(shè)計

    摘要:本篇解釋中類的控制指令,與指令式界面設(shè)計相關(guān)。本專欄歷史文章介紹一項讓可以與抗衡的技術(shù)可視化開發(fā)工具非正經(jīng)入門之一三宗罪可視化開發(fā)工具非正經(jīng)入門之二分離界面設(shè)計可視化開發(fā)工具非正經(jīng)入門之三雙源屬性與數(shù)據(jù)驅(qū)動可視化開發(fā)工具非正經(jīng)入門之四 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計要點。本篇解釋 Shadow Widget 中類 Vue 的控制指令,與指令式界面...

    pinecone 評論0 收藏0

發(fā)表評論

0條評論

Carl

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<