掃二維碼與項目經理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網交流
Vue 的 2.x 版本有很多的全局 API 和 配置,他們會在全局范圍內改變 Vue 的行為。

成都創(chuàng)新互聯(lián)公司專注于圖們企業(yè)網站建設,響應式網站設計,商城建設。圖們網站建設公司,為圖們等地區(qū)提供建站服務。全流程按需定制,專業(yè)設計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務
比如(官方例子),如果你想創(chuàng)建一個全局的組件,你會用到 Vue.component:
- Vue.component('trump-sucks', {
- data: () => ({ position: 'America president', }),
- template: `
Trump is the worst ${position}
`;- });
或者聲明一個全局指令:
- Vue.directive('focus', {
- inserted: el => {
- console.log('聚焦!');
- el.focus();
- },
- });
這樣確實比較方便,但是會造成一些問題。首先要明確的一點是,Vue 2.x 在設計上并沒有 app(應用)的概念。開發(fā)者在使用 Vue 2.x 是所謂的 app 不過是一個用 new Vue()創(chuàng)建的 Vue 實例罷了(呵,不過如此)。由同一個 Vue 構造函數(shù)創(chuàng)建的 Vue 實例都會共享來自構造函數(shù)的全局配置。這將會導致:
在測試過程中,由于全局配置的存在,測試用例很容易就會被“污染”。開發(fā)者需要小心翼翼地將全局配置找一個地方存下來,在每次測試結束后將其還原,比如 Vue.config.errorHandler;一些 API 比如 Vue.use 和 Vue.mixin 甚至沒有避免其影響的辦法。這使得在測試中一旦涉及了插件,整個過程都會變得非常棘手。事實上,為了解決這個問題,vue-test-utils 不得不引入一個特殊的 API:createLocalVue:
- import { createLocalVue, mount } from '@vue/test-utls';
- const localVue = createLocalVue();
- localVue.use(MyPlugin);
- mount(Component, { localVue });
還有一個避免不了的問題是,一旦頁面上有多個 Vue 實例時,它們的全局配置就很自然地共享了,但在很多時候開發(fā)者并不想要這樣的結果
- Vue.mixin({
- mounted: () => {
- console.log('wubba lubba dub dub');
- },
- });
- const rick = new Vue({ el: '#rick' });
- const morty = new Vue({ el: '#morty' });
因此,為了規(guī)避這些問題,Vue 3 引入了應用實例的概念。
全局 API: createApp
調用 createApp 會返回一個 應用實例,沒錯,應用實例這個概念是 Vue 3 中新引入的。
- import { createApp } from 'vue';
- const app = createApp();
應用實例會暴露一個當前全局 API 的子集。在這個重構工作中,Vue 團隊秉承的經驗法則是:任何會在全局范圍內影響 Vue 行為的 API 都會被遷移至應用實例中去。
2.x 的全局 API 3.x 的應用實例 API Vue.config app.config Vue.config.productionTip 移除 Vue.config.ignoredElements app.config.isCustomElement Vue.component app.component Vue.directive app.directive Vue.mixin app.mixin Vue.use app.use
其他不會在全局影響 Vue 行為的 api 都已改造為具名導出的構建方式(named exports),就像之前尤雨溪尤大在直播里說的那樣:為了支持 TreeShaking。
掛載一個應用實例
在使用 createApp(VueInstance) 得到一個應用實例后,這個應用實例就可以用來把整個 Vue 跟實例掛載到頁面上了:
- import { createApp } from 'vue';
- import MyApp from './MyApp.vue';
- const app = createApp(MyApp);
- app.mount('#app');
在完成了這些改造之后,開篇我們提到的那些例子將會重寫成這樣:
- app.component('trump-sucks', {
- data: () => ({ position: 'America president', }),
- template: `
Trump is the worst ${position}
`;- });
- app.directive('focus', {
- inserted: el => {
- console.log('聚焦!');
- el.focus();
- },
- });
- // 至此,所有在 app 所包含的組件樹內創(chuàng)建的 Vue 實例才會共享 trump-sucks 這個組件和 focus 這個指令,而 Vue 構造函數(shù)并沒有被污染。
多個應用實例的配置共享
上文提到的“不是所有開發(fā)者都想要的全局配置共享”,在 Vue 3 中可以通過工廠函數(shù)的方式實現(xiàn):
- import { createApp } from 'vue';
- import CaiXuKun from './CXK.vue';
- import WuYiFan from './WYF.vue';
- const createIdolApp = (IdolInstance) => {
- const idolApp = createApp(IdolInstance);
- idolApp.directive('sing-and-dance', {
- inserted: () => {
- console.log('I am cool!');
- },
- });
- }
- createIdolApp(CaiXuKun).mount('#caixukun');
- createIdolApp(WuYiFan).mount('#wuyifan');
這樣就能實現(xiàn)多個應用實例的配置共享了:蔡徐坤和吳亦凡都有了一個叫做“唱跳”的 Vue 自定義指令。

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網交流