vue process.env獲取不到_從文檔開始,重學vue(下)源碼級別

769fc93b1af1581bf13a45875ea68617.png

此篇文章主要是從應用及源碼層面講解vue部分常用api,閱讀起來可能略有難度,新手可以看《從文檔開始,重學vue(上)》

示例代碼均在vue-cli3中完成

Vue.extend()

可以使用 extend 創建一個子類,該方法通常用于構建全局組件,如彈框組件等,下面我們就用它來制作個全局alert組件吧

  1. 首先我們需要一個alert.vue組件,組件很簡單就接受一個參數,然后有兩個控制顯示隱藏的方法58907b6711c7acc75c27507b839b991b.png
  2. 需要把alert掛載到body 注意extend的使用方式bdacb91c3a4d0943b6d0c11176329728.png
  3. 使用

使用之前別忘了在main.jsuse一下

import Alert from "./components/Alert/create";Vue.use(Alert)

用起來也非常方便,如下:

mounted(){	this.$alert('公眾號,碼不停息')}

上面我們使用extend直接給他傳了個組件進去,其實我們也可以給extend的配置對象,如下:

Vue.extend({ template: "{{msg}}", data() {   return {     msg: "碼不停息"   }; }});

下面我們通過源碼來看看在vue內部extend都做了哪些事情,關鍵性代碼已經加上注釋0fb0646812d4dbdbe4b2cdee89e56d34.png主要做的事情就是把通過extend掛載的組件初始化,并完善里面的options最后返回組件

Vue.nextTick()

如果想理解清楚nextTick,需要我們了解vue異步隊列javascript(確切的說是瀏覽器)的事件循環機制

  • vue異步更新隊列
  • 事件循環機制

可能你還沒有注意到,Vue 在更新 DOM 時是異步執行的。只要偵聽到數據變化,Vue 將開啟一個隊列,并緩沖在同一事件循環中發生的所有數據變更。如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。這種在緩沖時去除重復數據對于避免不必要的計算和 DOM 操作是非常重要的。然后,在下一個的事件循環“tick”中,Vue 刷新隊列并執行實際 (已去重的) 工作。Vue 在內部對異步隊列嘗試使用原生的 Promise.then、MutationObserver 和 setImmediate,如果執行環境不支持,則會采用 setTimeout(fn, 0) 代替(Vue官網)

可以簡單的總結為Vue實現響應式并不是數據發生變化之后 DOM 立即變化,而是按一定的策略進行 DOM 的更新,他的策略就是同一事件循環中的所有數據變化完成之后,再統一進行視圖更新,如果在這個過程中想要操作dom就比較棘手了,而Vue.nextTick就是來解決這樣的問題,如下:

  
{{ time }}
export default { data() { return { time: "" }; }, methods: { getDom() { return document.getElementById("time").innerHTML; } }, mounted() { this.time = new Date().toLocaleTimeString(); console.log("獲取time", this.getDom()); //獲取不到 this.$nextTick(() => { console.log("獲取time", this.getDom()); //可以獲取到 }); }};
6b91a6dec1082b3924e8f06479354565.png

可以看到,當我們給time賦值后直接通過原生dom獲取值是獲取不到的,而用this.$nextTick(callback)就可以獲取到了,那nextTick在內部做了什么呢?我們找到相應的源碼68bf2e1088a6eb9cddc06446222d537e.png可以看出,當我們在代碼中執行$nextTick方法時,內部是調用了nextTick,那我們再來看看nextTick方法里面都有什么?066a48ab184cd3d0151702b8fb0343cf.png原來nextTick方法把我們傳的函數都push到了一個callback數組里,那這個數組是什么時候執行呢?為了方便看,我把相關代碼都復制出來如下:f634f3d9c35b09d18d48703b716bd485.png代碼較長,可以放大觀看,關鍵代碼已給出注釋,主要邏輯如下:

用戶調用$nextTick(callback) -> 把用戶傳入函數push到callback數組 -> 檢測當前平臺環境決定使用哪種方式處理異步 -> 執行flushCallbacks函數 -> flushCallbacks中循環執行callback

因為微任務會在當前宏任務執行完畢后立即執行,這樣就能保證在執行$nextTick()的時候,當前宏任務(包括頁面渲染)已經執行完畢

Vue.set()

Vue.set()設置的值是響應式,當我們需要對 復雜數據類型 新增屬性和值,同時需要新增的值是 響應式 的時候就需要使用該api 如下所示:

  1. 直接給對象賦一個新的屬性和新值
  
公眾號: {{ userInfo.name }}
作者:{{ userInfo.author || "暫無數據" }}
export default { data() { return { userInfo: { name: "碼不停息" } }; }, methods: {}, mounted() { this.userInfo.author = "劉小灰"; // 注意 userInfo開始沒有author屬性 }};

渲染結果如下, 數據沒有出來,新增的author不是響應式72e9b6865d1bc340343cc2b8e67962d8.png

  1. 我們再用Vue.set()給對象賦一個新的屬性和新值
  
公眾號: {{ userInfo.name }}
作者:{{ userInfo.author || "暫無數據" }}
export default { data() { return { userInfo: { name: "碼不停息" } }; }, methods: {}, mounted() { this.$set(this.userInfo, "author", "劉小灰"); //使用set賦值 }};

再看看結果,新增的author是響應式63871c1363c916fe203510106b838183.png

除了基本使用,我們來思考下Vue為什么要設置這個api,為什么直接通過.語法添加的屬性就不是響應式的呢? 使用this.$set()是有如何做到響應式的呢?

我們來源碼中找答案

簡單了解下響應式

響應式的具體表現是當我們把data中的屬性和頁面綁定后,改變data中的數據后,頁面會自動更新,那Vue是如何實現響應式的呢?

不難得出在vue2.x中是使用Object.defineProperty對數據進行劫持來實現響應式,當我們初始化的時候,會把每一個數據都進行依賴收集,內部主要是通過遍歷及遞歸來實現,如下(關鍵代碼已給出注釋):2082a28efd71ed0d567440950f12c7f3.png下面我們來看看核心方法defineReactive都干了什么事情(關鍵代碼已給出注釋)288e695bfa4fce4632cc3886978d3520.png

大體流程

初始化 -> 執行Observer -> 如果是數組特殊處理,否則遍歷子 -> 執行walk -> defineReactive進行響應式處理,如果數據中對象嵌套,遞歸之,否則進行依賴收集,確保全部數據都經過Object.defineProperty的洗禮 -> 響應式處理完畢

這時問題來了, 如果你在代碼中給某個對象通過.語法新加個屬性,這個時候初始化過程早已結束,新加的屬性并沒有經過Object.defineProperty的洗禮,自然不會變成響應式數據,這個時候我們就需要使用Vue.set()方法,讓數據變成響應式,那set中是如何做的呢?其實就是重新調了下Object.definePropertyset方法進行依賴收集即可

關于Vue是如何對數組進行特殊處理的,可以看Object.defineProperty是如何實現對數組的監聽

Vue.use()

安裝 Vue 插件使用,use的源碼比較短我們直接看源碼:如下(關鍵代碼已給出注釋)984bed7df7e54bb100027e4be308c692.png所以在我們平常使用時,我們有兩種使用方式

方式一:Vue.use({	install(vue){        }})方式二:Vue.use((vue)=>{})

無論是哪種方式,Vue都會把vue實例在回調中返回回來供我們使用

最后

最后我想說說為什么我們要學習源碼,我覺得源碼能不能學透并不重要(當然,如果你可以把源碼徹底看懂也再好不過),對我們大部分人來說,學習源碼最重要的目的是 查漏補缺 ,看大佬們是怎么寫代碼,是怎么組織代碼,而這種能力不是我們多做幾個項目,多發幾個ajax請求能夠得到的,就拿自己來說,看了源碼后我發現自己對函數式編程,對發布訂閱模式掌握的還不是不好,然后自己花些時間再加強下這方面的理解,然后把自己理解到的知識再在看源碼中得以升華,我感覺這是最酷的!

最后的最后

交個朋友吧,關注微信公眾號,拉你進群,和一群志同道合的人學習源碼

5a87909b22a4c6f3ea6b4e2d62d37c52.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446017.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446017.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446017.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Microsoft Visual Studio2019環境下搭建SDL開發環境

參考鏈接 《基于 FFmpeg SDL 的視頻播放器的制作》課程的視頻_雷霄驊的博客-CSDN博客_雷霄驊ffmpeg視頻教程小學期課程資料 - 基于FFmpegSDL的視頻播放器的制作.zip_免費高速下載|百度網盤-分享無限制輔助參考鏈接VS自動鏈接到Windows上隨vcpkg安裝的SDL2庫 | 碼農俱樂部 - G…

不關注公眾號可以獲取openid嗎_微信公眾號粉絲遷移

目錄 [toc] 微信公眾號遷移 正常的公眾號遷移直接通過微信操作就可以,如下圖。但是因為udb數據里面存的是遷移前公眾號的openid以及unionid,需要自行獲取新舊openid以及unionid。 舊的用戶信息要在遷移之前獲取,第三步點擊同意之后就公眾號的接口就調不通…

建筑專業規范大全 2020版_房屋建筑工程現行規范標準目錄匯編(2020版)—建筑電氣...

房屋建筑工程現行規范標準目錄匯編(2020版)建筑電氣規范編號規范名稱GB 50034-2013建筑照明設計標準GB 50052-2009供配電系統設計規范GB 50053-201320kV及以下變電所設計規范GB 50057-2010建筑物防雷設計規范GB 50147-2010電氣裝置安裝工程 高壓電器施工及驗收規范GB 50148-201…

基于Microsoft Visual Studio2019環境編寫ffmpeg視頻解碼代碼

舊代碼 舊代碼使用了很多過時的API,這些API使用后,vs會報編譯器警告 (級別 3) C4996的錯誤即 函數被聲明為已否決 報 C4996的錯誤 // test_ffmpeg.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。 // #define SDL_MAIN_HANDLED …

16進制轉double dotnet_終于把計算機進制弄明白了!

And theres one thing that I need from you我只需要你為我做一-件事Can you come through, through待在我的身邊就好Through, yeah你可以撫慰一切不滿And theres one thing that I need from you你可以過來Can you come through?待在我的身邊嗎-comethruJeremy Zucker進制進制…

FFmpeg源代碼簡單分析-架構圖-解碼

參考鏈接 FFmpeg源代碼結構圖 - 解碼_雷霄驊的博客-CSDN博客_ffmpeg雷霄驊函數背景色 函數在圖中以方框的形式表現出來。不同的背景色標志了該函數不同的作用: 粉紅色背景函數:FFmpeg的API函數。白色背景的函數:FFmpeg的內部函數。黃色背景…

JUnit單元測試筆記

#01 JUnit簡介 1.在項目工程中的Library,add 一個JUnit的Jar包,按需要添加JUnit 3 或 JUnit 4(分為被測試類與測試類較佳)。 2.單元測試是由程序員完成的。 3.Java 5 之前的版本只能 用JUnit 4前的版本(因為JUnit 4用到Java 5的…

jqery獲取每個月天數_三年級《年、月、日》單元重要知識點整理匯總,以及難點題型解析...

昨天給大家分享了《計算經過的時間》問題,今天給大家分享的是《年、月、日》單元中重要的幾個知識點,以及難點題型解析。知識點1 感知年、月、日一、結合生活實際,看看下面事情需要經過多少時間。跑完100米大約需要經過十幾(秒)。2.打一場籃球…

FFmpeg源代碼簡單分析-架構圖-編碼

參考鏈接 FFmpeg源代碼結構圖 - 編碼_雷霄驊的博客-CSDN博客_ffmpeg 源碼函數背景色 函數在圖中以方框的形式表現出來。不同的背景色標志了該函數不同的作用: 粉紅色背景函數:FFmpeg的API函數。白色背景的函數:FFmpeg的內部函數。黃色背景的…

為革命,保護視力——為Eclipse更換暗黑皮膚及編輯頁面的字體顏色主題

1.在Eclipse中的菜單欄的Help -> Eclipse Market 的 Search欄中輸入 Eclipse Moonrise UI Theme ,之后自己執生啦(確保上網配置正確)。 2.與上面操作類似,輸入 Eclipse Color Theme,選擇安裝。 3.選擇菜單欄的Win…

python函數可以作為容器對象嗎_正確理解Python函數是第一類對象

正確理解 Python函數,能夠幫助我們更好地理解 Python 裝飾器、匿名函數(lambda)、函數式編程等高階技術。函數(Function)作為程序語言中不可或缺的一部分,太稀松平常了。但函數作為第一類對象(First-Class Object)卻是 Python 函數的一大特性。那到底什么…

FFmpeg源代碼簡單分析-通用- av_register_all()

參考鏈接 ffmpeg 源代碼簡單分析 : av_register_all()_雷霄驊的博客-CSDN博客_av_register_all()從學齡前開始解讀FFMPEG代碼 之 avcodec_register_all函數_zzyincsdn的博客-CSDN博客

@suppressWarnings(unchecked)及其相關屬性在Java中意思

首先suppressWarnings("unchecked")是JDK1.5中新加入的Annotation語法,用來壓制警告信息的。 編寫代碼時,有時會提示一些警告(例如:使用已經廢棄的類,沒有加入泛型等),如果不想讓程序…

FFmpeg源代碼簡單分析-通用-avcodec_register_all()

參考鏈接 ffmpeg 源代碼簡單分析 : avcodec_register_all()_雷霄驊的博客-CSDN博客

pythonsklearn乳腺癌數據集_Python的Sklearn庫中的數據集

一、Sklearn介紹scikit-learn是Python語言開發的機器學習庫,一般簡稱為sklearn,目前算是通用機器學習算法庫中實現得比較完善的庫了。其完善之處不僅在于實現的算法多,還包括大量詳盡的文檔和示例。其文檔寫得通俗易懂,完全可以當…

FFmpeg源代碼簡單分析-通用- 內存的分配和釋放(av_malloc()、av_free()等)

參考鏈接 FFmpeg源代碼簡單分析:內存的分配和釋放(av_malloc()、av_free()等)_雷霄驊的博客-CSDN博客_av_malloc 內容介紹 內存操作的常見函數位于libavutil\mem.c中本文記錄最常使用的幾個函數: av_malloc()av_realloc()av_mal…

面試題——死鎖的實現

public class DeadLock {public static Object Chopstick_1 new Object();public static Object Chopstick_2 new Object();public static void main(String[] args) {final DeadLock deadLock new DeadLock();// 第一個線程 new Thread(new Runnable() {public void run()…

python回歸分析實驗_python線性回歸實驗

實驗算法python線性回歸實驗【實驗名稱】Python線性回歸實驗【實驗要求】掌握Python線性回歸模型應用過程,根據模型要求進行數據預處理,建模,評價與應用;【背景描述】線性回歸是利用數理統計中回歸分析,來確定兩種或兩…

FFmpeg源代碼簡單分析-通用-結構體分析-AVFormatContext

參考鏈接 FFMPEG結構體分析:AVFormatContext_雷霄驊的博客-CSDN博客_avformatcontext AVFormatContext AVFormatContext是包含碼流參數較多的結構體結構體的定義位于libavformat/avformat.h/*** Format I/O context.//格式化 I/O 上下文* New fields can be added…

log4j詳解與實戰

log4j詳解與實戰 http://www.iteye.com/topic/378077