世界快資訊:Vue入門淺析

        2023-05-15 17:33:23 來源: 博客園

        title: vue入門淺析author: Sun-Winddate: May 14,2022

        寫這篇博文的目的在于為初學(xué)vue的同學(xué)對vue有一些更進一步的了解讀這篇博文前,您應(yīng)該至少安裝了vue環(huán)境,能在本地運行一個簡單的demo本文將淺析vue項目工程的結(jié)構(gòu),以及用npm運行項目的過程中發(fā)生的一些事件注明:該文本應(yīng)在2022.5.14發(fā)表,由于博主有其他安排耽擱后面忘了,現(xiàn)在補上。

        項目的文件結(jié)構(gòu)主文件結(jié)構(gòu)

        一般的vue工程項目核心部分都在src里存放 vue 項目的源代碼。其文件夾下的各個文件(文件夾)分別為:


        (資料圖片)

        assets?:資源文件,比如存放 css,圖片等資源component?:組件文件夾,用來存放 vue 的公共組件(注冊于全局,在整個項目中通過關(guān)鍵詞便可直接輸出)。router?:用來存放 ?index.js?,這個 js 用來配置路由tool?:用來存放工具類 js,將 js 代碼封裝好放入這個文件夾可以全局調(diào)用(比如常見的? api.js?,?http.js? 是對 http 方法和 api 方法的封裝)views?:用來放主體頁面,雖然和組件文件夾都是 vue 文件,但 views 下的 vue 文件是可以用來充當(dāng)路由 view 的。main.js?:是項目的入口文件,作用是初始化 vue 實例,并引入所需要的插件。app.vue?:是項目的主組件,所有頁面都是在該組件下進行切換的.?其他文件結(jié)構(gòu)public:用于存放靜態(tài)文件public/index.html:是一個模板文件,作用是生成項目的入口文件,webpack打包的js,css也會自動注入到該頁面中。我們?yōu)g覽器訪問項目的時候就會默認(rèn)打開生成好的index.htmlpackage.json: 模塊基本信息項目開發(fā)所需要模塊,版本,項目名稱vue.config.js:包含vue項目的其他配置,包括端口等信息node_modules:項目的依賴模塊dist:打包文件npm run serve/dev淺析

        我們在本地運行vue項目,常見的指令就是npm run serve/dev;與其說是指令,不如說是腳本我們通常會在package.json中配置 script 字段作為 NPM 的執(zhí)行腳本。以個人開發(fā)項目為例,Vue.js 源碼構(gòu)建的腳本如下:

        "scripts": {    "serve": "vue-cli-service serve",    "build": "vue-cli-service build",    "lint": "vue-cli-service lint",    "stylelint": "stylelint src/css/*.* --fix",    "htmlhint": "htmlhint **.html",    "eslint": "eslint src/**/*.js src/**/*.vue",    "eslint-fix-js": "eslint src/**/*.js --fix",    "eslint-fix-vue": "eslint src/**/*.vue --fix"  },

        所以當(dāng)我們在終端運行npm run serve時,實際上運行的是vue-cli-service serve通過這個腳本去構(gòu)建整個vue項目

        構(gòu)建的過程中發(fā)生了什么public/index.html

        之前我們提到過,這個文件作為項目的入口文件,首先加載這個html文件下面這些代碼是個例子

                

        我們注意到一個特別的div塊,它的id為app

        src/main.js

        這里的app其實與src/main.js文件有關(guān)

        import Vue from "vue";new Vue({  el: "#app",  render: h => h(app)});

        我們都知道,new 關(guān)鍵字在 Javascript 語言中代表實例化是一個對象,而 Vue 實際上是一個類,類在 Javascript 中是用 Function 來實現(xiàn)的,在vue.js源碼中是這樣定義的

        function Vue (options) {  if (process.env.NODE_ENV !== "production" &&    !(this instanceof Vue)  ) {    warn("Vue is a constructor and should be called with the `new` keyword")  }  this._init(options)}

        可以看到vue只能通過關(guān)鍵字初始化,this._init函數(shù)這里就不再具體介紹Vue 初始化主要就干了幾件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等。

        在初始化的最后,檢測到如果有 el 屬性,則調(diào)用 vm.$mount 方法掛載 vm,掛載的目標(biāo)就是把模板渲染成最終的DOM在compiler版本的$mount實現(xiàn)中,它對 el 做了限制,Vue 不能掛載在 body、html這樣的根節(jié)點上。接下來的是很關(guān)鍵的邏輯 —— 如果沒有定義 render 方法,則會把 el 或者 template字符串轉(zhuǎn)換成 render 方法。

        這里我們要牢記,在 Vue 2.0 版本中,所有 Vue 的組件的渲染最終都需要 render方法,無論我們是用單文件 .vue 方式開發(fā)組件,還是寫了 el 或者 template 屬性,最終都會轉(zhuǎn)換成 render 方法,那么這個過程是 Vue 的一個在線編譯的過程。

        最后,調(diào)用原先原型上的 $mount 方法掛載。

        結(jié)合之前public/index.html中的例子

        實際上是編寫了如下render函數(shù)

        render: function (createElement) {  return createElement("div", {     attrs: {        id: "app"      },  })}

        vm._render 最終是通過執(zhí)行 createElement 方法并返回的是 vnode,它是一個虛擬 Node

        Virtual DOM介紹

        瀏覽器真正的DOM通常是非常龐大的,因為瀏覽器產(chǎn)生DOM的標(biāo)準(zhǔn)本身就比較復(fù)雜,當(dāng)我們頻繁地進行DOM更新,就會產(chǎn)生一系列的性能問題而 Virtual DOM 就是用一個原生的 JS 對象去描述一個 DOM 節(jié)點,所以它比創(chuàng)建一個 DOM 的代價要小很多。在 Vue.js 中,Virtual DOM 是用 VNode 這么一個 Class 去描述在 Vue.js 中,VNode 的 create 是通過之前提到的 createElement 方法創(chuàng)建的。

        生命周期

        這也是一張比較經(jīng)典的圖了在開發(fā)過程中,我們會頻繁地跟vue的生命周期打交道

        beforeCreate 和 created 函數(shù)都是在實例化 Vue 的階段在vue.js源碼中 beforeCreate 和 created 的鉤子調(diào)用是在 initState 的前后,initState 的作用是初始化 props、data、methods、watch、computed 等屬性

        在執(zhí)行 vm._render() 函數(shù)渲染 VNode 之前,執(zhí)行了 beforeMount 鉤子函數(shù),在執(zhí)行完 vm._update() 把 VNode patch 到真實 DOM 后,執(zhí)行 mouted 鉤子。beforeUpdate 和 updated 的鉤子函數(shù)執(zhí)行時機都應(yīng)該是在數(shù)據(jù)更新的時候,比如雙向綁定等等

        export function mountComponent (  vm: Component,  el: ?Element,  hydrating?: boolean): Component {  // ...  // we set this to vm._watcher inside the watcher"s constructor  // since the watcher"s initial patch may call $forceUpdate (e.g. inside child  // component"s mounted hook), which relies on vm._watcher being already defined  new Watcher(vm, updateComponent, noop, {    before () {      if (vm._isMounted) {        callHook(vm, "beforeUpdate")      }    }  }, true /* isRenderWatcher */)  // ...}

        可以看到這里有一個vm._isMounted的判斷,也就是說組件在mounted后才會去執(zhí)行這個鉤子函數(shù)同時這里實例化了一個watcher去監(jiān)聽vm上的數(shù)據(jù)變化重新渲染

        beforeDestroy 和 destroyed 鉤子函數(shù)的執(zhí)行時機在組件銷毀的階段注意mounted和destroyed的執(zhí)行過程都是先子后父從下圖可以看到初始化vue到最終渲染的整個過程

        注冊組件

        在開發(fā)一個組件的過程中往往會用到其他的組件組件注冊的語法如下

        Vue.component("my-component", {  // 選項})

        import HelloWorld from "./components/HelloWorld"export default {  components: {    HelloWorld  }}

        注冊組件實際上是一個合并的過程,合并option再創(chuàng)建vnode。

        由于博主在這一部分學(xué)識尚淺,暫不做過多的描述

        下載插件

        開發(fā)的過程中很可能需要一些其他的插件如Element等使用一般來說通過Vue.use()來下載插件,并且會阻止多次注冊相同的插件

        export function initUse (Vue: GlobalAPI) { Vue.use = function (plugin: Function | Object) {  const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))  if (installedPlugins.indexOf(plugin) > -1) {   return this  }  const args = toArray(arguments, 1)  args.unshift(this)  if (typeof plugin.install === "function") {   plugin.install.apply(plugin, args)  } else if (typeof plugin === "function") {   plugin.apply(null, args)  }  installedPlugins.push(plugin)  return this }}

        這是use方法的源碼,可以看到其參數(shù)只能是object或者function,然后判斷其是否被注冊過然后再調(diào)用該插件的install方法

        可以看到 Vue 提供的插件注冊機制很簡單,每個插件都需要實現(xiàn)一個靜態(tài)的 install 方法,當(dāng)我們執(zhí)行 Vue.use 注冊插件的時候,就會執(zhí)行這個 install 方法,并且在這個 install 方法的第一個參數(shù)我們可以拿到 Vue 對象,這樣的好處就是作為插件的編寫方不需要再額外去import Vue 了。

        路由

        路由的主要作用是根據(jù)不同的路徑映射到不同的視圖,一般我們用官方插件vue-router來解決路由的問題

        Object.defineProperty(Vue.prototype, "$router", {    get () { return this._routerRoot._router }  })  Object.defineProperty(Vue.prototype, "$route", {    get () { return this._routerRoot._route }  })

        在vue-router的類定義中有在vue原型上定義的 $router 和 $route 兩個屬性的get方法,這也是為什么可以在組件實例上訪問 this.$router和this.$route

        在new一個vueRouter后會返回它的實例,在beforecreate()中有這樣一段代碼

        beforeCreate() {  if (isDef(this.$options.router)) {    // ...    this._router = this.$options.router    this._router.init(this)    // ...  }}  

        所以在執(zhí)行該鉤子函數(shù)時,如果有傳入router實例,則會執(zhí)行router.init方法匹配是利用matcher匹配,并且會生成用戶的路由表(具體細(xì)節(jié)暫時不表)當(dāng)我們點擊router-link的時候,會通過一系列函數(shù)找到完整的url,執(zhí)行pushState方法

        export function pushState (url?: string, replace?: boolean) {  saveScrollPosition()  const history = window.history  try {    if (replace) {      history.replaceState({ key: _key }, "", url)    } else {      _key = genKey()      history.pushState({ key: _key }, "", url)    }  } catch (e) {    window.location[replace ? "replace" : "assign"](url)  }}

        該方法會更新瀏覽器的url地址,并且把當(dāng)前url壓入歷史棧中有一個專門的監(jiān)聽器會監(jiān)聽歷史棧的變化情況

        setupListeners () {  const router = this.router  const expectScroll = router.options.scrollBehavior  const supportsScroll = supportsPushState && expectScroll  if (supportsScroll) {    setupScroll()  }  window.addEventListener(supportsPushState ? "popstate" : "hashchange", () => {    const current = this.current    if (!ensureSlash()) {      return    }    this.transitionTo(getHash(), route => {      if (supportsScroll) {        handleScroll(this.router, route, current, true)      }      if (!supportsPushState) {        replaceHash(route.fullPath)      }    })  })}

        當(dāng)點擊瀏覽器的返回按鈕時,會觸發(fā)popstate事件,通過同樣的方法拿到當(dāng)前要跳轉(zhuǎn)的url并進行路徑轉(zhuǎn)換

        在router-view中

        data.routerView = true// ...while (parent && parent._routerRoot !== parent) {  if (parent.$vnode && parent.$vnode.data.routerView) {    depth++  }  if (parent._inactive) {    inactive = true  }  parent = parent.$parent}const matched = route.matched[depth]// ...const component = cache[name] = matched.components[name]

        這個循環(huán)就是從當(dāng)前的的父節(jié)點向上找,一直找到根節(jié)點(vue實例),遍歷完成后,就根據(jù)當(dāng)前遍歷的深度和路徑找到對應(yīng)的組件并進行渲染在router-view的最后有根據(jù) component 渲染出對應(yīng)的組件 vonde:

        return h(component, data, children)
        hash模式:單頁應(yīng)用標(biāo)配,hash發(fā)生變化的url都會被瀏覽器記錄下來history模式:可以進行切換和修改(歷史狀態(tài)),使得路由配置更自由其他vuex

        Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。該狀態(tài)管理模式包含以下幾個部分:

        state:驅(qū)動數(shù)據(jù)的應(yīng)用源view:以聲明方法將state映射到視圖actions:響應(yīng)在view上用戶的輸入導(dǎo)致的狀態(tài)變化以下是一個簡單的數(shù)據(jù)流模式

        需要注意以下兩點

        Vuex 的狀態(tài)存儲是響應(yīng)式的。當(dāng) Vue 組件從 store 中讀取狀態(tài)的時候,若 store 中的狀態(tài)發(fā)生變化,那么相應(yīng)的組件也會相應(yīng)地得到高效更新。你不能直接改變 store 中的狀態(tài)。改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化,從而讓我們能夠?qū)崿F(xiàn)一些工具幫助我們更好地了解我們的應(yīng)用。

        參考書籍《vue.js技術(shù)揭秘》

        關(guān)鍵詞:

        精選 導(dǎo)讀

        世界快資訊:Vue入門淺析

        title:vue入門淺析author:Sun-Winddate:May14,2022寫這篇博文的目的在于為初學(xué)vue的同學(xué)對vue有一些更進一

        發(fā)布時間: 2023-05-15 17:33
        要聞   2023-05-15

        熱點!從“靠鋼吃飯”到“棄鋼突圍”:一家鋼企的數(shù)字變身

        新華社天津5月12日電(記者郭方達)尚未進入廠區(qū),灰色外墻上一幅巨大的鯤形彩繪率先映入眼中。多彩墻體結(jié)

        發(fā)布時間: 2023-05-15 16:54
        要聞   2023-05-15

        左洛復(fù)鹽酸舍曲林說明書_舍曲林說明書-天天通訊

        1、有證據(jù)表明,舍曲林在過量服用時仍有很大的安全范圍。2、曾有舍曲林單獨過量服用高達13 5g的報道。3、曾

        發(fā)布時間: 2023-05-15 16:21
        要聞   2023-05-15

        “互換通”啟動 金融開放穩(wěn)步推進

        “互換通”啟動金融開放穩(wěn)步推進

        發(fā)布時間: 2023-05-15 16:06
        要聞   2023-05-15

        煙臺市萊山區(qū)第八小學(xué)開展地震應(yīng)急疏散演練活動

        為進一步增強師生安全意識,提高全校師生緊急避險、自救自護和應(yīng)變的能力,掌握地震來臨時最有效的逃生方法

        發(fā)布時間: 2023-05-15 15:14
        要聞   2023-05-15

        熱點 推薦

        世界快資訊:Vue入門淺析

        title:vue入門淺析author:Sun-Winddate:May14,2022寫這篇博文的目的在于為初學(xué)vue的同學(xué)對vue有一些更進一

        發(fā)布時間: 2023-05-15 17:33
        要聞   2023-05-15

        萬里印刷(08385.HK)一季度凈虧損1069.9萬港元

        格隆匯5月15日丨萬里印刷(08385 HK)公布,截至2023年3月31日止第一季度,公司收益為4221 7萬港元,同比減少

        發(fā)布時間: 2023-05-15 17:31
        IT   2023-05-15

        天津創(chuàng)業(yè)型人才落戶準(zhǔn)遷證獲取方式

        ??天津創(chuàng)業(yè)型人才落戶準(zhǔn)遷證獲取方式獲取方式一覽業(yè)務(wù)辦理進度查詢提交成功后個人中心的“業(yè)務(wù)網(wǎng)辦進度”

        發(fā)布時間: 2023-05-15 17:09
        國內(nèi)   2023-05-15

        世界快看:蘭州市博物館參觀攻略(門票預(yù)約+開放時間+交通指

        蘭州市博物館參觀攻略博物館地處市中心繁華地段的慶陽路240號,依明代白衣寺舊址而建。現(xiàn)有包括中軸線上的

        發(fā)布時間: 2023-05-15 17:03
        科技   2023-05-15

        東風(fēng)本田征戰(zhàn)TCR China 揭幕戰(zhàn)斬獲亞軍上演賽道“名場面”

        賽道競逐,風(fēng)云再起。5月12日-14日,2023年CTCC中國汽車場地職業(yè)聯(lián)賽超級杯·TCR中國系列賽震撼來襲,首站

        發(fā)布時間: 2023-05-15 17:02
        汽車   2023-05-15

        熱點!從“靠鋼吃飯”到“棄鋼突圍”:一家鋼企的數(shù)字變身

        新華社天津5月12日電(記者郭方達)尚未進入廠區(qū),灰色外墻上一幅巨大的鯤形彩繪率先映入眼中。多彩墻體結(jié)

        發(fā)布時間: 2023-05-15 16:54
        要聞   2023-05-15

        感恩母親 體驗“孕媽媽”艱辛-新動態(tài)

        母愛,是每個人成長道路上不可或缺的親情。她最關(guān)心我們,對我們無私奉獻,不求回報。5月14日,在母親節(jié)這

        發(fā)布時間: 2023-05-15 17:05
        IT   2023-05-15

        聯(lián)想ThinkPad春季新品發(fā)布會預(yù)熱,30周年限定禮盒“驚喜出艙”

        IT之家5月15日消息,聯(lián)想ThinkPad官博發(fā)布預(yù)熱,新品發(fā)布會即將在5月18日舉行。官博發(fā)布的視頻介紹的是Thin

        發(fā)布時間: 2023-05-15 16:46
        國內(nèi)   2023-05-15

        敏華控股(01999)將于7月20日派發(fā)末期股息每股10港仙_全球熱頭條

        敏華控股(01999)公布,公司將于2023年7月20日派發(fā)末期股息每股10港仙。

        發(fā)布時間: 2023-05-15 16:59
        科技   2023-05-15

        左洛復(fù)鹽酸舍曲林說明書_舍曲林說明書-天天通訊

        1、有證據(jù)表明,舍曲林在過量服用時仍有很大的安全范圍。2、曾有舍曲林單獨過量服用高達13 5g的報道。3、曾

        發(fā)布時間: 2023-05-15 16:21
        要聞   2023-05-15

        四川調(diào)研督導(dǎo)道路交通安全和運輸執(zhí)法領(lǐng)域突出問題專項整治工

        四川新聞網(wǎng)-首屏新聞成都5月15日訊(記者胡旭陽)為扎實推進道路交通安全和運輸執(zhí)法領(lǐng)域突出問題專項整治工

        發(fā)布時間: 2023-05-15 16:21
        IT   2023-05-15

        石墨文檔回應(yīng)崩了:故障正在全力排查搶修中

        針對服務(wù)器宕機一事,在線協(xié)同辦公平臺石墨文檔回應(yīng)稱,因技術(shù)原因,目前部分石墨文檔暫時無法編輯,故障正

        發(fā)布時間: 2023-05-15 16:21
        國內(nèi)   2023-05-15

        拼多多貨在路上可以申請退款嗎?拼多多退款多久可以到賬?

        拼多多是大家經(jīng)常使用并且非常熟悉的一家電商平臺,用戶可以在上面買到各種商品,并享受不同類型的優(yōu)惠,其中拼團優(yōu)惠是拼多多比較突出的一

        發(fā)布時間: 2023-05-15 16:28
        推薦   2023-05-15

        V8混動 蘭博基尼Urus PHEV諜照曝光

        [本站海外諜照]日前,外媒在蘭博基尼工廠附近拍攝到了UrusPHEV測試車。按照計劃這款車將會在2024年正式發(fā)布

        發(fā)布時間: 2023-05-15 16:09
        汽車   2023-05-15

        年產(chǎn)250臺 AC Cobra GT Roadster首發(fā) 天天速讀

        [本站新車首發(fā)]曾經(jīng)為世界車迷貢獻了傳世經(jīng)典跑車ACCobra的英國AC汽車公司近日正式推出該車的復(fù)刻版本――A

        發(fā)布時間: 2023-05-15 16:23
        汽車   2023-05-15

        環(huán)球即時看!阿斯頓·馬丁新DB系列將于5月24日首發(fā)

        [本站資訊]近日,我們從阿斯頓?馬丁官方獲取了三張全新一代DBGT的預(yù)告圖,新車將于5月24日首發(fā)。阿斯頓?

        發(fā)布時間: 2023-05-15 16:02
        汽車   2023-05-15

        拼多多退店要等30天嗎? 退店的條件是什么?

        拼多多平臺的店鋪數(shù)量越來越多了, 競爭非常激烈,在這種情況下,很多人選擇將自己的店鋪轉(zhuǎn)讓出去或者是關(guān)閉掉,那么,拼多多退店要等30天

        發(fā)布時間: 2023-05-15 16:25
        推薦   2023-05-15

        當(dāng)前熱點-畫蛋糕圖片大全大圖涂色_畫蛋糕圖片

        你們好,最近小活發(fā)現(xiàn)有諸多的小伙伴們對于畫蛋糕圖片大全大圖涂色,畫蛋糕圖片這個問題都頗為感興趣的,今

        發(fā)布時間: 2023-05-15 16:00
        科技   2023-05-15

        七天無理由退貨有運費險嗎?七天之內(nèi)退貨運費誰出?

        線上購物是現(xiàn)在比較熱門的一種購物方式,一方面線上購物發(fā)貨比較快,甚至第二天就能到貨,另一方面線上購物商品價格會更加優(yōu)惠、便宜。此外

        發(fā)布時間: 2023-05-15 16:21
        社會   2023-05-15

        買車可以用支付寶支付嗎?全款買車都是怎么支付的?

        買車的時候,選擇好汽車等待商家提交訂單即可支付了, 買車可以用銀行卡也可以用現(xiàn)金,那么,買車可以用支付寶支付嗎?全款買車都是怎么支

        發(fā)布時間: 2023-05-15 16:18
        社會   2023-05-15
        亚洲黄色一级毛片| 亚洲视频一区在线| 亚洲经典千人经典日产| va天堂va亚洲va影视中文字幕 | 男人的天堂亚洲一区二区三区| 亚洲中文字幕久在线| 亚洲成人免费在线观看| 久久精品国产亚洲AV大全| 久久亚洲中文字幕精品有坂深雪| 亚洲国产成人久久综合一 | 亚洲成在人天堂一区二区| 亚洲精品私拍国产福利在线| 亚洲国产综合专区在线电影| 亚洲午夜未满十八勿入| 亚洲美女视频一区二区三区| 亚洲嫩草影院在线观看| 亚洲香蕉久久一区二区三区四区| 亚洲娇小性xxxx色| 亚洲国产精品精华液| 国产精品亚洲色婷婷99久久精品| 亚洲?v女人的天堂在线观看| 亚洲裸男gv网站| 国产精品亚洲成在人线| 亚洲AV日韩AV鸥美在线观看| 精品亚洲国产成AV人片传媒| 亚洲国产亚洲综合在线尤物| 亚洲中文字幕久久精品无码A| 亚洲AV一区二区三区四区| 国产亚洲男人的天堂在线观看| 亚洲免费日韩无码系列 | 亚洲中文字幕久久久一区| 国产精品亚洲专区无码牛牛| 亚洲色一色噜一噜噜噜| 亚洲精品夜夜夜妓女网| 亚洲人成网站影音先锋播放| 亚洲午夜电影一区二区三区| 亚洲色在线无码国产精品不卡| 国产亚洲高清在线精品不卡| 国产亚洲视频在线播放| 亚洲爱情岛论坛永久| youjizz亚洲|