Vue 的 2.x 版本有很多的全局 API 和 配置,他们会在全局范畴内扭转 Vue 的行为。
比方常见的全局 API 有:Vue.component / Vue.mixin / Vue.extend / Vue.nextTick;
常见的全局配置有:Vue.config.silent / Vue.config.devtools / Vue.config.productionTip
比方(官网例子),如果你想创立一个全局的组件,你会用到 Vue.component
:
Vue.component('trump-sucks', {data: () => ({position: 'America president',}),
template: `<h1>Trump is the worst ${position}</h1>`;
});
或者申明一个全局指令:
Vue.directive('focus', {
inserted: el => {console.log('聚焦!');
el.focus();},
});
这样的确比拟不便,然而会造成一些问题。首先要明确的一点是,Vue 2.x 在设计上并没有 app(利用)的概念。开发者在应用 Vue 2.x 时所谓的 app 不过是一个用 new Vue()
创立的 Vue 实例罢了(呵,不过如此)。由同一个 Vue 构造函数创立的 Vue 实例都会共享来自构造函数的全局配置。这将会导致:
在测试过程中,因为全局配置的存在,测试用例很容易就会被“净化”。开发者须要小心翼翼地讲全局配置找一个中央存下来,在每次测试完结后将其还原,比方 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 实例时,它们的全局配置就很天然地共享了,但在很多时候开发者并不想要这样的后果
Vue.mixin({mounted: () => {console.log('wubba lubba dub dub');
},
});
const rick = new Vue({el: '#rick'});
const morty = new Vue({el: '#morty'});
因而,为了躲避这些问题,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: `<h1>Trump is the worst ${position}</h1>`;
});
app.directive('focus', {
inserted: el => {console.log('聚焦!');
el.focus();},
});
// 至此,所有在 app 所蕴含的组件树内创立的 Vue 实例才会共享 trump-sucks 这个组件和 focus 这个指令,而 Vue 构造函数并没有被净化。
多个利用实例的配置共享
上文提到的“不是所有开发者都想要的全局配置共享”,在 Vue 3 中能够通过工厂函数的形式实现:
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');
这样就能实现多个利用实例的配置共享了:蔡徐坤和吴亦凡都有了一个叫做“唱跳”的 Vue 自定义指令。
想要理解更多信息,请拜访官网:https://v3.vuejs.org/guide/mi…(目前还没有中文版)
文章首发于我的卫星攻肿号,请点击:这里