摘要:中引入了中的中引入了中的中,定義了的構(gòu)造函數(shù)中的原型上掛載了方法,用來做初始化原型上掛載的屬性描述符,返回原型上掛載的屬性描述符返回原型上掛載與方法,用來為對(duì)象新增刪除響應(yīng)式屬性原型上掛載方法原型上掛載事件相關(guān)的方法。
入口尋找
入口platforms/web/entry-runtime-with-compiler中import了./runtime/index導(dǎo)出的vue。
./runtime/index中引入了core/index中的vue.
core/index中引入了instance/index中的vue
instance/index中,定義了vue的構(gòu)造函數(shù)
instance/index中的vuefunction 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) } // 原型上掛載了init方法,用來做初始化 initMixin(Vue) // 原型上掛載$data的屬性描述符getter,返回this._data // 原型上掛載$props的屬性描述符getter, 返回this._props // 原型上掛載$set與$delete方法,用來為對(duì)象新增/刪除響應(yīng)式屬性 // 原型上掛載$watch方法 stateMixin(Vue) // 原型上掛載事件相關(guān)的方法, $on、$once、$off、$emit。 eventsMixin(Vue) // 原型上掛載_update、$destroy與$forceUpdate方法,與組件更新有關(guān)。 lifecycleMixin(Vue) // 原型掛載組件渲染相關(guān)方法,_render方法(用來返回vnode,即虛擬dom) renderMixin(Vue) export default Vuecore/index中的vue index
import Vue from "./instance/index" import { initGlobalAPI } from "./global-api/index" import { isServerRendering } from "core/util/env" // 初始化一些全局API initGlobalAPI(Vue) // 是否是服務(wù)端渲染 Object.defineProperty(Vue.prototype, "$isServer", { get: isServerRendering // global["process"].env.VUE_ENV === "server" }) // ssr相關(guān) Object.defineProperty(Vue.prototype, "$ssrContext", { get () { /* istanbul ignore next */ return this.$vnode && this.$vnode.ssrContext } }) Vue.version = "__VERSION__" export default VueinitGlobalAPI
// 定義vue配置對(duì)象,配置對(duì)象詳情見 import config from "../config"中的備注 const configDef = {} configDef.get = () => config Object.defineProperty(Vue, "config", configDef) // 定義一些內(nèi)部公用方法 Vue.util = { warn, // ??警告打印相關(guān) extend, // 淺拷貝函數(shù) mergeOptions, // 配置合并,用到的時(shí)候細(xì)看 defineReactive // 定義響應(yīng)式屬性的方法。 } // 靜態(tài)方法,同$set、$delete、$nextTick Vue.set = set Vue.delete = del Vue.nextTick = nextTick Vue.options = Object.create(null) ASSET_TYPES.forEach(type => { Vue.options[type + "s"] = Object.create(null) }) // Vue.options => {"components":{},"directives":{},"filters":{}} // 跟Weex"s multi-instance scenarios多場景有關(guān) Vue.options._base = Vue; //將內(nèi)置組件塞進(jìn)來 extend(Vue.options.components, builtInComponents) // 定義Vue.use,主要在應(yīng)用在插件系統(tǒng)中 initUse(Vue) // 定義Vue.mixin, 就一句this.options = mergeOptions(this.options, mixin) initMixin(Vue) // 定義Vue.extend, 用作原型繼承,通過它,可以創(chuàng)建子組件的構(gòu)造函數(shù) initExtend(Vue) // 擴(kuò)展Vue.component,Vue.directive,Vue.filter方法 initAssetRegisters(Vue)runtime/index中的vue
import Vue from "core/index" import config from "core/config" import { extend, noop } from "shared/util" import { mountComponent } from "core/instance/lifecycle" import { devtools, inBrowser, isChrome } from "core/util/index" import { query, mustUseProp, isReservedTag, isReservedAttr, getTagNamespace, isUnknownElement } from "web/util/index" import { patch } from "./patch" import platformDirectives from "./directives/index" import platformComponents from "./components/index" // 一些標(biāo)簽檢查類的方法。平臺(tái)相關(guān) Vue.config.mustUseProp = mustUseProp Vue.config.isReservedTag = isReservedTag Vue.config.isReservedAttr = isReservedAttr Vue.config.getTagNamespace = getTagNamespace Vue.config.isUnknownElement = isUnknownElement // 平臺(tái)相關(guān)指令組件 // 指令有model與show // 組件有Transition與TransitionGroup extend(Vue.options.directives, platformDirectives) extend(Vue.options.components, platformComponents) // install platform patch function Vue.prototype.__patch__ = inBrowser ? patch : noop // public mount method Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean ): Component { el = el && inBrowser ? query(el) : undefined return mountComponent(this, el, hydrating) }entry-runtime-with-compiler中的vue
import config from "core/config" import { warn, cached } from "core/util/index" import { mark, measure } from "core/util/perf" import Vue from "./runtime/index" import { query } from "./util/index" import { shouldDecodeNewlines } from "./util/compat" import { compileToFunctions } from "./compiler/index" // 根據(jù)id返回dom內(nèi)容 const idToTemplate = cached(id => { const el = query(id) return el && el.innerHTML }) // 重寫$mount方法 const mount = Vue.prototype.$mount Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean ): Component { el = el && query(el) /* 將vue綁定到body或者h(yuǎn)tml元素上的錯(cuò)誤提示 */ if (el === document.body || el === document.documentElement) { process.env.NODE_ENV !== "production" && warn( `Do not mount Vue to or - mount to normal elements instead.` ) return this } const options = this.$options // 解析template或者el屬性,將其轉(zhuǎn)化為render函數(shù) if (!options.render) { let template = options.template // 獲得模板字符串 if (template) { if (typeof template === "string") { if (template.charAt(0) === "#") { template = idToTemplate(template) } } else if (template.nodeType) { template = template.innerHTML } else { if (process.env.NODE_ENV !== "production") { warn("invalid template option:" + template, this) } return this } } else if (el) { template = getOuterHTML(el) } // 獲得模板字符串后,編譯模板為render函數(shù) if (template) { /* istanbul ignore if */ if (process.env.NODE_ENV !== "production" && config.performance && mark) { mark("compile") } const { render, staticRenderFns } = compileToFunctions(template, { shouldDecodeNewlines, delimiters: options.delimiters, comments: options.comments }, this) options.render = render options.staticRenderFns = staticRenderFns /* istanbul ignore if */ if (process.env.NODE_ENV !== "production" && config.performance && mark) { mark("compile end") measure(`vue ${this._name} compile`, "compile", "compile end") } } } return mount.call(this, el, hydrating) } /** * Get outerHTML of elements, taking care * of SVG elements in IE as well. */ function getOuterHTML (el: Element): string { if (el.outerHTML) { return el.outerHTML } else { const container = document.createElement("div") container.appendChild(el.cloneNode(true)) return container.innerHTML } } Vue.compile = compileToFunctions export default Vue文章鏈接
vue源碼分析系列
vue源碼分析系列之debug環(huán)境搭建
vue源碼分析系列之響應(yīng)式數(shù)據(jù)(一)
vue源碼分析系列之響應(yīng)式數(shù)據(jù)(二)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101636.html
摘要:目標(biāo)是為了可以調(diào)試版本的,也就是下的源碼,所以主要是的開啟。結(jié)語至此就可以開心的研究源碼啦。文章鏈接源碼分析系列源碼分析系列之入口文件分析源碼分析系列之響應(yīng)式數(shù)據(jù)一源碼分析系列之響應(yīng)式數(shù)據(jù)二 概述 為了探究vue的本質(zhì),所以想debug一下源碼,但是怎么開始是個(gè)問題,于是有了這樣一篇記錄。目標(biāo)是為了可以調(diào)試es6版本的,也就是src下的源碼,所以主要是sourceMap的開啟。原文來自...
摘要:執(zhí)行當(dāng)時(shí)傳入的回調(diào),并將新值與舊值一并傳入。文章鏈接源碼分析系列源碼分析系列之環(huán)境搭建源碼分析系列之入口文件分析源碼分析系列之響應(yīng)式數(shù)據(jù)一源碼分析系列之響應(yīng)式數(shù)據(jù)二源碼分析系列之響應(yīng)式數(shù)據(jù)三 前言 上一節(jié)著重講述了initComputed中的代碼,以及數(shù)據(jù)是如何從computed中到視圖層的,以及data修改后如何作用于computed。這一節(jié)主要記錄initWatcher中的內(nèi)容。 ...
摘要:本系列文章旨在化繁為簡,通讀源碼,描述背后的實(shí)現(xiàn)邏輯。記錄方式主要是代碼注釋文章鏈接源碼分析系列之環(huán)境搭建源碼分析系列之入口文件分析源碼分析系列之響應(yīng)式數(shù)據(jù)一源碼分析系列之響應(yīng)式數(shù)據(jù)二 概述 在使用vue的時(shí)候,會(huì)遇到很多神奇的地方,比如 修改vue實(shí)例中data對(duì)象的屬性值,會(huì)觸發(fā)dom值的改變;改變dom中的輸入,會(huì)觸發(fā)data對(duì)應(yīng)屬性的改變,即雙向數(shù)據(jù)綁定。 通過watch可以...
摘要:代碼初始化部分一個(gè)的時(shí)候做了什么當(dāng)我們一個(gè)時(shí),實(shí)際上執(zhí)行了的構(gòu)造函數(shù),這個(gè)構(gòu)造函數(shù)內(nèi)部掛載了很多方法,可以在我的上一篇文章中看到。合并構(gòu)造函數(shù)上掛載的與當(dāng)前傳入的非生產(chǎn)環(huán)境,包裝實(shí)例本身,在后期渲染時(shí)候,做一些校驗(yàn)提示輸出。 概述 在使用vue的時(shí)候,data,computed,watch是一些經(jīng)常用到的概念,那么他們是怎么實(shí)現(xiàn)的呢,讓我們從一個(gè)小demo開始分析一下它的流程。 dem...
閱讀 3331·2021-11-16 11:45
閱讀 4410·2021-09-22 15:38
閱讀 2855·2021-09-22 15:26
閱讀 3363·2021-09-01 10:48
閱讀 863·2019-08-30 15:56
閱讀 730·2019-08-29 13:58
閱讀 1497·2019-08-28 18:00
閱讀 2176·2019-08-27 10:53