<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                >[success] # 模板編譯代碼分析 ~~~ 1.其實整個$mount方法在vue有兩個,一個是專門解析模板在'platforms\web\runtime-with-compiler.js' 另一是直接解析渲染函數的在'\platforms\web\runtime\index.js', 2.我們解讀分析的代碼版本是包含'platforms\web\runtime-with-compiler.js'里面的$mount ~~~ >[info] ## 分析源碼中的代碼 ~~~ 1.之前說過即使使用了模板的方式,最后也轉成了渲染函數,vue 也給我們提供了可以幫忙轉換模板 的vue版本,也提供了不幫忙轉換需要寫渲染函數的版本,無論是那個版本都是$mount 作為入口 站在我的角度來說,我可能可以做一個變量來判斷當前用戶使用的版本然后一頓if-else來做區分, vue在這里是怎么做的呢? 2.在帶編譯版本的'$mount'使用前vue保留了他直接解析'渲染函數的$mount',可以看一下,下面的代碼片段 ~~~ * 代碼片段 ~~~js /*把原本不帶編譯的$mount方法保存下來,在最后會調用。*/ const mount = Vue.prototype.$mount // 這個是\platforms\web\runtime\index.js 只解析渲染函數的$mount /*掛載組件,帶模板編譯*/ Vue.prototype.$mount = function (){....} // platforms\web\runtime-with-compiler.js 中的$mount ~~~ >[danger] ##### 開始分析源碼 ~~~ 1.這里要說明一下,下面源碼中中文解釋部分我使用的是'https://github.com/answershuto/learnVue' 這個github項目中 answershuto 大佬加的中文注釋 2.通過源碼可以解答上個章節第一個問題,'Vue 不能掛載在 body、html 這樣的根節點上' 3.我們現在分析的是模板版本的$mount,可以發現他會先判斷你是否有'render'這參數也是直接影響到vue 是使用了'渲染函數'的方式,還是'模板方式' ~~~ * 源碼 ~~~js /*把原本不帶編譯的$mount方法保存下來,在最后會調用。*/ const mount = Vue.prototype.$mount /*掛載組件,帶模板編譯*/ Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean ): Component { el = el && query(el) /* istanbul ignore if */ if (el === document.body || el === document.documentElement) { process.env.NODE_ENV !== 'production' && warn( `Do not mount Vue to <html> or <body> - mount to normal elements instead.` ) return this } const options = this.$options // resolve template/el and convert to render function /*處理模板templete,編譯成render函數,render不存在的時候才會編譯template,否則優先使用render*/ if (!options.render) { let template = options.template /*template存在的時候取template,不存在的時候取el的outerHTML*/ if (template) { /*當template是字符串的時候*/ if (typeof template === 'string') { if (template.charAt(0) === '#') { template = idToTemplate(template) /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && !template) { warn( `Template element not found or is empty: ${options.template}`, this ) } } } else if (template.nodeType) { /*當template為DOM節點的時候*/ template = template.innerHTML } else { /*報錯*/ if (process.env.NODE_ENV !== 'production') { warn('invalid template option:' + template, this) } return this } } else if (el) { /*獲取element的outerHTML*/ template = getOuterHTML(el) } if (template) { /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { mark('compile') } /*將template編譯成render函數,這里會有render以及staticRenderFns兩個返回,這是vue的編譯時優化,static靜態不需要在VNode更新時進行patch,優化性能*/ const { render, staticRenderFns } = compileToFunctions(template, { shouldDecodeNewlines, delimiters: options.delimiters }, this) options.render = render options.staticRenderFns = staticRenderFns /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { mark('compile end') measure(`${this._name} compile`, 'compile', 'compile end') } } } /*調用const mount = Vue.prototype.$mount保存下來的不帶編譯的mount*/ return mount.call(this, el, hydrating) } ~~~ >[danger] ##### 模板的使用方式分析 ~~~ 1.通過源碼可以發現'模板的使用方式'有兩種一種是你直接綁定'el' 中形式,一種是你使用'template'屬性的 對這幾種使用方式來做個說明 ~~~ * 先看el 的方式 ~~~ 1.先分析一下el這種情況,就需要分析'query(el)'方法在源碼'platforms\web\util\index.js', 有一個'返回一個元素的DOM實例對象'方法 /*返回一個元素的DOM實例對象*/ export function query (el: string | Element): Element { if (typeof el === 'string') { const selected = document.querySelector(el) if (!selected) { process.env.NODE_ENV !== 'production' && warn( 'Cannot find element: ' + el ) return document.createElement('div') } return selected } else { return el } } 2.也就是說你的el如果是字符串可以使用'querySelector() 方法返回文檔中匹配指定 CSS 選擇器的一個元素' 或者你可以傳入一個'dom實例對象' 因此我們可以寫法如下 var vm = new Vue({ el: "#app", // 也可以綁定css選擇器 }) var vm = new Vue({ el: document.getElementById('app'), // 也可以綁定css選擇器 }) ~~~ * 在看template方式 ~~~ 1.第一步依舊需要el,第二步聲明'template',這里要注意你在使用template不僅是在vue的opition中聲明'template' 也需要聲明el 2.而且template聲明的內容要用template 標簽包裹 3.即使你定義了el 里面的內容也會被template給替換掉 <body> <div id="app"> <p>{{msg}}</p> </div> <template id="app7777"> <div>{{msg}}123</div> </template> <script> var vm = new Vue({ el: "#app", template: document.getElementById('app7777'), data: { msg: "第一個案例" } }) </script> </body> // 或者直接綁定字符串dom形式 var vm = new Vue({ el: "#app", template: '<div>2222{{msg}}</div>', data: { msg: "第一個案例" } }) // 字符串id形式 var vm = new Vue({ el: "#app", template: '#app7777', data: { msg: "第一個案例" } }) ~~~ >[danger] ##### 現在來對著生命周期圖來看這塊 ~~~ 1.當然你實在不想寫el 也可以這么寫 new Vue({ render: h => h(App) }).$mount("#app"); ~~~ ![](https://img.kancloud.cn/13/14/13141c8cea9139bb9416f6c853e48d56_757x428.png) >[danger] ##### 小的細節代碼說明 ~~~ 1.其實發現一段小的代碼'idToTemplate(template)',這段代碼是下面的代碼組成的,利用閉包做的緩存的代碼 function cached(fn) { const cache = Object.create(null) return (function cachedFn(str) { const hit = cache[str] return hit || (cache[str] = fn(str)) }) } /*根據id獲取templete,即獲取id對應的DOM,然后訪問其innerHTML*/ const idToTemplate = cached(id => { const el = query(id) return el && el.innerHTML }) ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看