成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

手寫簡易前端框架:Function 和 Class 組件

開發 前端
「組件本質上是對 vdom 的動態渲染邏輯的封裝,class 和 function 是兩種封裝形式」。

上篇文章我們實現了 vdom 的渲染,這是前端框架的基礎。但手寫 vdom 太麻煩,我們又支持了 jsx,用它來寫頁面更簡潔。

jsx 不是直接編譯成 vdom 的,而是生成 render function,執行之后產生 vdom。

中間多加了一層 render function,可以執行一些動態邏輯。別小看這一層 render function,它恰恰是實現組件的原理。

實現組件渲染

支持了 jsx 后,可以執行一些動態邏輯,比如循環、比如從上下文中取值:

const list = ['aaa', 'bbb'];
const jsx = <ul className="list">
{
list.map(item => <li className="item">{item}</li>)
}
</ul>

render(jsx, document.getElementById('root'));

這個封裝成函數,然后傳入參數不就是組件么?

我們在 render 函數里處理下函數組件的渲染:

if (isComponentVdom(vdom)) {
const props = Object.assign({}, vdom.props, {
children: vdom.children
});

const componentVdom = vdom.type(props);
return render(componentVdom, parent);
}

如果是 vdom 是一個組件,那么就創建 props 作為參數傳入(props 要加上 children),執行該函數組件,拿到返回的 vdom 再渲染。

判斷組件就是根據 type 是否為 function:


function isComponentVdom(vdom) {
return typeof vdom.type == 'function';
}

就這幾行代碼,我們就實現了函數組件。

測試下效果,聲明兩個函數組件,傳入 props:

function Item(props) {
return <li className="item" style={props.style} onClick={props.onClick}>{props.children}</li>;
}

function List(props) {
return <ul className="list">
{props.list.map((item, index) => {
return <Item style={{ background: item.color }} onClick={() => alert(item.text)}>{item.text}</Item>
})}
</ul>;
}

const list = [
{
text: 'aaa',
color: 'blue'
},
{
text: 'ccc',
color: 'orange'
},
{
text: 'ddd',
color: 'red'
}
]

render(<List list={list}/>, document.getElementById('root'));

在瀏覽器跑一下:

我們實現了函數組件!

是不是非常簡單!它其實就是在 jsx 的基礎上封裝成了函數,然后傳入參數而已。

然后再實現下 class 組件:

class 組件需要聲明一個類,有 state 的屬性:

class Component {
constructor(props) {
this.props = props || {};
this.state = null;
}

setState(nextState) {
this.state = nextState;
}
}

然后渲染 vdom 的時候,如果是類組件,單獨處理下:

if (isComponentVdom(vdom)) {
const props = Object.assign({}, vdom.props, {
children: vdom.children
});

if (Component.isPrototypeOf(vdom.type)) {
const instance = new vdom.type(props);

const componentVdom = instance.render();
instance.dom = render(componentVdom, parent);

return instance.dom;
} else {
const componentVdom = vdom.type(props);
return render(componentVdom, parent);
}
}

判斷如果 vdom 是 Component,就傳入 props 創建實例,然后調用 render 拿到 vdom 再渲染。

還可以加上渲染前后的生命周期函數:

const instance = new vdom.type(props);

instance.componentWillMount();

const componentVdom = instance.render();
instance.dom = render(componentVdom, parent);

instance.componentDidMount();

return instance.dom;

這樣就實現了 class 組件。

我們測試下,聲明一個 class 組件,傳入 props,設置 state:

function Item(props) {
return <li className="item" style={props.style} onClick={props.onClick}>{props.children}</li>;
}

class List extends Component {
constructor(props) {
super();
this.state = {
list: [
{
text: 'aaa',
color: 'blue'
},
{
text: 'bbb',
color: 'orange'
},
{
text: 'ccc',
color: 'red'
}
],
textColor: props.textColor
}
}

render() {
return <ul className="list">
{this.state.list.map((item, index) => {
return <Item style={{ background: item.color, color: this.state.textColor}} onClick={() => alert(item.text)}>{item.text}</Item>
})}
</ul>;
}
}

render(<List textColor={'pink'}/>, document.getElementById('root'));

瀏覽器跑一下:

class 組件渲染成功!

就這樣,我們實現了 class 組件,支持了 props 和 state。

代碼上傳到了 github:https://github.com/QuarkGluonPlasma/frontend-framework-exercize

總結

上篇文章我們支持了 jsx,它編譯產生 render function,執行之后可以拿到 vdom,然后再渲染。

多了這層 render function 之后,它可以執行很多動態邏輯,比如條件判斷、循環,從上下文取值等。

對這些邏輯封裝一下就是組件了:

  • 封裝成函數,傳入 props,就是函數組件
  • 封裝成 class,傳入 props,設置 state 屬性,就是 class 組件

「組件本質上是對 vdom 的動態渲染邏輯的封裝,class 和 function 是兩種封裝形式」。

實現了 vdom 的渲染之后,支持組件的兩種封裝形式是非常簡單的事情。

至此,我們支持了 vdom 渲染、jsx 編譯、class 和 function 組件,渲染部分基本差不多了,下篇文章我們來實現渲染之后的更新,也就是 patch 的功能。

責任編輯:姜華 來源: 神光的編程秘籍
相關推薦

2022-01-21 08:21:48

前端vdom渲染

2022-01-24 13:46:24

框架

2021-09-15 08:09:43

前端技術編程

2021-09-13 09:20:20

前端框架VUE

2021-06-07 00:15:26

瀏覽器HtmlParser

2021-06-04 05:16:33

瀏覽器js源碼

2022-02-11 13:44:56

fiber架構React

2010-12-29 09:51:29

前端基礎框架

2022-03-16 22:24:50

ReactstateHooks

2021-08-04 07:47:17

表單組件代碼

2023-02-27 09:10:57

前端組件設計

2022-01-10 11:04:41

單鏈表面試編程

2015-07-14 10:11:48

前端框架語言

2024-07-01 00:00:03

2020-12-10 06:01:20

前端Compose方法

2023-01-03 09:35:34

SpringbootStarter

2023-02-27 09:38:36

Springbootstarter

2020-11-02 08:19:18

RPC框架Java

2022-09-13 18:55:09

React組件fromJS

2024-10-05 00:00:05

高性能分布式IM
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 51ⅴ精品国产91久久久久久 | 亚洲精品av在线 | 国产精品久久久久久久三级 | 日本在线视频中文字幕 | 国产精品久久久久久久久久久久久 | 欧美九九 | 国产农村一级国产农村 | 欧美一级特黄aaa大片在线观看 | 婷婷毛片 | 亚洲福利网 | 四虎永久在线精品免费一区二 | 成人网av | 国产精品自产拍在线观看蜜 | 国产一区二区三区精品久久久 | 国产精品久久久久久福利一牛影视 | 色吧综合| 91色在线| 女人毛片a毛片久久人人 | 在线不卡视频 | 综合久久久 | 欧美精品三区 | 久久噜噜噜精品国产亚洲综合 | 亚洲免费在线 | 2022国产精品 | 一区二区免费 | 国产精品久久国产精品久久 | 性色综合 | 韩国精品一区 | 国外成人在线视频 | 伊人免费观看视频 | www.亚洲 | 国产精品久久久久久久久大全 | 国产91av视频在线观看 | 伊人天堂网| 一级a性色生活片久久毛片 午夜精品在线观看 | 亚洲国产成人精品女人久久久 | 久久最新精品 | 欧洲亚洲精品久久久久 | 欧美日韩一区二区视频在线观看 | 久热精品在线观看视频 | 丝袜 亚洲 欧美 日韩 综合 |