Vue 3:全局 API 被取消了?

网友投稿 280 2023-05-19

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>`;  });  1.2.3.4.

或者声明一个全局指令:

复制Vue.directive(focus, {    inserted: el => {      console.log(聚焦!);      el.focus();    },  });  1.2.3.4.5.6.

这样确实比较方便,但是会造成一些问题。首先要明确的一点是,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 });  1.2.3.4.

还有一个避免不了的问题是,一旦页面上有多个 Vue 实例时,它们的全局配置就很自然地共享了,但在很多时候开发者并不想要这样的结果

复制Vue.mixin({    mounted: () => {      console.log(wubba lubba dub dub);    },  });  const rick = new Vue({ el: #rick });  const morty = new Vue({ el: #morty });  1.2.3.4.5.6.7.8.

因此,为了规避这些问题,Vue 3 引入了应用实例的概念。

全局 API: createApp

调用 createApp 会返回一个 应用实例,没错,应用实例这个概念是 Vue 3 中新引入的。

复制import { createApp } fromvue const app = createApp();  1.2.

应用实例会暴露一个当前全局 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。

[[334669]]

挂载一个应用实例

在使用 createApp(VueInstance) 得到一个应用实例后,这个应用实例就可以用来把整个 Vue 跟实例挂载到页面上了:

复制import { createApp } fromvue import MyApp from./MyApp.vue const app = createApp(MyApp);  app.mount(#app);  1.2.3.4.5.

在完成了这些改造之后,开篇我们提到的那些例子将会重写成这样:

复制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 构造函数并没有被污染。  1.2.3.4.5.6.7.8.9.10.11.12.13.

多个应用实例的配置共享

上文提到的“不是所有开发者都想要的全局配置共享”,在 Vue 3 中可以通过工厂函数的方式实现:

复制import { createApp } fromvue 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);  1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.

这样就能实现多个应用实例的配置共享了:蔡徐坤和吴亦凡都有了一个叫做“唱跳”的 Vue 自定义指令。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:用好 ChatGPT,让你工作效率提升10倍
下一篇:【重磅消息】OpenAI 开放的GPT3.5-Turbo,价格直接降了90%
相关文章

 发表评论

暂时没有评论,来抢沙发吧~