webapck搭建環境,讓你知道vue中的h函數的作用和虛擬節點如何上樹!
- 2021 年 12 月 13 日
- 筆記
- vue底層原理理解系類
搭建環境
npm init 初始化項目
npm i -D snabbdom 安裝
npm i -D webpack@5 webpack-cli@3 webpack-dev-server@3
簡單介紹
snabbdom 是一個DOM庫.[重要]
不能夠直接運行在Node環境中,
我們需要搭建一個webpack和webpack-dev-server的開發環境
需要注意的是必須安裝webpck5. 不能夠安裝webpack4.
因為webpck4中沒有讀取 exports的能力哈
然後安裝:目的是搭建開發的運行環境
npm i -D webpack@5 webpack-cli@3 webpack-dev-server@3
這個千萬不忘記配置呀
創建 webpack.config文件
//這個webpack.config文件在項目的根目錄下
// 安裝官網配置直接複製 //webpack.js.org/ 然後做簡單的修改
const path = require('path');
module.exports = {
// 入口,需要靠你去創建
entry: './src/index.js',
// 出口
output: {
// path: path.resolve(__dirname, 'dist'),
//虛擬的打包路徑 也就是說文件夾不會真正的生成,而是在8080埠虛擬生成的
// xuni 這個不會真正的生成,在記憶體中,打包後的文件名是 bundle
publicPath:'xuni',
filename: 'bundle.js',
},
<!-- 配置的是 開發服務 -->
devServer: {
port: 8080, //埠
// 靜態資源文件夾,你創建一個,跟src 同級,
contentBase:'www'
}
};
需要創建的文件
根據上面的配置要求。
我們需要在項目的跟目錄下創建 src文件夾,src下有index.js文件
我們需要在項目的跟目錄下創建 www文件夾,src下有index.html文件
我們在index.js文件中寫
console.log("你好啊,環境已經搭建ok,我好高興")
這個文件打包後對應的虛擬文件是bundle.js
我們在index.html文件中寫
<body>
<h1>你好啊!</h1>
<!--
這個container 在我們等會使用snabbdom的時候需要,
我們現在就將他創建好
-->
<div id="container"></div>
</body>
<!--
bundle.js 是我們生成在記憶體中的,在物理上看不見。
我們等會寫的xuni/bundle.js 是打包後的。
它打包前的是 src下有index.js文件
-->
<script src="xuni/bundle.js"></script>
</html>
更改 package.json 文件配置
在package.json文件中。
我們需要更改一下配置
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
更改為
"scripts": {
"dev": "webpack-dev-server"
},
這樣我們執行 npm run dev 就會將,
我們下載的 webpack-dev-server服務啟動起來
然後簡單去走一下 snabbdom的流程
snabbdom的地址://github.com/snabbdom/snabbdom
複製Example。到我們的 index.js文件中
我們會發現有
const container = document.getElementById("container");
所以我們需要在index.html中去創建
這就解釋了為啥我們的index.html需要有一個id為container
不過我們剛剛已經創建了
然後我們會發現有兩個函數報錯 someFn is not undefined
anotherEventHandler is not undefined
我們將這兩個函數更改為普通函數 就ok了

index.js簡單使用h函數
import {
init,
classModule,
propsModule,
styleModule,
eventListenersModule,
h,
} from "snabbdom";
let myVnode1 = h
(
'a',
{ props:
{ href: '//www.cnblogs.com/IwishIcould/' }
},
'我的部落格'
)
console.log("myVnode1", myVnode1) //輸出來的內容就是虛擬dom節點
這行程式碼說明了: h函數產生虛擬dom節點

區別
<div>
<p>123</p>
</div>
轉化為這個
let obj={
'tag':'div',
'child':[
'tag':'p',
'text':'123'
]
}
不是h函數做的。
而是模板編譯原理做的
使用patch函數讓虛擬dom節點上樹
import {
init,
classModule,
propsModule,
styleModule,
eventListenersModule,
h,
} from "snabbdom";
let myVnode1 = h('a', { props: { href: '//www.cnblogs.com/IwishIcould/' } }, '我的部落格')
console.log("myVnode1", myVnode1) //輸出來的內容就是虛擬dom節點
// 使用init函數創建 patch函數
const patch = init([classModule, propsModule, styleModule, eventListenersModule])
const container = document.getElementById('container')
// 讓虛擬節點上樹
patch(container,myVnode1)

init函數創建patch函數
使用init函數創建patch函數 ,init函數接受4個參數。
const patch = init([classModule, propsModule, styleModule, eventListenersModule])
[類模組,屬性模組,style模組,事件模組 ]
patch函數讓虛擬dom節點上樹
// 讓虛擬節點上樹
patch(container,myVnode1)
patch函數接受兩個參數,上樹到哪一個容器下,上樹的虛擬節點
一個容器讓多個虛擬節點上樹,可以使用h函數的嵌套
let myVnode1 = h('ul', {}, [
h('li', {}, '姓名'),
h('li', {}, '年齡'),
h('li', {}, '愛好'),
])
console.log("myVnode1", myVnode1) //輸出來的內容就是虛擬dom節點
// 使用init函數創建 patch函數
const patch = init([classModule, propsModule, styleModule, eventListenersModule])
const container = document.getElementById('container')
// 讓虛擬節點上樹
patch(container, myVnode1)
console.log("上樹後", myVnode1) //輸出來的內容就是虛擬dom節點
