尋找項目中頂級Vue對象 (一)


個人博客首發博客園: http://www.cnblogs.com/zhangrunhao/

參考

感謝作者

問題背景

  • 在調試Chrome的時候, 發現不能找到vm這個對象.
  • window下面也沒有看到這個對象.
  • 產生了好奇心.

過程分析

  • 在dev環境下面:
    • 在控制台看的時候放到了 window__VUE_DEVTOOLS_GLOBAL_HOOK__
  • 找到了new Vue的運行棧.
  • 但是沒能確定在Vue中具體的運行過程.
  • 應該是在import的時候, webpack就把引入的Vue對象放到了某個地方, 保存起來了.

運行時構建的Vue庫/獨立構建的Vue庫

  • 使用import/require引入的是 運行時構建的Vue庫 dist/vue.runtime.common.js
  • 使用<script>引入的是獨立構建的Vue庫
  • 區別就是是否包含一個template功能, 因為在運行時構建的Vue庫中, 我們通過打包工具webpack等解決了這一問題.

選擇掛載優先級

  • render渲染函數 > template編譯模板 > 掛載到el屬性上的指定DOM

render函數

  • 掛載在Vue的頂級函數上面. 渲染的最優先選擇
  • render: function(cb / createElement) {} // 所有的的核心都在這個回調函數中
  • 這個回調函數就是createElement函數, 也就是我們用來創建VNode的函數, render返回的就是 回調函數的執行結果
  • return createElement(tag, data, array) // 這個就是我們的返回結果
  • 參數第一個表示, 我們的標簽名稱, 或者是一個實例組件. data就是我們這個組件的描述信息了. 什么都有.
  • 最后一個參數, 我們用來遞歸形成的子標簽, 或者子組件, 數組表示平行關系
  • 第二個參數, 如果是一個字符串的話, 就是我們想要往里面插入的子組件陳列
  • render: h => h(App) / render(h) {return h('div', this.hi)}

vue不渲染Dom, 實現場景直接通信

  • 新建文件 import Vue from 'vue; export EventBus = new Vue()
  • 通過$on添加監聽事件
    • import EventBus from './event-bus.js; EventBus.$on('customerEvent', function() {}).
    • 此處盡量不要使用箭頭函數, 里面的指針不易改變
    • 回頭自己試試.
  • 其他文件引入, 通過$emit觸發
    • import EventBus from './event-bus.js; EventBus.$emit('customerEvent', ...params)

查找vue.runtime.common.js

應該從打包工具開始查找

/dist文件夾下八個文件的區別

  • 按照運行環境區分: 完整構建/運行時構建, 也就是是否可以使用template選項
  • 按照模塊化規范: UMD/CommonJS/ESModule
    • AMD: requireJS實現. 主要是異步加載模塊. (偏向瀏覽器)
    • COMMONJS: Node, 同步加載, 模塊無需包裝. (偏向服務器)
    • UMD: AMD和COMMON的結合, (先判斷是否執行export/Node), 再判斷是否支持(define/AMD).
  • vue.common.js: 基於common的完整構建. 使用webpack打包時, 需要配置別名.(這就不太理解了)
    • 我又預感, 問題應該就出在webpack的配置中
// webpack-1
{
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.common.js'
    }
  }
}
  • vue.esm.js: 基於ESModule的完整構建. 使用webpack打包時, 也是需要配置
  • vue.js: 基於UMD的完整構建
  • vue.runtime.common.js: 基於common的運行時構建. 不支持template, .vue被解析成了render函數
  • vue.runtime.esm.js: 基於ESModule的運行時構建.
  • vue.runtime.js: 基於UMD的運行時構建.

項目直接引用的vue, 引用的是vue.runtime.common.js嗎. 為何可以使用ESModle

  • 先貼出vue的package.json
{
  // ...
  "main": "dist/vue.runtime.common.js",
  "module": "dist/vue.runtime.esm.js",
  "unpkg": "dist/vue.js",
  "jsdelivr": "dist/vue.js",
  // ...
}
  • main: 是基於COMMONJS的. module: 是基於ES6的.
  • 因為使用ES6的話, 可以配置uglifyjs-webpack-plugin插件, 可以去除沒有用到的函數.
  • 但是因為有些npm包不支持ES6, 比如有些node環境.
  • 這個時候, 會判斷當前支持哪種環境, 然后選擇不同的包.
  • 引入的時候, 不論包怎么導出都可用import引入. 但是導出的時候, 就會區分出來. 使用export/export default關鍵字, 還是module.exports/exports導出

結論, 我們的項目, 應該是引用了run.runtime.esm.js

webpack中配置別名

  • baseConf.resolve.alias.vue = 'vue/dist/vue.common.js';
  • 當我們解析vue / vue$ 的時候, 就會解析到指定的目錄下面.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM