<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                >[success] # Vue 響應式 1. 下面正常的js邏輯代碼是否能像`vue`一樣,當`price `發生改變期待著`total `也可以重新計算,但實際結果卻是打印出來的結果為`10 `而不是`12` 2. 因此可以看出`JavaScript`是程序性的,**不是反應性**的,為了使total反應性,我們必須使用`JavaScript`使事物表現不同 ~~~ let price = 5 let quantity = 2 let total = price * quantity price++ console.log(`total is ${total}`) // 10 ~~~ >[danger] ##### 讓數據具備響應收集 1. 想讓代碼開始變成**反應性**,據需要在想讓觸發的節點重新運行指定邏輯代碼,我們先收集在觸發 2. 我們將收集和觸發函數命名為`watchFn`,在指定位置觸發 ~~~ const reactiveFns = [] function watchFn(fn) { reactiveFns.push(fn) // 收集后進行觸發 fn() } // 統一觸發所有收集 function replay() { reactiveFns.forEach((run) => run()) } let price = 5 let quantity = 2 let total = 0 watchFn(() => { total = price * quantity }) price++ // 每次執行完都要觸發一下 replay() console.log(total) // 可以得到觸發后值 ~~~ >[danger] ##### 收集更多數據怎么辦 1. 在實際開發中,會有更多數據需要被收集觸發,如果只是單純的使用數組收集差生問題,下面案例產生問題**觸發將不希望改變的name 也被觸發** ~~~ const reactiveFns = [] function watchFn(fn) { reactiveFns.push(fn) // 收集后進行觸發 fn() } // 統一觸發所有收集 function replay() { reactiveFns.forEach((run) => run()) } let name = 'w' // 收集名字變化 watchFn(() => { name += '1' }) let price = 5 let quantity = 2 let total = 0 watchFn(() => { total = price * quantity }) price++ // 每次執行完都要觸發一下,這次觸發將不希望改變的name 也被觸發 replay() console.log(total) // 可以得到觸發后值 ~~~ 2. 為每一個對象創建一個屬于自己的收集對象這樣,就不會相互忽然,創建一個 `Depend` 類,用來收集各自的響應觸發 3. 讓數據可以更加自由的觸發對象的變化可以使用兩種方案`Object.defineProperty`或`new Proxy`,代碼思路是我們將每個需要響應式的數據定義屬于自己的收集,觸發時候觸發屬于自己的收集響應的方法 ~~~ // 屬于每個對象自己的收集 class Depend { constructor() { this.reactiveFns = [] } addDepend(fn) { if (fn) { this.reactiveFns.push(fn) } } notify() { this.reactiveFns.forEach((fn) => { fn() }) } } // 設置一個專門執行響應式函數的一個函數 function watchFn(fn, dep) { dep.addDepend(fn) fn() } const info = { name: 'w', age: 18 } const bookInfo = { name: '語文', price: 125 } const InfoDep = new Depend() const bookDep = new Depend() // 使用Object.defineProperty 收集 function proxy(obj, dep) { Object.keys(obj).forEach((key) => { let value = obj[key] Object.defineProperty(obj, key, { set: function (newValue) { value = newValue // 進行設置值的時候進行觸發收集 dep.notify() }, get: function () { return value }, }) }) } watchFn(() => { console.log(`info 信息收集`) }, InfoDep) proxy(info, InfoDep) watchFn(() => { console.log(`bookInfo 信息收集`) }, bookDep) proxy(bookInfo, bookDep) console.log('---------------') info.age++ bookInfo.price++ ~~~ >[danger] ##### 自定義收集依賴 1. 對象會有多個屬性,不同屬性可能需要的是不同的收集響應,因此需要一個新的收集數據解構 `{對象:{屬性:Depend},對象:{屬性:Depend]}}`對象能做為`key`需要使用`WeakMap` 2. `getDepend` 作為一個自動收集和使用響應的方法,主要是將數據可以存儲在`WeakMap` 解構,并將每一個屬性`key `都可以對應 屬于自己`Depend` 3. `Object.defineProperty` 進行收集當觸發`get` 時候進行收集,`set` 時候進行觸發 4. `watchFn` 用來觸發第一次響應,和給響應事件賦值,這里將`target ` 作為全局變量,當觸發`watchFn` 收集的時候必須要觸發一次收集對象對應屬性的` get`,此時觸發對應屬性`get`后并且將對應屬性響應方法收集(因為是全局定義所以方便收集),觸發后`watchFn` 再將`target `置為`null` 等待下一次觸發 ~~~ // 屬于每個對象自己的收集 class Depend { constructor() { this.reactiveFns = [] } addDepend(fn) { if (fn) { this.reactiveFns.push(fn) } } notify() { this.reactiveFns.forEach((fn) => { fn() }) } } // 收集響應式數據解構 const objMap = new WeakMap() // 定義一個收集方法 function getDepend(obj, key) { // 判斷響應式中是否收集了 對象所對應key let map = objMap.get(obj) if (!map) { // 不存在 就創建一個{對象: Map} map = new Map() objMap.set(obj, map) } // 判斷對象key 是否已經創建響應收集 const getDep = map.get(key) if (!getDep) { const dep = new Depend() // 收集key依賴 和dep map.set(key, dep) } // 將對應key 收集的依賴返回 return map.get(key) } let target = null // 設置一個專門執行響應式函數的一個函數 function watchFn(fn) { target = fn fn() target = null } function proxy(obj) { Object.keys(obj).forEach((key) => { let value = obj[key] Object.defineProperty(obj, key, { get() { // 觸發get 時候要收集響應依賴 const dep = getDepend(obj, key) // 將依賴收集 dep.addDepend(target) return value }, set(nvalue) { // 觸發依賴 value = nvalue const dep = getDepend(obj, key) dep.notify() }, }) }) } const info = { name: 'w', age: 18 } proxy(info) watchFn(function foo() { console.log('foo function') console.log('foo:', info.name) console.log('foo', info.age) }) watchFn(function bar() { console.log('bar function') console.log('bar:', info.age + 10) }) console.log('age發生變化-----------------------') info.age = 20 ~~~ * 如果我們將`proxy` 定義的名字改為`reactive`,將里面的`Object.defineProperty` 換成 `new Proxy` 就是vue3的一個模型 ~~~ // 封裝一個函數: 負責通過obj的key獲取對應的Depend對象 const objMap = new WeakMap() function getDepend(obj, key) { // 1.根據對象obj, 找到對應的map對象 let map = objMap.get(obj) if (!map) { map = new Map() objMap.set(obj, map) } // 2.根據key, 找到對應的depend對象 let dep = map.get(key) if (!dep) { dep = new Depend() map.set(key, dep) } return dep } function reactive(obj) { const objProxy = new Proxy(obj, { set: function(target, key, newValue, receiver) { // target[key] = newValue Reflect.set(target, key, newValue, receiver) const dep = getDepend(target, key) dep.notify() }, get: function(target, key, receiver) { const dep = getDepend(target, key) dep.depend() return Reflect.get(target, key, receiver) } }) return objProxy } // ========================= 業務代碼 ======================== const obj = reactive({ age: 18, address: "廣州市" }) watchFn(function() { console.log(obj.name) console.log(obj.age) console.log(obj.age) }) // 修改name console.log("--------------") obj.age = 20 console.log("=============== user =================") const user = reactive({ nickname: "abc", level: 100 }) watchFn(function() { console.log("nickname:", user.nickname) console.log("level:", user.level) }) user.nickname = "cba" ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看