摘要:但是,最后一步,事件怎么綁定呢這塊沒(méi)有深入研究了,不過(guò)我想,應(yīng)該這樣去實(shí)現(xiàn)也是沒(méi)有問(wèn)題的。的具體做法是,把方法放到了一個(gè)叫做的組件上去實(shí)現(xiàn)這個(gè)功能,然后再把內(nèi)容放進(jìn)這個(gè)組件。其他的邏輯比如顯示隱藏之類,全部都放到組件自身上去實(shí)現(xiàn)。
1、Dialog組件提供什么功能,解決什么問(wèn)題?
zent的Dialog組件,使用姿勢(shì)是這樣的(代碼摘自zent官方文檔:https://www.youzanyun.com/zan...)
import { Dialog, Button } from "zent"; class Example extends React.Component { state = { visible: false } triggerDialog = visible => { this.setState({ visible }); }; render() { return (); } } ReactDOM.render(, mountNode);
可以通過(guò)visible屬性控制彈層的顯示與隱藏
可以隨意的在Dialog組件里添加任意多的內(nèi)容
可以在任意位置使用Dialog組件
2、如果我來(lái)實(shí)現(xiàn)會(huì)怎么做?如果我來(lái)實(shí)現(xiàn),其實(shí)很簡(jiǎn)單,用jQuery已經(jīng)寫(xiě)了無(wú)數(shù)遍了,但是,想想當(dāng)初用jQuery來(lái)寫(xiě)組件的時(shí)候,非常方便的可以在body下面插入一個(gè)div,并且綁定事件,或者,直接把彈層的div寫(xiě)到body標(biāo)簽下面。
但是,react,卻是組件嵌套組件,所有組件都渲染在一個(gè)被稱為root的div下面,這可怎么把一個(gè)節(jié)點(diǎn)掛載到body下面呢?
也簡(jiǎn)單,我直接用document.body.appendChild把組件直接插入到body后面,但是發(fā)現(xiàn),document.body.appendChild的參數(shù)必須是標(biāo)準(zhǔn)的dom節(jié)點(diǎn),而react里面,通過(guò)this.props.children取出來(lái)的數(shù)據(jù),并不是標(biāo)準(zhǔn)的dom節(jié)點(diǎn),這也好辦,把這些節(jié)點(diǎn)轉(zhuǎn)成標(biāo)準(zhǔn)的dom節(jié)點(diǎn),然后插入到body下面不就ok了?我是這么想的。但是,最后一步,事件怎么綁定呢?這塊沒(méi)有深入研究了,不過(guò)我想,應(yīng)該這樣去實(shí)現(xiàn)也是沒(méi)有問(wèn)題的。
順便說(shuō)一下,曾經(jīng)我還實(shí)現(xiàn)過(guò)一個(gè)React的彈層,但是必須放到最外層使用。。。哈哈,不說(shuō)了,都是淚,侵入太強(qiáng),無(wú)法做到在任意位置使用Dialog組件。
3、zent的Dialog實(shí)現(xiàn)方式zent實(shí)現(xiàn)方式,其實(shí)跟我上面說(shuō)的基本思路是一致的,只是,用的方法不再是document.body.appendChild,而是用到了一個(gè)React提供的叫做ReactDOM.unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback)的方法,第一個(gè)參數(shù)是當(dāng)前dialog所在的父組件,第二個(gè)參數(shù)是將要渲染的dialog內(nèi)容,其實(shí)就是this.props.children,第三個(gè)參數(shù)是即將要掛載到body下面的一個(gè)div容器節(jié)點(diǎn),callback就是成功之后的回調(diào)了。
從函數(shù)名可以看出,這個(gè)方法是不穩(wěn)定的,但是,zent還是用了,不過(guò)效果很好,哈哈。
zent的具體做法是,把ReactDOM.unstable_renderSubtreeIntoContainer方法放到了一個(gè)叫做Portal的組件上去實(shí)現(xiàn)這個(gè)功能,然后再把dialog內(nèi)容放進(jìn)這個(gè)Portal組件。
{this.props.children}
Portal組件本身的功能非常簡(jiǎn)單,僅僅只是負(fù)責(zé)把其子組件渲染到body下面的一個(gè)新創(chuàng)建的div下面去。其他的邏輯(比如顯示、隱藏、mask之類),全部都放到dialog組件自身上去實(shí)現(xiàn)。當(dāng)然,顯示與隱藏的功能,還是由Portal來(lái)控制,隱藏的時(shí)候,Portal會(huì)把當(dāng)前的子組件從body上面卸載掉。
4、極簡(jiǎn)實(shí)現(xiàn)以下是一個(gè)極簡(jiǎn)的Portal實(shí)現(xiàn),即把自己的子組件渲染到body上面去。
import React from "react"; import ReactDOM from "react-dom"; export default class Portal extends React.Component { renderChildren() { const container = document.createElement("div"); document.body.appendChild(container); ReactDOM.unstable_renderSubtreeIntoContainer(this, React.Children.only(this.props.children), container); } componentDidMount() { this.renderChildren(); } render() { return null; } }
以下是,基于Portal的Dialog組件的極簡(jiǎn)實(shí)現(xiàn):
import React from "react"; import Portal from "./portal"; export default class Dialog extends React.Component { render() { return} } {this.props.children}
使用方式:
import React, { Component } from "react"; import ReactDOM, { render } from "react-dom"; import Dialog from "./dialog"; class App extends Component { onTextClick = () => { console.log("clicked") } render() { return (); } } render(, document.getElementById("root"));
當(dāng)然,真正要實(shí)現(xiàn)一個(gè)Dialog需要考慮的問(wèn)題還有很多,比如控制隱藏與顯示、定制動(dòng)畫(huà),自定義樣式,配置dialog的標(biāo)題和其他屬性等等,只是這些我們?cè)趈Query時(shí)代都已經(jīng)做過(guò)。
這里主要分析了Portal的實(shí)現(xiàn),畢竟,在React里面,要把組件渲染到app根節(jié)點(diǎn)外面去并不容易。
(全文完)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95589.html
摘要:引言組件中有很多彈出式組件,常見(jiàn)的如,以及等。這樣一種層次結(jié)構(gòu)在實(shí)踐中大大降低了各類彈層組件的實(shí)現(xiàn)和維護(hù)成本。但是的組件實(shí)現(xiàn)了一個(gè)大多數(shù)組件庫(kù)都沒(méi)有實(shí)現(xiàn)的功能彈層的嵌套處理。 引言 UI 組件中有很多彈出式組件,常見(jiàn)的如 Dialog,Tooltip 以及 Select 等。這些組件都有一個(gè)特點(diǎn),它們的彈出層通常不是渲染在當(dāng)前的 DOM 樹(shù)中,而是直接插入在 body (或者其它類似的...
摘要:是有贊端規(guī)范的實(shí)現(xiàn)版本,提供了一整套基礎(chǔ)的組件以及常用的業(yè)務(wù)組件。目前我們有組件,其中包括以及等實(shí)用的業(yè)務(wù)組件。一套有贊設(shè)計(jì)師繪制的圖標(biāo)庫(kù)。為了解決這些問(wèn)題,提供了一套自己的時(shí)間選擇組件,包括日期選擇周選擇組件月選擇以及時(shí)間區(qū)間選擇。 Zent ( ?zent ) 是有贊 PC 端 Web UI 規(guī)范的 React 實(shí)現(xiàn)版本,提供了一整套基礎(chǔ)的 UI 組件以及常用的__業(yè)務(wù)組件__。通...
摘要:源碼真的這么可怕嗎從以上的事例中可以看出,其實(shí)并沒(méi)有。對(duì)于源碼的恐懼,讓我們漸漸思維固化,自己告訴自己不要去碰源碼,時(shí)間長(zhǎng)了就遺忘了還有這樣一條路可走。 一個(gè)小需求 事情的起因,是昨天有一個(gè)新的需求被提出。 需求是要實(shí)現(xiàn),讓我們自己定制的彈出層,具備按下 ESC 也能退出的功能。我把任務(wù)交給了同組的小伙伴S去實(shí)現(xiàn)。(這個(gè)項(xiàng)目用到了vue技術(shù)棧,以及餓了么的UI框架。) 我開(kāi)完會(huì)回來(lái),發(fā)...
摘要:近期給自己立了個(gè)小,讀源碼,每周至少讀篇源碼下面來(lái)談?wù)労瓦@兩個(gè)基于的框架源碼的基本結(jié)構(gòu)以及區(qū)別。例如四兩個(gè)庫(kù)組件整體引入和按需引入整體引入兩個(gè)庫(kù)一樣的方法。 (近期給自己立了個(gè)小flag,讀源碼,每周至少讀1篇源碼) 下面來(lái)談?wù)刬view 和 Elemet UI 這兩個(gè)基于Vue 的UI 框架源碼的基本結(jié)構(gòu)以及區(qū)別。 一、文件結(jié)構(gòu)開(kāi)發(fā)主要放在根文件夾下的src下: 1. ivew 文件...
閱讀 654·2021-09-24 09:48
閱讀 2499·2021-08-26 14:14
閱讀 524·2019-08-30 13:08
閱讀 1450·2019-08-29 15:22
閱讀 3084·2019-08-29 11:06
閱讀 1011·2019-08-26 18:26
閱讀 1062·2019-08-26 13:53
閱讀 2538·2019-08-26 12:21