dom wrapper 是以 (個人理解)
也就是說, 網頁渲染, 主要依賴以上5個函式
程式碼
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js native </title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
main.js
window.onload = () =>{
// 把 html element 先一次宣告好
let body = document.querySelector("body")
let inputText = document.createElement("input")
let view = document.createElement("div")
// setup inputText
body.appendChild(inputText) // 將 inputText 掛到 body 下面
inputText.setAttribute("type","text") // 為了輸入文字, 設定為 text 類型
inputText.setAttribute("placeholder","input text") // 給個預設文字友善使用者
inputText.addEventListener("keydown",(e)=>{ // 註冊事件監聽器, keydown 為鍵盤壓下的時候
if( e.key === "Enter"){ // 捕捉 Enter 按鍵
let temp = document.createElement("div") // 每一個輸入的文字 用個 div 去渲染
temp.innerHTML = e.target.value // 把 div 加上文字, e.target.value 就是使用者輸入
view.appendChild( temp ) // 將 temp 加入 view
e.target.value = "" // 將 輸入框的文字清掉, 讓使用者輸入下一個
}
})
inputText.setAttribute("style","margin-bottom:10px") // 這邊做個 css 設定
// setup view
body.appendChild(view) // 將 view 加入 body下面
}
virtual dom 就是 把一個 html tag 拆成 3部份
<div class="header" style="color:red"> Hello World</div>
解說:
tag: div
props: class="header" style="color:red", 這邊可以用物件去處裡
Hello World: child
主要以上三個結構(其實省略了 onclick 的事件監聽, 但是複雜度會變高, 故簡單實做先省略)
react renderer 分為三個主要部份 ( 先省略render 裡面的優化演算法 fiber 等等 )
codepen
reacty.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>reacty</title>
</head>
<body>
<div id="root"></div>
<script>
window.onload = ()=>{
const Reacty = {
createElement,
render
}
const root = document.querySelector("#root")
Reacty.render(
Reacty.createElement("div", { style:"font-weight:medium" },
Reacty.createElement("div", {style:"font-size:20px;color:red"},"hello"),
Reacty.createElement("div", {style:"font-size:15px;color:gray"}, "this is yale"),
"coding is fun"
),
root
)
function createElement(type, props, ...children){
return {
type,
props: {
...props,
children: children.map((child) =>
typeof child === "object" ? child : createTextElement(child)
)
}
}
}
function createTextElement(text) {
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: []
}
}
}
function render(element, container){
const dom =
element.type == "TEXT_ELEMENT"
? document.createTextNode("")
: document.createElement(element.type)
const isProperty = (key) => key !== "children"
Object.keys(element.props)
.filter(isProperty)
.forEach((name)=>{
dom[name] = element.props[name]
})
element.props.children.forEach((child)=>render(child, dom))
container.appendChild(dom)
}
}
</script>
</body>
</html>
參考資料:
build your own react
後記:
註解要寫的好多, 改天再補好了, 參考資料個人是跟前半段, 後半段fiber比較複雜, 躺平xD