日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

局部钩子能防全局钩子吗_Vue你真的熟吗?来回答这几个问题试试

發布時間:2024/10/5 vue 91 豆豆
生活随笔 收集整理的這篇文章主要介紹了 局部钩子能防全局钩子吗_Vue你真的熟吗?来回答这几个问题试试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

這個面向中高級Web前端的面經系列文章,到此便接近尾聲了。是不是還有繼續出,這個要看接下來的時間安排了。

小團體有個朋友說,他準備更新一些android-kotlin從入門到上手寫業務的文章。所以關注我的Web前端的朋友們,不著急,先休息休息,消化消化之前的文章,提前預祝跳槽的朋友,有個好東家~!

本系列文章鏈接如下:

“金三銀四”,讓我們愉快的開始準備Web面經吧:CSS篇

“金三銀四”,讓我們愉快的開始準備Web面經吧:JavaScript-上

中高端Web前端面試題,直擊BAT:JavaScript篇

元宵節,猿宵節,寫代碼之余面經走一波:JavaScript篇

通往中高端Web前端:瀏覽器篇

正文

1. nextTick

在下次dom更新循環結束之后執行延遲回調,可用于獲取更新后的dom狀態

  • 新版本中默認是mincrotasks, v-on中會使用macrotasks
  • macrotasks任務的實現:
  • setImmediate / MessageChannel / setTimeout

2. 生命周期

  • _init_
  • initLifecycle/Event,往vm上掛載各種屬性
  • callHook: beforeCreated: 實例剛創建
  • initInjection/initState: 初始化注入和 data 響應性
  • created: 創建完成,屬性已經綁定, 但還未生成真實dom
  • 進行元素的掛載: $el / vm.$mount()
  • 是否有template: 解析成render function*.vue文件: vue-loader會將編譯成render function
  • beforeMount: 模板編譯/掛載之前
  • 執行render function,生成真實的dom,并替換到dom tree中
  • mounted: 組件已掛載
  • update:
  • 執行diff算法,比對改變是否需要觸發UI更新
  • flushScheduleQueuewatcher.before: 觸發beforeUpdate鉤子 - watcher.run(): 執行watcher中的 notify,通知所有依賴項更新UI
  • 觸發updated鉤子: 組件已更新
  • actived / deactivated(keep-alive): 不銷毀,緩存,組件激活與失活
  • destroy:
  • beforeDestroy: 銷毀開始
  • 銷毀自身且遞歸銷毀子組件以及事件監聽
  • remove(): 刪除節點
  • watcher.teardown(): 清空依賴
  • vm.$off(): 解綁監聽
  • destroyed: 完成后觸發鉤子

上面是vue的聲明周期的簡單梳理,接下來我們直接以代碼的形式來完成vue的初始化

new Vue({})// 初始化Vue實例function _init() { // 掛載屬性 initLifeCycle(vm) // 初始化事件系統,鉤子函數等 initEvent(vm) // 編譯slot、vnode initRender(vm) // 觸發鉤子 callHook(vm, 'beforeCreate') // 添加inject功能 initInjection(vm) // 完成數據響應性 props/data/watch/computed/methods initState(vm) // 添加 provide 功能 initProvide(vm) // 觸發鉤子 callHook(vm, 'created') // 掛載節點 if (vm.$options.el) { vm.$mount(vm.$options.el) }}// 掛載節點實現function mountComponent(vm) { // 獲取 render function if (!this.options.render) { // template to render // Vue.compile = compileToFunctions let { render } = compileToFunctions() this.options.render = render } // 觸發鉤子 callHook('beforeMounte') // 初始化觀察者 // render 渲染 vdom, vdom = vm.render() // update: 根據 diff 出的 patchs 掛載成真實的 dom vm._update(vdom) // 觸發鉤子 callHook(vm, 'mounted')}// 更新節點實現funtion queueWatcher(watcher) {nextTick(flushScheduleQueue)}// 清空隊列function flushScheduleQueue() { // 遍歷隊列中所有修改 for(){ // beforeUpdate watcher.before() // 依賴局部更新節點 watcher.update() callHook('updated') }}// 銷毀實例實現Vue.prototype.$destory = function() { // 觸發鉤子 callHook(vm, 'beforeDestory') // 自身及子節點 remove() // 刪除依賴 watcher.teardown() // 刪除監聽 vm.$off() // 觸發鉤子 callHook(vm, 'destoryed')}

3. 數據響應(數據劫持)

看完生命周期后,里面的watcher等內容其實是數據響應中的一部分。數據響應的實現由兩部分構成: 觀察者( watcher )依賴收集器( Dep ),其核心是 defineProperty這個方法,它可以 重寫屬性的 get 與 set 方法,從而完成監聽數據的改變。

  • Observe (觀察者)觀察 props 與 state
  • 遍歷 props 與 state,對每個屬性創建獨立的監聽器( watcher )
  • 使用 defineProperty 重寫每個屬性的 get/set(defineReactive)
  • get: 收集依賴
  • Dep.depend()watcher.addDep()
  • set: 派發更新
  • Dep.notify()
  • watcher.update()
  • queenWatcher()
  • nextTick
  • flushScheduleQueue
  • watcher.run()
  • updateComponent()

大家可以先看下面的數據相應的代碼實現后,理解后就比較容易看懂上面的簡單脈絡了。

let data = {a: 1}// 數據響應性observe(data)// 初始化觀察者new Watcher(data, 'name', updateComponent)data.a = 2// 簡單表示用于數據更新后的操作function updateComponent() { vm._update() // patchs}// 監視對象function observe(obj) { // 遍歷對象,使用 get/set 重新定義對象的每個屬性值 Object.keys(obj).map(key => { defineReactive(obj, key, obj[key]) })}function defineReactive(obj, k, v) { // 遞歸子屬性 if (type(v) == 'object') observe(v) // 新建依賴收集器 let dep = new Dep() // 定義get/set Object.defineProperty(obj, k, { enumerable: true, configurable: true, get: function reactiveGetter() { // 當有獲取該屬性時,證明依賴于該對象,因此被添加進收集器中 if (Dep.target) { dep.addSub(Dep.target) } return v }, // 重新設置值時,觸發收集器的通知機制 set: function reactiveSetter(nV) { v = nV dep.nofify() }, })}// 依賴收集器class Dep { constructor() { this.subs = [] } addSub(sub) { this.subs.push(sub) } notify() { this.subs.map(sub => { sub.update() }) }}Dep.target = null// 觀察者class Watcher { constructor(obj, key, cb) { Dep.target = this this.cb = cb this.obj = obj this.key = key this.value = obj[key] Dep.target = null } addDep(Dep) { Dep.addSub(this) } update() { this.value = this.obj[this.key] this.cb(this.value) } before() { callHook('beforeUpdate') }}

尾聲

汗--!沒想到才寫一半就這么多內容了,為了閱讀體驗,決定分上下倆部分發。后續文章可以關注我,翻看歷史文章~

總結

以上是生活随笔為你收集整理的局部钩子能防全局钩子吗_Vue你真的熟吗?来回答这几个问题试试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。