Vue2和Vue3的区别之一就是对于全局扩展属性的挂载方式变了,以前Vue2的挂载方式可以直接通过property进行原型挂载,而Vue3却需要使用app.config.globalProperties实现属性的全局挂载。
Vue2和Vue3组件的创建方式不同
vue2的创建方式是基于Vue构造函数创建的 实例化对象,而vue3则是通过creatApp来创建实例。从创建方式上我们就已经可以看出为什么使用原型挂载无法挂载到实例化对象中
vue2
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
vue3
import { createApp } from 'vue'
const app = createApp({ /* 根组件选项 */ })
createApp 函数
从该函数中我们可以看到createApp是先创建一个渲染器,然后该函数提供了createApp函数
createApp
export const createApp = ((...args) => {
const app = ensureRenderer().createApp(...args)
...
return app
}) as CreateAppFunction<Element>
baseCreateRenderer函数,这个函数返回了createAppAPI函数作为我们执行的createApp函数
function baseCreateRenderer(
options: RendererOptions,
createHydrationFns?: typeof createHydrationFunctions
): any {
return {
render,
hydrate,
createApp: createAppAPI(render, hydrate)
}
}
createAppAPI函数中 config属性是通过 get,set形式声明的,也就是我们传入什么就返回什么,而且这个函数还提供了其它原先在Vue2.0中的方法比如use,component,mount,unmount等方法。该函数执行所返回的是一个对象,而不是通过构造函数创建的实例化对象。
export function createAppAPI<HostElement>(
render: RootRenderFunction<HostElement>,
hydrate?: RootHydrateFunction
): CreateAppFunction<HostElement> {
const app: App = (context.app = {
_uid: uid++,
_component: rootComponent as ConcreteComponent,
_props: rootProps,
_container: null,
_context: context,
_instance: null,
version,
get config() {
return context.config
},
set config(v) {},
use() {},
mixin() { },
component() { },
directive() {},
mount() {},
unmount() {},
provide(key, value) {},
runWithContext(fn) {}
})
return app
}
总结
vue3.0 改变了原先new组件创建对象的方式,选择了通过createApp的方式创建对象,这样的好处是,我们在单个页面创建多个vue实例时,可以根据需求挂载不同的公用函数到不同的实例上,避免了多个对象之间的原型污染问题。