国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 語(yǔ)言 > JavaScript > 正文

這應(yīng)該是最詳細(xì)的響應(yīng)式系統(tǒng)講解了

2024-05-06 15:36:44
字體:
供稿:網(wǎng)友

前言

本文從一個(gè)簡(jiǎn)單的雙向綁定開始,逐步升級(jí)到由defineProperty和Proxy分別實(shí)現(xiàn)的響應(yīng)式系統(tǒng),注重入手思路,抓住關(guān)鍵細(xì)節(jié),希望能對(duì)你有所幫助。

一、極簡(jiǎn)雙向綁定

首先從最簡(jiǎn)單的雙向綁定入手:

// html<input type="text" id="input"><span id="span"></span>
// jslet input = document.getElementById('input')let span = document.getElementById('span')input.addEventListener('keyup', function(e) { span.innerHTML = e.target.value})

以上似乎運(yùn)行起來也沒毛病,但我們要的是數(shù)據(jù)驅(qū)動(dòng),而不是直接操作dom:

// 操作obj數(shù)據(jù)來驅(qū)動(dòng)更新let obj = {}let input = document.getElementById('input')let span = document.getElementById('span')Object.defineProperty(obj, 'text', { configurable: true, enumerable: true, get() {  console.log('獲取數(shù)據(jù)了')  return obj.text }, set(newVal) {  console.log('數(shù)據(jù)更新了')  input.value = newVal  span.innerHTML = newVal }})input.addEventListener('keyup', function(e) { obj.text = e.target.value})

以上就是一個(gè)簡(jiǎn)單的雙向數(shù)據(jù)綁定,但顯然是不足的,下面繼續(xù)升級(jí)。

二、以defineProperty實(shí)現(xiàn)響應(yīng)系統(tǒng)

在Vue3版本來臨前以defineProperty實(shí)現(xiàn)的數(shù)據(jù)響應(yīng),基于發(fā)布訂閱模式,其主要包含三部分:Observer、Dep、Watcher。

1. 一個(gè)思路例子

// 需要劫持的數(shù)據(jù)let data = { a: 1, b: {  c: 3 }}// 劫持?jǐn)?shù)據(jù)dataobserver(data)// 監(jiān)聽訂閱數(shù)據(jù)data的屬性new Watch('a', () => {  alert(1)})new Watch('a', () => {  alert(2)})new Watch('b.c', () => {  alert(3)})

以上就是一個(gè)簡(jiǎn)單的劫持和監(jiān)聽流程,那對(duì)應(yīng)的observer和Watch該如何實(shí)現(xiàn)?

2. Observer

observer的作用就是劫持?jǐn)?shù)據(jù),將數(shù)據(jù)屬性轉(zhuǎn)換為訪問器屬性,理一下實(shí)現(xiàn)思路:

①Observer需要將數(shù)據(jù)轉(zhuǎn)化為響應(yīng)式的,那它就應(yīng)該是一個(gè)函數(shù)(類),能接收參數(shù)。
②為了將數(shù)據(jù)變成響應(yīng)式,那需要使用Object.defineProperty。
③數(shù)據(jù)不止一種類型,這就需要遞歸遍歷來判斷。

// 定義一個(gè)類供傳入監(jiān)聽數(shù)據(jù)class Observer { constructor(data) {  let keys = Object.keys(data)  for (let i = 0; i < keys.length; i++) {   defineReactive(data, keys[i], data[keys[i]])  } }}// 使用Object.definePropertyfunction defineReactive (data, key, val) { // 每次設(shè)置訪問器前都先驗(yàn)證值是否為對(duì)象,實(shí)現(xiàn)遞歸每個(gè)屬性 observer(val) // 劫持?jǐn)?shù)據(jù)屬性 Object.defineProperty(data, key, {  configurable: true,  enumerable: true,  get () {   return val  },  set (newVal) {   if (newVal === val) {    return   } else {    data[key] = newVal    // 新值也要劫持    observer(newVal)   }  } })}// 遞歸判斷function observer (data) { if (Object.prototype.toString.call(data) === '[object, Object]') {  new Observer(data) } else {  return }}// 監(jiān)聽objobserver(data)            
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 白河县| 邢台市| 嘉禾县| 左贡县| 澎湖县| 九龙城区| 自贡市| 咸阳市| 井冈山市| 萨迦县| 治县。| 同仁县| 贵溪市| 辽中县| 张家港市| 永泰县| 兴文县| 盐山县| 海口市| 贵南县| 玉屏| 明星| 开封市| 舞钢市| 邢台市| 蕲春县| 济南市| 凤庆县| 望城县| 银川市| 宁乡县| 稻城县| 龙岩市| 翁牛特旗| 海南省| 汝城县| 漠河县| 婺源县| 遂溪县| 张家口市| 儋州市|