国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

魚滑怎么制作教程搜索引擎優(yōu)化seo的英文全稱是

魚滑怎么制作教程,搜索引擎優(yōu)化seo的英文全稱是,wordpress 安裝問題,用html5做京東網(wǎng)站代碼通過上一篇文章已經(jīng)初始化項目,集成了ts和jest。本篇實現(xiàn)Vue3中響應式模塊里的reactive方法。 前置知識要求 如果你熟練掌握Map, Set, Proxy, Reflect,可直接跳過這部分。 Map Map是一種用于存儲鍵值對的集合,并且能夠記住鍵的原始插入順…

通過上一篇文章已經(jīng)初始化項目,集成了tsjest。本篇實現(xiàn)Vue3中響應式模塊里的reactive方法。

前置知識要求

如果你熟練掌握Map, Set, Proxy, Reflect,可直接跳過這部分。

Map

Map是一種用于存儲鍵值對的集合,并且能夠記住鍵的原始插入順序。 其中鍵和值可以是任意類型的數(shù)據(jù)。

初始化,添加,獲取

let myMap = new Map()myMap.set('name', 'wendZzoo')
myMap.set('age', 18)myMap.get('name')
myMap.get('age')

Map 中的一個鍵只能出現(xiàn)一次,它在 Map 的集合中是獨一無二的,重復設置的會被覆蓋

myMap.set('name', 'jack')

Map 的鍵和值可以是任意類型的數(shù)據(jù)

myMap.set({name: 'wendZzoo'}, [{age: 18}])

刪除

let myMap = new Map()
myMap.set('name', 'Tom')
myMap.delete('name')

key數(shù)據(jù)類型是對象時,需要使用對應的引用來刪除鍵值對

let myMap = new Map()
let key = [{name: 'Tom'}]
myMap.set(key, 'Hello')
myMap.delete(key)// 如果使用不同的引用來嘗試刪除鍵值對
// 它將無法正常工作
// 因為Map無法識別這兩個引用是相同的鍵
myMap.set([{name: 'Tom'}], 'Hello')
myMap.delete([{name: 'Tom'}])

Set

Set是一種集合數(shù)據(jù)結(jié)構(gòu),它允許存儲唯一的值,無重復項。Set對象可以存儲任何類型的值,包括基本類型和對象引用。

let mySet = new Set()mySet.add('wendZzoo')
mySet.add(18)
mySet.add({province: 'jiangsu', city: 'suzhou'})

可迭代

for (let key of mySet) {console.log(key)
}

Proxy

Proxy 對象用于創(chuàng)建一個對象的代理,從而實現(xiàn)基本操作的攔截和自定義(如屬性查找、賦值、枚舉、函數(shù)調(diào)用等)。

Vue 響應式的前提就是需要數(shù)據(jù)劫持,在 JS 中有兩種劫持 property 訪問的方式:getter / setters 和 Proxies。Vue 2 使用 getter / setters 完全是出于支持舊版本瀏覽器的限制,而在 Vue 3 中則使用了 Proxy 來創(chuàng)建響應式對象。

創(chuàng)建 Proxy 對象時,需要提供兩個參數(shù):目標對象 target(被代理的對象)和一個處理程序?qū)ο?handler(用于定義攔截行為的方法)。

其中 handler 常用的有 get,set 方法。

handler.get() 方法用于攔截對象的讀取屬性操作,完整使用可以參考:MDN

它接收三個參數(shù):

  1. target:目標對象
  2. property:被獲取的屬性名
  3. receiver:Proxy 或者繼承 Proxy 的對象
const obj = {name: 'wendZzoo', age: 18}
let myProxy = new Proxy(obj, {get: (target, property, receiver) => {console.log('收集依賴')return target[property]}
})// 執(zhí)行 myProxy.name
// 執(zhí)行 myProxy.age

handler.set() 方法是設置屬性值操作的捕獲器,完整使用參考:MDN

它接收四個參數(shù)

  1. target:目標對象
  2. property:將被設置的屬性名或 Symbol、
  3. value:新屬性值
  4. receiver:最初被調(diào)用的對象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型鏈上,或以其他方式被間接地調(diào)用(因此不一定是 proxy 本身)
const obj = {name: 'wendZzoo', age: 18}
let myProxy = new Proxy(obj, {get: (target, property, receiver) => {console.log('收集依賴')return target[property]},set: (target, property, value, receiver) => {console.log('觸發(fā)依賴')target[property] = valuereturn true}
})
myProxy.name = 'Jack'
myProxy.age = 20

Proxy 提供了一種機制,通過攔截和修改目標對象的操作來實現(xiàn)自定義行為,在 get 和 set 方法打印日志的地方,也就是 Vue3 實現(xiàn)依賴收集和觸發(fā)依賴的地方。

Reflect

Reflect 是一個內(nèi)置的對象,它提供攔截 JS 操作的方法。這讓它可以完美的和 Proxy 配合,Proxy 提供了對對象攔截的時機位置,Reflect 提供攔截方法。

Reflect 不是一個構(gòu)造函數(shù),因此不能 new 進行調(diào)用,更像 Math 對象,作為一個函數(shù)來調(diào)用,它所有的屬性和方法都是靜態(tài)的。

常用的方法有 get,set。

Reflect.get方法允許你從一個對象中取屬性值,完整使用參考:MDN

它接收三個參數(shù):

  1. target:需要取值的目標對象
  2. propertyKey:需要獲取的值的鍵值
  3. receiver:如果 target 對象中指定了getter,receiver 則為 getter 調(diào)用時的this值
let obj = {name: 'wendZzoo', age: 18}
Reflect.get(obj, 'name')
Reflect.get(obj, 'age')

Reflect.set 方法允許在對象上設置屬性,完整使用參考:MDN

它接收三個參數(shù):

  1. target:設置屬性的目標對象
  2. propertyKey:設置的屬性的名稱
  3. value:設置的值
  4. receiver:如果遇到 setter,receiver則為setter調(diào)用時的this值
let obj = {}
Reflect.set(obj, 'name', 'wendZzoo')let arr = ['name', 'address']
Reflect.set(arr, 1, 'age')
Reflect.set(arr, 'length', 1)

更改目錄

src下新建文件夾reactivity,新建effect.tsreactive.ts。

tests文件夾下刪除上一篇文章中用于驗證jest安裝的index.spec.ts,新建effect.spec.tsreactive.spec.ts。

reactive

先寫單測,明確需要的成果,再根據(jù)這個需求來實現(xiàn)函數(shù)。Vue3的reactive方法返回一個對象的響應式代理,那代理的對象和源對象是不同的,但是又能和源對象一樣的嵌套結(jié)構(gòu)。

那單測可以這樣寫:reactive.spec.ts

import { reactive } from "../reactivity/reactive";describe("reactive", () => {it("happy path", () => {let original = { foo: 1 };let data = reactive(original);expect(data).not.toBe(original);expect(data.foo).toBe(1);});
});

根據(jù)這兩個斷言,來實現(xiàn)現(xiàn)階段的reactive方法。Vue3中是使用Proxy實現(xiàn)。

reactive.ts

export function reactive(raw) {return new Proxy(raw, {get: (target, key) => {let res = Reflect.get(target, key);// TODO 依賴收集return res;},set: (target, key, value) => {let res = Reflect.set(target, key, value);// TODO 觸發(fā)依賴return res;},});
}

運行reactive單測,來驗證該方法實現(xiàn)是否正確,執(zhí)行yarn test reactive

effect

在官網(wǎng)上是沒有單獨提到這個 API 的,可以在進階主題的深入響應式系統(tǒng)一篇中找到它的身影。

effect直接翻譯為作用,意思是使其發(fā)生作用,這個使其的其就是我們傳入的函數(shù),所以effect的作用就是讓我們傳入的函數(shù)發(fā)生作用,也就是執(zhí)行這個函數(shù)。

使用示例

import { reactive, effect } from "vue";let user = reactive({age: 10,
});let nextAge;function setAge() {effect(() => {nextAge = user.age + 1;});console.log(nextAge);
}function updateAge() {user.age++;console.log(nextAge);
}

在沒有使用effect作用于nextAge時,直接觸發(fā)updateAge方法,輸出的nextAge就是undefined

調(diào)用setAgeeffect中函數(shù)執(zhí)行給nextAge賦值,響應式數(shù)據(jù)userage變化,nextAge也在繼續(xù)執(zhí)行effect中函數(shù)。

單測

effect的單測可以寫成這樣:

import { effect } from "../reactivity/effect";
import { reactive } from "../reactivity/reactive";describe("effect", () => {it("happy path", () => {let user = reactive({age: 10,});let nextAge;effect(() => {nextAge = user.age + 1;});expect(nextAge).toBe(11);});
});

effect方法就是接收一個方法,并執(zhí)行它。

effect.ts

class ReactiveEffect {private _fn: any;constructor(fn) {this._fn = fn;}run() {this._fn();}
}export function effect(fn) {let _effect = new ReactiveEffect(fn);_effect.run();
}

通過抽離成一個Class類,去執(zhí)行傳入的 fn 參數(shù)。

再來執(zhí)行所有的單測,驗證是否成功,執(zhí)行yarn test

依賴收集

修改effect單測,增加一個斷言,來判斷當age變化時,nextAge是否也更新了?

import { effect } from "../reactivity/effect";
import { reactive } from "../reactivity/reactive";describe("effect", () => {it("happy path", () => {let user = reactive({age: 10,});let nextAge;effect(() => {nextAge = user.age + 1;});expect(nextAge).toBe(11);// +++updateruser.age++;expect(nextAge).toBe(12);});
});

執(zhí)行單測發(fā)現(xiàn)無法通過,是因為Proxy代理時候并沒有實現(xiàn)依賴收集和觸發(fā)依賴,也就是reactive.ts中還有兩個 TODO。

但是,首先得清楚什么叫依賴

引用官方的例子:

let A0 = 1
let A1 = 2
let A2 = A0 + A1console.log(A2) // 3A0 = 2
console.log(A2) // 仍然是 3

當我們更改 A0 后,A2 不會自動更新。

那么我們?nèi)绾卧?JavaScript 中做到這一點呢?首先,為了能重新運行計算的代碼來更新 A2,我們需要將其包裝為一個函數(shù):

let A2function update() {A2 = A0 + A1
}

然后,我們需要定義幾個術語:

  • 這個 update() 函數(shù)會產(chǎn)生一個副作用,或者就簡稱為作用 (effect),因為它會更改程序里的狀態(tài)。
  • A0 和 A1 被視為這個作用的依賴 (dependency),因為它們的值被用來執(zhí)行這個作用。因此這次作用也可以說是一個它依賴的訂閱者 (subscriber)。

因此我們可以大膽通俗的講,依賴就是指的是觀察者(通常是視圖或副作用函數(shù))對數(shù)據(jù)的依賴關系。當觀察者需要訪問特定數(shù)據(jù)時,它就成為該數(shù)據(jù)的依賴。

依賴收集呢?

依賴收集是用于追蹤和管理數(shù)據(jù)依賴關系。常用于實現(xiàn)響應式系統(tǒng),其中數(shù)據(jù)的變化會自動觸發(fā)相關的更新操作。

當數(shù)據(jù)發(fā)生改變時,相關的視圖或操作也能夠自動更新,以保持數(shù)據(jù)和界面的同步。依賴收集可以幫助我們建立起數(shù)據(jù)和視圖之間的關聯(lián),確保數(shù)據(jù)的變化能夠自動反映在視圖上。

從代碼層面講,讀取對象的時候也就是get操作時,進行依賴收集,將目標對象target,對象中key,Dep實例做關聯(lián)映射。

effect.ts中定義依賴收集的方法track

class ReactiveEffect {private _fn: any;constructor(fn) {this._fn = fn;}run() {reactiveEffect = this;this._fn();}
}let targetMap = new Map();
export function track(target, key) {// target -> key -> deplet depMap = targetMap.get(target);if (!depMap) { // initdepMap = new Map();targetMap.set(target, depMap);}let dep = depMap.get(key);if (!dep) { // initdep = new Set();depMap.set(key, dep);}dep.add(reactiveEffect);
}let reactiveEffect;
export function effect(fn) {let _effect = new ReactiveEffect(fn);_effect.run();
}

觸發(fā)依賴

在設置對象屬性時,也就是進行set操作時,觸發(fā)依賴。將每個屬性上掛載的depSet結(jié)構(gòu)中的所有作用函數(shù)執(zhí)行。

export function trigger(target, key) {let depMap = targetMap.get(target);let dep = depMap.get(key);for (const effect of dep) {effect.run();}
}

至此,再次執(zhí)行所有單測,yarn test

總結(jié)

  1. 先通過單測入手,明確需要實現(xiàn)的函數(shù)方法的功能
  2. 分布實現(xiàn)功能點,即拆分功能點,先初步實現(xiàn)了reactive方法簡單版,只要求原數(shù)據(jù)和代理之后的數(shù)據(jù)不同,但是數(shù)據(jù)結(jié)構(gòu)又要一樣,像深拷貝一樣。
  3. 通過Class類,實現(xiàn)effect方法可以自執(zhí)行其傳入的函數(shù)參數(shù)
  4. 依賴收集,通過兩個Map結(jié)構(gòu)和一個Set結(jié)構(gòu)來映射數(shù)據(jù)關系,將所有的fn存放到dep中。通過一個全局變量reactiveEffect來獲取到effct實例,為后續(xù)觸發(fā)依賴時,直接拿dep中每一項去執(zhí)行。
  5. 觸發(fā)依賴,通過映射關系獲取到dep,因為depSet結(jié)構(gòu),可迭代,循環(huán)每項執(zhí)行。
http://m.aloenet.com.cn/news/32821.html

相關文章:

  • 施工效果圖怎么做關鍵詞搜索優(yōu)化
  • 江蘇做網(wǎng)站公司東莞整站優(yōu)化推廣公司找火速
  • 個人電腦做網(wǎng)站服務器教程制作一個app軟件需要多少錢
  • 利辛做網(wǎng)站搜索引擎關鍵詞怎么選
  • php怎么建立站點下載百度語音導航地圖安裝
  • 如何更新網(wǎng)站緩存濟南網(wǎng)絡優(yōu)化廠家
  • 網(wǎng)站中鏈接怎么做推廣網(wǎng)站公司
  • 網(wǎng)站開發(fā)進度管理表谷歌seo工具
  • 太原網(wǎng)站建設費用上首頁seo
  • 網(wǎng)站一般寬度windows優(yōu)化大師有哪些功能
  • 國內(nèi) 設計網(wǎng)站的公司網(wǎng)站3000行業(yè)關鍵詞
  • 手機網(wǎng)站開發(fā)教程東莞做網(wǎng)站哪家公司好
  • 網(wǎng)站有沒有做網(wǎng)站地圖怎么看今天國際新聞大事
  • 想做一個自己設計公司的網(wǎng)站怎么做的網(wǎng)站推廣公司電話
  • 電腦做系統(tǒng)網(wǎng)站鄭州網(wǎng)站優(yōu)化培訓
  • 軟件工程師是程序員嗎電腦優(yōu)化工具
  • 建設一個大型網(wǎng)站大概費用磁力王
  • 主流門戶網(wǎng)站百度關鍵詞搜索推廣
  • 怎樣設計網(wǎng)頁教程關鍵詞優(yōu)化外包
  • 鄭州電力高等??茖W校哪個專業(yè)好重慶seo和網(wǎng)絡推廣
  • 可視化網(wǎng)站制作軟件站長之家ppt素材
  • 深圳html5網(wǎng)站建設搜索引擎營銷sem
  • 遼寧網(wǎng)站推廣的目的網(wǎng)絡運營是做什么的工作
  • 做外國網(wǎng)站買域名推廣賺錢一個2元
  • 網(wǎng)站建設后期維護小魔仙網(wǎng)絡廣告宣傳平臺
  • 企業(yè)網(wǎng)絡營銷策劃方案范文免費seo教程資源
  • wordpress 添加搜索引擎北京網(wǎng)絡seo
  • 三合一網(wǎng)站建設方案深圳市網(wǎng)絡營銷推廣服務公司
  • b2b網(wǎng)站建設開發(fā)china東莞seo
  • 網(wǎng)站的服務有哪些seo外鏈工具有用嗎