Vue2.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:'Americapresident',}),template:`
Trumpistheworst${position}
`;});或者声明一个全局指令:Vue.directive('focus',{inserted:el=>{console.log('focus!');el.focus();},});这样确实比较方便,但是会带来一些问题,首先要明确的是Vue2.x在设计上没有app(应用)的概念,开发者正在使用Vue2.x的是所谓的应用程序,它只是一个使用newVue()创建的Vue实例(啊,但就是这样)。由同一个Vue构造函数创建的Vue实例将共享来自构造函数的全局配置。这将导致:在测试过程中,由于g的存在局部配置,测试用例很容易被“污染”。开发者需要仔细找一个地方保存全局配置,每次测试后恢复,比如Vue.config.errorHandler;Vue.use和Vue.mixin等一些API甚至没有办法避免它的影响。一旦测试涉及插件,这使得整个过程非常棘手。其实为了解决这个问题,vue-test-utils不得不引入一个特殊的API:createLocalVue:import{createLocalVue,mount}from'@vue/test-utls';constlocalVue=createLocalVue();localVue.use(MyPlugin);mount(组件,{localVue});另一个无法回避的问题是,一旦页面上有多个Vue实例,它们的全局配置自然是共享的,但很多时候开发者并不希望这样的结果Vue.mixin({mounted:()=>{console.log('wubbalubbadubdub');},});constrick=newVue({el:'#rick'});constmorty=newVue({el:'#morty'});因此,为了避免这些问题,Vue3引入了应用实例的概念。全局API:createApp调用createApp会返回一个应用实例,没错,应用实例的概念是Vue3新引入的。import{createApp}from'vue';constapp=createApp();应用实例会暴露出当前的全球API。在这次重构工作中,Vue团队遵循了一条经验法则:任何影响Vue全局行为的API都将迁移到应用程序实例中。2.x全局API3.x应用程序实例APIVue.configapp.configVue.config.productionTip移除Vue.config.ignoredElementsapp.config.isCustomElementVue.componentapp.componentVue.directiveapp.directiveVue.mixinapp.mixinVue.useapp.use其他不影响Vue全局行为的API全部转化为命名exports,正如之前游与戏游达在直播中所说:为了支持TreeShaking。挂载一个应用实例使用createApp(VueInstance)得到一个应用实例后,可以使用这个应用实例将整个Vue和实例挂载到页面:import{createApp}from'vue';importMyAppfrom'./MyApp.vue';constapp=createApp(MyApp);app.mount('#app');完成这些改造后,我们一开始提到的例子将被改写为:app.component('trump-sucks',{data:()=>({position:'美国总统',}),template:`
Trumpisttheworst${position}
`;});app.directive('focus',{inserted:el=>{console.log('Focus!');el.focus();},});//此时,应用包含的组件树中创建的所有Vue实例将共享Trump-sucks组件和focus指令,而Vue构造函数没有被污染。多个应用实例的配置共享上面提到的“不是所有开发者都想要的全局配置共享”在Vue3中可以通过工厂函数来实现:import{createApp}from'vue';importCaiXuKunfrom'。/CXK.vue';importWuYiFanfrom'./WYF.vue';constcreateIdolApp=(IdolInstance)=>{constidolApp=createApp(IdolInstance);idolApp.directive('sing-and-dance',{inserted:()=>{console.log('Iamcool!');},});}createIdolApp(蔡徐坤).mount('#caixukun');createIdolApp(吴亦凡).mount('#吴亦凡');从而实现多个应用实例的配置共享:蔡徐坤和吴亦凡都有一个Vue自定义命令叫“唱歌跳舞”。