Vue3響應(yīng)式源碼實現(xiàn)
初始化項目結(jié)構(gòu)
vue-proxy
├── effect.js
├── effect.ts
├── index.html
├── index.js
├── package.json
├── reactive.js
├── reactive.ts
└── webpack.config.js
reactive.ts
import { track, trigger } from "./effect"
// 判斷是否是對象
const isObject = (target) => target !== null && typeof target === "object"
// 泛型約束只能傳入Object類型
export const reactive = <T extends object>(target: T) => {
return new Proxy(target, {
get(target, key, receiver) {
console.log(target);
console.log(key);
console.log(receiver);
let res = Reflect.get(target, key, receiver)
track(target, key)
if (isObject(res)) {
return reactive(res)
}
return res
},
set(target, key, value, receiver) {
let res = Reflect.set(target, key, value, receiver)
console.log(target, key, value);
trigger(target, key)
return res
}
})
}
effect.ts
// 更新視圖的方法
let activeEffect;
export const effect = (fn: Function) => {
const _effect = function () {
activeEffect = _effect;
fn()
}
_effect()
}
// 收集依賴
const targetMap = new WeakMap()
export const track = (target, key) => {
let depsMap = targetMap.get(target)
if (!depsMap) {
depsMap = new Map()
targetMap.set(target, depsMap)
}
let deps = depsMap.get(key)
if (!deps) {
deps = new Set()
depsMap.set(key, deps)
}
deps.add(activeEffect)
}
// 觸發(fā)更新
export const trigger = (target, key) => {
const depsMap = targetMap.get(target)
const deps = depsMap.get(key)
deps.forEach(effect => effect())
}
測試
執(zhí)行 tsc
轉(zhuǎn)成 js 代碼,沒有 tsc
的全局安裝 typescript
npm install typescript -g
新建 index.js
,分別引入 effect.js
和 reactive.js
import { effect } from "./effect.js";
import { reactive } from "./reactive.js";
let data = reactive({
name: "lisit",
age: 18,
foor: {
bar: "汽車"
}
})
effect(() => {
document.getElementById("app").innerText = `數(shù)據(jù)綁定:${data.name} -- ${data.age} -- ${data.foor.bar}`
})
document.getElementById("btn").addEventListener("click", () => {
data.age++
})
新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<button id="btn">按鈕</button>
</body>
然后再根目錄執(zhí)行
npm init -y
安裝依賴
npm install webpack webpack-cli webpack-dev-server html-webpack-plugin -D
然后新建 webpack.config.js
const path = require("path")
const HtmlWebpakcPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./index.js",
output: {
path: path.resolve(__dirname, "dist")
},
plugins: [
new HtmlWebpakcPlugin({
template: path.resolve(__dirname, "./index.html")
})
],
mode: "development",
// 開發(fā)服務(wù)器
devServer: {
host: "localhost", // 啟動服務(wù)器域名
port: "3000", // 啟動服務(wù)器端口號
open: true, // 是否自動打開瀏覽器
},
}
執(zhí)行命令啟動項目
npx webpack serve
文章來源:http://www.zghlxwxcb.cn/news/detail-697283.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-697283.html
到了這里,關(guān)于Vue3響應(yīng)式源碼實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!