从一个入口开始
vue3从发布正式版到现在已经过去半年左右,大家聚焦讨论的重点集中在响应式api 和组合式api,无可厚非,这俩个api的变化确实可以直接影响到整个vue应用的开发方式和体验,今天我们来谈一个不那么起眼的小知识点
相信大家在使用vue-cli脚手架开发vue应用的时候,一定在src/main.js里见过这样的代码
new Vue({
render: h => h(App)
}).$mount('#app')
一切从new一个vue实例开始,然后当你使用vue3进行开发的时候,同样是入口文件main.js,却变成了下面这样
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
一切从一个createApp方法的执行开始,那vue3为什么把应用的初始化变成这样子,和new Vue相比,createApp有哪些好处呢?
createApp的好处
想象一个场景:我们需要开发一个比较大的vue应用,团队A需要一个vueA实例对象,它拥有全局组件ShowDialog,团队B需要一个vueB实例对象,它不需要全局组件showDialog,要求俩个vue实例的功能要完全独立,相互隔离,该如何实现?
vue2中,我们可能会写出这样的代码
以上,我们通过new操作符,连续实例化了俩个vue实例A和B,并且注册好了一个全局组件,我们期待全局组件只能在实例A控制的视图区域中使用,然而这是行不通的,因为vue2的组件系统设计中,所有的vue实例是共享一个Vue构造函数对象的(包括全局指令/全局组件等),无法做到完全隔离
看vue3中如何解决该问题
createApp方法可以返回一个提供应用上下文的应用实例,应用实例挂载的整个组件树共享同一个上下文
以上,我们使用vue3中的createApp方法进行实例创建,这一次创建出来的实例A和B拥有完全隔离的环境,这一次我们的show-dialog组件,在vueA实例控制的视图中是完全全局可用的,而在vueB控制的视图区域是不可用的(如果你想在A和B环境*享,把show-dialog组件配置项抽离出来,各自注册一下即可)大家可以把案例中的vueA 和 vueB想象成俩个完全不同的应用实例,它们各自为营,互不影响,完全隔离,同样也可以*的选择要共享哪些东西
场景应用
我们可能会奇怪,做了蛮多的vue项目,貌似很少见到有多次new Vue的情景,事实上随着项目规模的扩大,由独立团队共同协作开发项目以及前端微服务的普及,你可能会在某个时候发现自己也需要这样做,说的简单一点,如果多个单页应用由多个团队一起开发,并且共享一套js运行环境的时候,隔离就显得格外的重要了
所以某种程度上,createApp 新api的产生算是一种前瞻性的面向未来的设计,你可以*的选择当前需要几个应用实例,并且可以在隔离环境的前提下*的组合需要共享的东西,不是吗?nice