webapck搭建環境,讓你知道vue中的h函式的作用和虛擬節點如何上樹!

南風晚來晚相識發表於2021-12-13

搭建環境

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檔案在專案的根目錄下
// 安裝官網配置直接複製 https://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的地址:https://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: 'https://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: 'https://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節點

尾聲

如何你覺得我寫的還不錯的話,
給我點一個推薦或者打賞,這是我寫下去的動力。
看官,我已經三個月沒有吃辣條了。
給我買一包吧,就一包!求求你了!
diff演算法是如何跟新的,看這一篇文章

diff演算法是如何跟新的請看這一篇文章

相關文章