国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

理解數(shù)據(jù)驅(qū)動(dòng)視圖原理

Lyux / 461人閱讀

摘要:源代碼響應(yīng)式原理數(shù)據(jù)觀察數(shù)據(jù)遞歸無反應(yīng)無反應(yīng)無反應(yīng)包括無反應(yīng)講解只所以能實(shí)現(xiàn)雙向綁定,是利用里面的這就是為什么只支持及以上從以上代碼可以看出,對象屬性的刪除和添加新屬性,不會(huì)觸發(fā)對應(yīng)的方法對于初始化沒有定義的屬性,設(shè)置值不能觸發(fā)視圖層渲染在

源代碼1
// 響應(yīng)式原理 defineProperty
 
//數(shù)據(jù)
const data = {
  obj: {
    a: 4,
    b: 6
  },
  arr: [1, 5, 9]
}
 
// 觀察數(shù)據(jù)
function observe(data) {
  Object.keys(data).forEach(function(key) {
    let value = data[key]
    if (value && typeof value === "object") observe(value) // 遞歸
    Object.defineProperty(data, key, {
      get() {
        console.log(`get ${key}`)
        return value
      },
      set(newVal) {
        console.log(`set ${key} = ${newVal}`)
        if (newVal && typeof newVal === "object") observe(newVal)
        value = newVal
      }
    })
  })
 
}
 
observe(data)
 
let obj = data.obj
// get obj
let arr = data.arr
// get arr
 
 
obj.a = 8
// set a = 8
obj.a
// get a
delete obj.b
// 無反應(yīng)
obj.c = 9
// 無反應(yīng)
obj.c
// 無反應(yīng)
 
data.obj = {...obj, c: 7}
// set obj = [object Object]
obj = data.obj
// get obj
 
obj.c = 9
// set c = 9
obj.c
// get c
 
arr.push(9) // 包括pop,shift,unshift,splice,sort,reverse
// 無反應(yīng)
data.arr = [...arr,9]
// set arr = 1,5,9,9,9
講解

vue只所以能實(shí)現(xiàn)雙向綁定,是利用es5里面的Object.defineProperty(這就是為什么vue只支持es9及以上)

從以上代碼可以看出,對象屬性的刪除(delete obj.b)和添加新屬性(obj.c = 9),不會(huì)觸發(fā)對應(yīng)的set方法(vue對于初始化沒有定義的屬性,設(shè)置值不能觸發(fā)視圖層渲染)

在項(xiàng)目開發(fā)中肯定會(huì)遇到有些屬性,初始化時(shí)沒有定義,通過改變其父元素的值去實(shí)現(xiàn)(data.obj = {...obj, c: 7}),父元素的值改變后,會(huì)觸發(fā)其set方法,會(huì)對其子元素重新進(jìn)行雙向綁定

對于數(shù)組的處理,push,pop,shift,unshift,splice,sort,reverse都不會(huì)觸發(fā)set,但我們看到的vue,這些方法是會(huì)觸發(fā)視圖層的變化,這是因?yàn)関ue針對這些方法做了特殊的處理,原理如

const arr = [5, 9, 8]
const push = Array.prototype.push
Array.prototype.push = function () {
  const result = push.apply(this, arguments)
  console.log("做自己喜歡的事情")
  return result
}
arr.push(7)
console.log(arr)

vue代碼片段

/*
 * not type checking this file because flow doesn"t play well with
 * dynamically accessing methods on Array prototype
 */
 
var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto);[
  "push",
  "pop",
  "shift",
  "unshift",
  "splice",
  "sort",
  "reverse"
]
.forEach(function (method) {
  // cache original method
  var original = arrayProto[method];
  def(arrayMethods, method, function mutator () {
    var args = [], len = arguments.length;
    while ( len-- ) args[ len ] = arguments[ len ];
 
    var result = original.apply(this, args);
    var ob = this.__ob__;
    var inserted;
    switch (method) {
      case "push":
      case "unshift":
        inserted = args;
        break
      case "splice":
        inserted = args.slice(2);
        break
    }
    if (inserted) { ob.observeArray(inserted); }
    // notify change
    ob.dep.notify();
    return result
  });
});
 
/*  */
源代碼2
// 響應(yīng)式原理 defineProperty
 
//數(shù)據(jù)
const data = {
  obj: {
    a: 4,
    b: 6
  },
  arr: [1, 5, 9]
}
function Dep() {}
Dep.target = null // 當(dāng)前函數(shù)
function watcher(fn) { // 函數(shù)
  Dep.target = fn
  fn()
}
 
// 初始化
function init() {
  const a = () => {
    console.log(data.obj.a)
  }
  const mix = () => {
    const c = data.obj.a + data.obj.b
    console.log(c)
  }
  watcher(a)
  watcher(mix)
}
 
// 觀察數(shù)據(jù)
function observe(data) {
  Object.keys(data).forEach(function(key) {
    let value = data[key]
    const dep = [] // 存放函數(shù)的容器
    if (value && typeof value === "object") observe(value) // 遞歸
    Object.defineProperty(data, key, {
      get() {
        dep.push(Dep.target)
        return value
      },
      set(newVal) {
        if (newVal && typeof newVal === "object") observe(newVal)
        value = newVal
        dep.forEach(fn => fn())
      }
    })
  })
 
}
 
observe(data)
init()
 
setTimeout(() => {
  data.obj.a = 10
}, 2000)
講解

以上代碼可以看出,當(dāng)obj.a值變化的時(shí)候,會(huì)觸發(fā)a函數(shù)和mix函數(shù),具體執(zhí)行步驟如下

先將屬性a綁定了對應(yīng)的set和get方法

初始化init()時(shí),會(huì)調(diào)用watcher(a),此時(shí) Dep.target等于a函數(shù)

執(zhí)行a()函數(shù)時(shí),會(huì)執(zhí)行里面的console.log(data.obj.a)

data.obj.a會(huì)調(diào)用a的get方法,此時(shí)dep.push(Dep.target)就相當(dāng)于dep.push(a函數(shù)),mix函數(shù)同理

當(dāng)屬性a的值改變時(shí)(data.obj.a = 10),會(huì)觸發(fā)其set方法,dep.forEach(fn => fn())將a函數(shù)和mix函數(shù)循環(huán)執(zhí)行一遍,從而實(shí)現(xiàn)了數(shù)據(jù)驅(qū)動(dòng)視圖

注意點(diǎn)

在驅(qū)動(dòng)視圖之前都要先賦值,比如源代碼2的(value = newVal)和(dep.forEach(fn => fn()))不能互換位置

以上代碼不是vue的源代碼,但原理是一致的,幫助開發(fā)者更好的理解自己寫的代碼

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107178.html

相關(guān)文章

  • vue總結(jié)系列--數(shù)據(jù)驅(qū)動(dòng)和響應(yīng)式

    摘要:由于是需要兼容的后臺系統(tǒng),該項(xiàng)目并不能使用到等技術(shù),因此我在上的經(jīng)驗(yàn)大都是使用原生的編寫的,可以看見一個(gè)組件分為兩部分視圖部分,和數(shù)據(jù)部分。 在公司里幫項(xiàng)目組里開發(fā)后臺系統(tǒng)的前端項(xiàng)目也有一段時(shí)間了。 vue這種數(shù)據(jù)驅(qū)動(dòng),組件化的框架和react很像,從一開始的快速上手基本的開發(fā),到后來開始自定義組件,對element UI的組件二次封裝以滿足項(xiàng)目需求,期間也是踩了不少坑。由于將來很長一...

    AbnerMing 評論0 收藏0
  • vue的數(shù)據(jù)驅(qū)動(dòng)原理及簡單實(shí)現(xiàn)

    摘要:監(jiān)聽器構(gòu)造函數(shù)被監(jiān)聽數(shù)據(jù)屬性遍歷監(jiān)聽函數(shù)屬性被監(jiān)聽了,現(xiàn)在值為監(jiān)聽器被監(jiān)聽對象構(gòu)造函數(shù)所有入?yún)⒈O(jiān)聽數(shù)據(jù)更新視圖實(shí)現(xiàn)在流程介紹中,我們需要?jiǎng)?chuàng)建一個(gè)可以訂閱者的訂閱器,主要負(fù)責(zé)手機(jī)訂閱者,屬性變化的時(shí)候執(zhí)行相應(yīng)的訂閱者,更新函數(shù)。 1、目標(biāo)實(shí)現(xiàn) 理解雙向數(shù)據(jù)綁定原理; 實(shí)現(xiàn){{}}、v-model和基本事件指令v-bind(:)、v-on(@); 新增屬性的雙向綁定處理; PS:實(shí)例源...

    caoym 評論0 收藏0
  • 開源中國專訪:Chameleon原理首發(fā),其它跨多端統(tǒng)一框架都是假的?

    摘要:中國互聯(lián)網(wǎng)絡(luò)信息中心發(fā)布的中國互聯(lián)網(wǎng)絡(luò)發(fā)展?fàn)顩r統(tǒng)計(jì)報(bào)告顯示,截至年月,我國網(wǎng)民規(guī)模達(dá)億人,微信月活億支付寶月活億百度月活億另一方面,中國手機(jī)占智能手機(jī)整體的比例超過,月活約億。在年末正式發(fā)布了面向未來的跨端的。 開源中國專訪:Chameleon原理首發(fā),其它跨多端統(tǒng)一框架都是假的? 原創(chuàng): 嘉賓-張楠 開源中國 以往我們說某一功能跨多端,往往是指在諸如 PC、移動(dòng)等不同類型的設(shè)備之...

    GraphQuery 評論0 收藏0
  • MVVM框架理解及其原理實(shí)現(xiàn)

    摘要:小白一枚,一直使用的是,想要多了解一些其它的框架,正好最近越來越火熱,上的數(shù)已經(jīng)超過了。框架理解說起這個(gè)模型,就不得不說框架。函數(shù)表示創(chuàng)建一個(gè)文本節(jié)點(diǎn),函數(shù)表示創(chuàng)建一個(gè)數(shù)組。 小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越來越火熱,Github上的Star數(shù)已經(jīng)超過了React。而其背后蘊(yùn)含的MVVM框架思想也一直跟React的組件化開發(fā)思想并駕齊驅(qū),在這...

    DevWiki 評論0 收藏0
  • 給研發(fā)工程師的代碼質(zhì)量利器 | SOFAChannel#5 直播整理

    摘要:接入分為兩部分,其一是可視化編輯器,在官網(wǎng)上我們可以獲取該編輯器的安裝包,并通過的插件管理進(jìn)行安裝。借助可視化編輯器,在整個(gè)過程中我們可以替換大部分手工編寫代碼的工作,進(jìn)行一站式操作。,有趣實(shí)用的分布式架構(gòu)頻道。本文根據(jù) SOFAChannel#5 直播分享整理,主題:給研發(fā)工程師的代碼質(zhì)量利器 —— 自動(dòng)化測試框架 SOFAActs。回顧視頻以及 PPT 查看地址見文末。歡迎加入直播互動(dòng)釘...

    ivan_qhz 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<