Appearance
全面拥抱 Vue 3
相较于 Vue 2.0
1. 源码组织上的变化
在 Vue 2
中,所有的源码都存在在 src
目录下:
Vue 3
相对于 Vue 2
使用 monorepo
的方式进行包管理,使用 monorepo
的管理 方式,使得 Vue 3
源码模块职责显得特别地清晰明了,每个包独立负责一块核心功能的 实现,方便开发和测试。
比如,compiler-core
专职负责与平台无关层的渲染器底层,对外提供统一调用函数,内 部通过完整的测试用例保障功能的稳定性。而 compiler-dom
和 compiler-ssr
则依托 于 compiler-core
分别实现浏览器和服务端侧的渲染器上层逻辑,模块核心职责清晰明 了,提高了整体程序运行的健壮性!
2. 引入 Composition API
3. 运作机制的变化
- 之前通过
new Vue()
来创建Vue
对象的方式已经变成了createApp
; - 在响应式部分也由原来的
Object.defineProperty
改成了现在的Proxy API
实现; - 针对响应式依赖收集的内容,在
Vue 2.x
版本中是收集了Watcher
,而到了Vue 3
中则成了effect
。
Object.defineProperty
Object.defineProperty 是拦截对象的具体的某个属性
const person = {};
Object.defineProperty(person, 'name', {
set (value) {
console.log('name:', value)
},
get () {
return '小明'
}
});
console.log(person.name);
- 无法监听整个对象,只能对每个属性单独监听
- 无法监听对象的属性的新增,删除(需要补充额外的 api 来解决)
- 无法监听数组的变化
proxy
真正地对整个对象进行代理,因为 proxy 可以劫持整个对象
const person = {
name: '小明',
age: 18
};
const personProxy = new Proxy(person, {
get: function(target, prop) {
console.log(`获取了${prop}:`, target[prop]);
return target[prop];
},
set: function(target, prop, value) {
console.log(`修改了${prop}:`, value);
target[prop] = value;
}
});
console.log('name:', personProxy.name); // 获取了name:小明
personProxy.age = 20; // 修改了age:20
createApp 的非兼容性变更
vue2
:全局公用同一个 Vue
根实例,当我们有多个 Vue 实例的时候,其他的实例也被 迫接受了这个全局组件
全局对象被共享是一件非常危险的事情,研发中我们也尽量避免往全局对象下挂载内容, 很容易与其他模块定义的全局变量产生冲突,更何况一般的项目都是多人开发,谁也不能 保证自己定义的内容不会与其他人冲突(模块化的重要性吶)。
// 引入全局组件
import GlobalComponent from './GlobalComponent.vue';
// 注册全局组件
Vue.component('GlobalComponent', GlobalComponent);
// 下面两个实例都接受了全局组件
new Vue({
render: h => h(App),
}).$mount('#app');
new Vue({
render: h => h(App2),
}).$mount('#app2')
vue3
:不直接在 Vue 对象上进行操作,而是通过 createApp
来创建一个 App 应用实 例
// 引入封装好的store
import store from "./store";
createApp(App).use(store).mount('#app');
createApp(App2).mount('#app2');
下载 Vue 3 源码,开始深层学习