Vue中.vue文件比main.js先執(zhí)行的問題及解決
問題
在main.js,App.vue和兩個子組件(A.vue和B.vue)中分別輸出語句,查看他們的加載順序:
main.js
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false new Vue({ ? ? ? ? el: '#app', ? ? ? ? render: h => h(App), ? ? ? ? beforeCreate() { ? ? ? ? ? ? Vue.prototype.$bus = this //安裝全局事件總線 ? ? ? ? }, ? ? }) console.log('mainjs===============')
App.vue
<template> ?? ?<div > ?? ??? ?<A/> ?? ??? ?<B/> ?? ?</div> </template> <script> ?? ?import A from './components/A' ?? ?import B from './components/B' ?? ?export default { ?? ??? ?name:'App', ?? ??? ?components:{A,B}, ?? ??? ?mounted(){ ?? ??? ??? ?console.log('APP==================') ?? ??? ?} ?? ?} </script>
A.vue
<template> ?? ?<div > ?? ?</div> </template> <script> ?? ?export default { ?? ??? ?name:'A',?? ??? ? ?? ??? ?mounted() { ?? ??? ??? ?console.log('A=============') ?? ??? ?} ?? ?} </script>
B.vue
<template> ?? ?<div > ?? ?</div> </template> <script> ?? ?export default { ?? ??? ?name:'B', ?? ??? ?mounted() { ?? ??? ??? ?console.log('B==================') ?? ??? ?}, ?? ?} </script>
執(zhí)行結(jié)果:
可以看到main.js理論上應(yīng)該是最先執(zhí)行的,但是結(jié)果卻正好相反。
解釋
Vue加載時的執(zhí)行順序如下
1、執(zhí)行index.html文件
2、執(zhí)行main.js文件
3、main.js掛載了app.vue文件,用app.vue的templete替換index.html中的<div id="app"></div>
4、main.js中注入了路由文件,將對應(yīng)的組件渲染到router-view中
5、router-view中加載Layout文件
6、Layout 加載Navbar, Sidebar, AppMain
main.js確實(shí)是最先執(zhí)行的,但是出現(xiàn)上述問題的原因是ES6的模塊化加載規(guī)則。
ES6模塊化加載規(guī)則
ES6 模塊化的設(shè)計(jì)思想是盡量的靜態(tài)化,使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。
而CommonJS 和 AMD 模塊化,都只能在運(yùn)行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。
// CommonJS模塊 let { stat, exists, readfile } = require('fs'); // 等同于 let _fs = require('fs'); let stat = _fs.stat; let exists = _fs.exists; let readfile = _fs.readfile;
上面代碼的實(shí)質(zhì)是整體加載fs模塊(即加載fs的所有方法),生成一個對象(_fs),然后再從這個對象上面讀取 3 個方法。
這種加載稱為“運(yùn)行時加載”,因?yàn)橹挥羞\(yùn)行時才能得到這個對象。
ES6 模塊化不是引入一個對象,而是通過export命令顯式指定輸出的代碼,再通過import命令輸入。
// ES6模塊 import { stat, exists, readFile } from 'fs';
上面代碼的實(shí)質(zhì)是從fs模塊加載 3 個方法,其他方法不加載。
我的理解是,ES6的模塊化規(guī)則類似于cpp中的宏,在代碼編譯時進(jìn)行字符串替換,上述代碼使用import語句引入了 stat, exists, readFile 三個方法,那么在編譯時,三個方法名其實(shí)已經(jīng)被替換成了方法代碼本身,存在于當(dāng)前模塊當(dāng)中,我們自然就可以使用引入的這些方法。
官方將這種加載稱為“編譯時加載”或者靜態(tài)加載,即 ES6 可以在編譯時就完成模塊加載,效率要比 CommonJS 模塊的加載方式高。
原因
因?yàn)槭蔷幾g時加載,自然而然就存在編譯優(yōu)化。
import命令具有提升效果,會提升到整個模塊的頭部,首先執(zhí)行。
這也很好理解,我們引入了模塊,并使用模塊中的成員,那么當(dāng)然要先引入才能使用。
下面的代碼不會報錯,因?yàn)閕mport的執(zhí)行早于foo的調(diào)用。這種行為的本質(zhì)是,import命令是編譯階段執(zhí)行的,在代碼運(yùn)行之前。
foo(); import { foo } from 'my_module';
在main.js文件中,就算我們將import語句放到代碼最后,輸出結(jié)果也不會變,仍然是A->B->App>main.js。
Vue.config.productionTip = false new Vue({ ? ? ? ? el: '#app', ? ? ? ? render: h => h(App), ? ? ? ? beforeCreate() { ? ? ? ? ? ? Vue.prototype.$bus = this //安裝全局事件總線 ? ? ? ? }, ? ? }) console.log('mainjs===============') import Vue from 'vue' import App from './App.vue'
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于vue-element組件實(shí)現(xiàn)音樂播放器功能
這篇文章主要介紹了基于vue-element組件實(shí)現(xiàn)音樂播放器功能,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2018-05-05Vue.js原理分析之nextTick實(shí)現(xiàn)詳解
這篇文章主要給大家介紹了關(guān)于Vue.js原理分析之nextTick實(shí)現(xiàn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Vue指令之 v-cloak、v-text、v-html實(shí)例詳解
當(dāng)用戶頻繁刷新頁面或網(wǎng)速慢時,頁面未完成 Vue.js 的加載時,導(dǎo)致 Vue 來不及渲染,這就會導(dǎo)致在瀏覽器中直接暴露插值(表達(dá)式),這篇文章主要介紹了Vue指令 v-cloak、v-text、v-html,需要的朋友可以參考下2019-08-08Element-UI日期選擇器(選擇日期范圍)禁用未來日期實(shí)現(xiàn)代碼
我們在網(wǎng)頁開發(fā)時通常需要用到一些日期組件來方便用戶選擇時間,其中element日期組件是一個非常好用的工具,這篇文章主要給大家介紹了關(guān)于Element-UI日期選擇器(選擇日期范圍)禁用未來日期的相關(guān)資料,需要的朋友可以參考下2024-02-02vue-cli項(xiàng)目中使用echarts圖表實(shí)例
在本篇文章里我們給大家分享了關(guān)于vue中使用echarts圖表的實(shí)現(xiàn)方法,有興趣的朋友們學(xué)習(xí)下。2018-10-10