中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

seo排名技術(shù)教程seo排名軟件價格

seo排名技術(shù)教程,seo排名軟件價格,wordpress hook大全,建設(shè)淘寶網(wǎng)站的目的監(jiān)聽屬性watch 監(jiān)聽屬性介紹 我們可以使用 watch 函數(shù)在每次響應(yīng)式狀態(tài)發(fā)生變化時觸發(fā)回調(diào)函數(shù)wach 可以用于異步任務(wù) 監(jiān)聽屬性的初始化 watch和computed都先走initSate判斷傳入選項 export function initState(vm) {const opts vm.$options; // 獲取所有的選項if (opts.…

監(jiān)聽屬性watch

監(jiān)聽屬性介紹

我們可以使用 watch 函數(shù)在每次響應(yīng)式狀態(tài)發(fā)生變化時觸發(fā)回調(diào)函數(shù)wach 可以用于異步任務(wù)

監(jiān)聽屬性的初始化

watch和computed都先走initSate判斷傳入選項

export function initState(vm) {const opts = vm.$options; // 獲取所有的選項if (opts.data) {initData(vm);}if (opts.computed) {initComputed(vm);}if (opts.watch) {initWatch(vm);}
}

接下來initWatch進(jìn)入此函數(shù)

function initWatch(vm){let watch = vm.$options.watch;for(let key in watch){const handler = watch[key]; // 字符串 數(shù)組 函數(shù)if(Array.isArray(handler)){for(let i = 0; i < handler.length;i++){createWatcher(vm,key,handler[i]);}}else{createWatcher(vm,key,handler);}}}

通過原型方法$watch傳入處理參數(shù)創(chuàng)建一個觀察者收集依賴變化。

function createWatcher(vm,key,handler){// 字符串  函數(shù)if(typeof handler === 'string'){handler = vm[handler];}return vm.$watch(key,handler)
}

原型上的$watch函數(shù)

export function initStateMixin(Vue) {Vue.prototype.$nextTick = nextTick;// 最終調(diào)用的都是這個方法Vue.prototype.$watch = function (exprOrFn, cb) {// firstname// ()=>vm.firstname// firstname的值變化了 直接執(zhí)行cb函數(shù)即可new Watcher(this, exprOrFn, { user: true }, cb)}
}

計算屬性computed

計算屬性介紹

計算屬性是在 Vue 實例的computed選項中定義的,可以是一個函數(shù)或具有g(shù)et和set方法的對象。函數(shù)形式的計算屬性會在調(diào)用時被執(zhí)行,而對象形式的計算屬性則可以提供自定義的get和set方法
計算屬性適用于那些依賴其他響應(yīng)式數(shù)據(jù)的場景,而不適用于需要進(jìn)行異步操作或有副作用的場景。對于這些情況,可以使用偵聽器(watcher)或使用methods來處理。

計算屬性實現(xiàn)過程

計算屬性的初始化

1 在initComputed函數(shù)中,遍歷計算屬性對象,為每個計算屬性創(chuàng)建一個Watcher實例,并將其存儲在vm._computedWatchers中。

export function initState(vm) {const opts = vm.$options; // 獲取所有的選項if (opts.data) {initData(vm);}if (opts.computed) {initComputed(vm);}if (opts.watch) {initWatch(vm);}
}
function initComputed(vm) {const computed = vm.$options.computed;const watchers = vm._computedWatchers = {}; // 將計算屬性watcher保存到vm上for (let key in computed) {//獲取用戶定義的計算屬性let userDef = computed[key];// 我們需要監(jiān)控 計算屬性中g(shù)et的變化let fn = typeof userDef === 'function' ? userDef : userDef.get// 如果直接new Watcher 默認(rèn)就會執(zhí)行fn, 將屬性和watcher對應(yīng)起來 watchers[key] = new Watcher(vm, fn, { lazy: true })defineComputed(vm, key, userDef);}
}
屬性劫持

2 defineComputed 方法主要是重新定義計算屬性,其實最主要的是劫持get方法。
為啥要劫持呢? 因為我們需要根據(jù)依賴值是否發(fā)生變化來判斷計算屬性是否需要重新計算

function defineComputed(target, key, userDef) {// const getter = typeof userDef === 'function' ? userDef : userDef.get;const setter = userDef.set || (() => { })// 可以通過實例拿到對應(yīng)的屬性Object.defineProperty(target, key, {get: createComputedGetter(key),set: setter})
}

3 createComputedGetter判斷計算屬性的值是否變化 增加dirty
如果是true執(zhí)行更新

// 計算屬性根本不會收集依賴 ,只會讓自己的依賴屬性去收集依賴
function createComputedGetter(key) {// 我們需要檢測是否要執(zhí)行這個getterreturn function () {const watcher = this._computedWatchers[key]; // 獲取到對應(yīng)屬性的watcherif (watcher.dirty) {// 如果是臟的就去執(zhí)行 用戶傳入的函數(shù)watcher.evaluate(); // 求值后 dirty變?yōu)榱薴alse ,下次就不求值了}if (Dep.target) { // 計算屬性出棧后 還要渲染watcher, 我應(yīng)該讓計算屬性watcher里面的屬性 也去收集上一層watcherwatcher.depend();//計算屬性watcher收集渲染watcher}return watcher.value; // 最后返回的是watcher上的值}
}

watcher
新增了dirty屬性 標(biāo)識是否需要更新視圖
增加了evaluate方法 重新渲染 并且將dirty變成true

// src/observer/watcher.js// import { pushTarget, popTarget } from "./dep";
// import { queueWatcher } from "./scheduler";
// import {isObject} from '../util/index'
// // 全局變量id  每次new Watcher都會自增
// let id = 0;export default class Watcher {constructor(vm, exprOrFn, cb, options) {// this.vm = vm;// this.exprOrFn = exprOrFn;// this.cb = cb; //回調(diào)函數(shù) 比如在watcher更新之前可以執(zhí)行beforeUpdate方法// this.options = options; //額外的選項 true代表渲染watcher// this.id = id++; // watcher的唯一標(biāo)識// this.deps = []; //存放dep的容器// this.depsId = new Set(); //用來去重dep// this.user = options.user; //標(biāo)識用戶watcherthis.lazy = options.lazy; //標(biāo)識計算屬性watcherthis.dirty = this.lazy; //dirty可變  表示計算watcher是否需要重新計算 默認(rèn)值是true// 如果表達(dá)式是一個函數(shù)// if (typeof exprOrFn === "function") {//   this.getter = exprOrFn;// } else {//   this.getter = function () {//     //用戶watcher傳過來的可能是一個字符串   類似a.a.a.a.b//     let path = exprOrFn.split(".");//     let obj = vm;//     for (let i = 0; i < path.length; i++) {//       obj = obj[path[i]]; //vm.a.a.a.a.b//     }//     return obj;//   };// }// 非計算屬性實例化就會默認(rèn)調(diào)用get方法 進(jìn)行取值  保留結(jié)果 計算屬性實例化的時候不會去調(diào)用getthis.value = this.lazy ? undefined : this.get();}get() {pushTarget(this); // 在調(diào)用方法之前先把當(dāng)前watcher實例推到全局Dep.target上const res = this.getter.call(this.vm); //計算屬性在這里執(zhí)行用戶定義的get函數(shù) 訪問計算屬性的依賴項 從而把自身計算Watcher添加到依賴項dep里面收集起來popTarget(); // 在調(diào)用方法之后把當(dāng)前watcher實例從全局Dep.target移除return res;}//   把dep放到deps里面 同時保證同一個dep只被保存到watcher一次  同樣的  同一個watcher也只會保存在dep一次//   addDep(dep) {//     let id = dep.id;//     if (!this.depsId.has(id)) {//       this.depsId.add(id);//       this.deps.push(dep);//       //   直接調(diào)用dep的addSub方法  把自己--watcher實例添加到dep的subs容器里面//       dep.addSub(this);//     }//   }//   這里簡單的就執(zhí)行以下get方法  之后涉及到計算屬性就不一樣了update() {// 計算屬性依賴的值發(fā)生變化 只需要把dirty置為true  下次訪問到了重新計算if (this.lazy) {this.dirty = true;} else {// 每次watcher進(jìn)行更新的時候  可以讓他們先緩存起來  之后再一起調(diào)用// 異步隊列機(jī)制queueWatcher(this);}}//   計算屬性重新進(jìn)行計算 并且計算完成把dirty置為falseevaluate() {this.value = this.get();this.dirty = false;}depend() {// 計算屬性的watcher存儲了依賴項的deplet i = this.deps.length;while (i--) {this.deps[i].depend(); //調(diào)用依賴項的dep去收集渲染watcher}}//   run() {//     const newVal = this.get(); //新值//     const oldVal = this.value; //老值//     this.value = newVal; //跟著之后  老值就成為了現(xiàn)在的值//     if (this.user) {//       if(newVal!==oldVal||isObject(newVal)){//         this.cb.call(this.vm, newVal, oldVal);//       }//     } else {//       // 渲染watcher//       this.cb.call(this.vm);//     }//   }
}

computed和watch的區(qū)別

**相同點:**底層都會創(chuàng)建一個watcher computed定義的屬性可以在模板中使用 watch不能在視圖中國使用
不同點: computed不會默認(rèn)執(zhí)行 只有取值會執(zhí)行 內(nèi)部會以一個dirty屬性控制依賴的值是否變化
watch默認(rèn)用戶會提供一個回調(diào)函數(shù) 數(shù)據(jù)變化就使用用戶傳入的回調(diào)
本周總結(jié)
vue2手寫部分學(xué)習(xí)完了 其實感覺收集依賴那一部分還是有點繞 后續(xù)應(yīng)該會多看點別人總結(jié)的內(nèi)容對著自己代碼復(fù)習(xí)復(fù)習(xí)也學(xué)習(xí)了基礎(chǔ)的webpack
下周主要還是學(xué)習(xí)一下源碼 復(fù)習(xí)一下js高級啥的

http://www.risenshineclean.com/news/51767.html

相關(guān)文章:

  • 做網(wǎng)站好的網(wǎng)站建設(shè)公司排名青島百度推廣優(yōu)化怎么做的
  • 網(wǎng)站域名查詢地址做百度推廣銷售怎么找客戶
  • 中山市小欖新意網(wǎng)站設(shè)計有限公司太原網(wǎng)站建設(shè)制作
  • wordpress geogebraseo刷排名工具
  • 做本地網(wǎng)站需要的軟件網(wǎng)盤資源共享群吧
  • 淘寶上做網(wǎng)站排名的是真的嗎口碑營銷案例2022
  • 前程無憂怎么做網(wǎng)站百度識圖識別
  • 合肥高端網(wǎng)站建設(shè)公司哪家好seo優(yōu)化軟件大全
  • 企業(yè)網(wǎng)站建設(shè)相關(guān)書籍windows優(yōu)化大師卸載
  • 公司怎么申請免費做網(wǎng)站好用的搜索引擎
  • 龍元建設(shè)網(wǎng)站鄭州網(wǎng)絡(luò)營銷
  • 怎樣進(jìn)入建設(shè)通網(wǎng)站怎樣做網(wǎng)站
  • 可以做展示頁面的網(wǎng)站seo推廣優(yōu)化公司哪家好
  • wordpress前臺打開慢手機(jī)端關(guān)鍵詞排名優(yōu)化軟件
  • 杭州手機(jī)軟件開發(fā)公司上海網(wǎng)站seo策劃
  • 網(wǎng)站如何做公安部備案整站優(yōu)化全網(wǎng)營銷
  • 瑞金網(wǎng)站建設(shè)互聯(lián)網(wǎng)營銷工具有哪些
  • 自己有服務(wù)器如何建設(shè)微網(wǎng)站上海疫情最新數(shù)據(jù)
  • 手機(jī)網(wǎng)站做指向谷歌搜索為什么用不了
  • 做團(tuán)購網(wǎng)站需要多少錢seo優(yōu)化排名軟件
  • 招工 最新招聘信息怎么寫seo搜索引擎優(yōu)化教程
  • 看電影電視劇的好網(wǎng)站纖纖影院優(yōu)化網(wǎng)站服務(wù)
  • 網(wǎng)站備案難嗎批量查詢指數(shù)
  • 長沙網(wǎng)站建設(shè)公司排行榜百度信息流推廣技巧
  • 漂亮公司網(wǎng)站源碼打包下載seo自動刷外鏈工具
  • 專業(yè)濟(jì)南網(wǎng)站建設(shè)價格人民網(wǎng) 疫情
  • 合肥做網(wǎng)站多少錢哪里可以學(xué)企業(yè)管理培訓(xùn)
  • 蚌埠網(wǎng)站制作哪家好沈陽seo
  • wordpress兩種語言主題鄭州seo顧問熱狗
  • 電子商務(wù)網(wǎng)站建設(shè)題6百度一下搜索