一、vue3的新特性
- 向下兼容vue2
- 性能提升(打包的大小减少了41%,初次渲染快了55%,更新快了133%,内存使用减少了54%)
- CompositionAPI集合,解决vue2的一些组件开发问题
- 响应式原理由defineProperty变为Proxy
- 编译优化
- 提升了对TypeScript的支持
- createApp()方法创建实例
- 避免了this,生命周期的复杂性
- vue2.0大量的api挂在Vue实例对象上,难以实现treeshaking
- 重写了虚拟DOM,对模板编译进行了优化
- vite打包工具
二、安装配置
我们可以通过两个脚手架来安装:
1.脚手架 Vite
//npm
npm init vite-app hello-vue3
//yarn
yarn create vite-app hello-vue3
这种方式出来的脚手架只有最基础的配置,其他的路由和vuex都需要自己配置
2.脚手架 vue-cli
npm install -g @vue/cli
OR
yarn global add @vue/cli
OR
vue create hello-vue3
三、main.js
在入口处的main.js这里,对比之前的vue2,已经不是new了
vue2 main.js:
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App),
}).$mount('#app')
vue3 main.js
import { createApp } from 'vue'
import router from './router'
import store from './store'
import App from './App.vue'
// 如果你有更多的插件要引入需要用到use,而这里变化成链式调用了
createApp(App).use(router).use(store).mount('#app')
四、响应式Proxy
Proxy(vue3.0) vs Object.defineProperty(vue2.0)
vue2.0响应式原理
- 响应化过程需要遍历data,props等,消耗较大
- 不支持Set/Map、class、数组等类型
- 新加或删除属性无法监听
- 数组响应化需要额外实现
- 对应的修改语法有限制
vue3.0响应式原理
- 使用ES6的Proxy来解决这些问题。
- 通过Proxy代理,来拦截对data的一系列的操作。
五、vue3新特性的使用
composition API
当组件变得越来越大时,逻辑关注点的列表也会随之增长,这可能会导致组件难以阅读和理解,且碎片化使得理解和维护复杂组件变得更加的困难。选项的分离掩盖了潜在的逻辑问题,此外,在处理单个逻辑关注点的时候,我们必须不断地“跳转”相关代码的选项快。 这个时候composition API 应运而生。在使用Composition API的位置被称之为setup。
setup函数
setup函数是一个新的vue组件选项,是用于在组件中Composition API的入口
注意:由于在执行 setup 时尚未创建组件实例,因此在 setup 选项中没有 this。这意味着,除了 props 之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。
在使用setup函数时,它将接受两个参数:
- props
- context
Props
他是setup的第一个参数,而它也是响应式的,当传入新的prop的时候,它将被更新
export default {
props: {
title: String
},
setup(props) {
console.log(props.title)
}
}
注意: 因为
props是响应式的,不能使用ES6解构,因为它会消除prop的响应性。
而如果真的需要解构prop,可以通过使用setup函数中的toRefs来安全的使用。
import { toRefs } from 'vue'
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
}
context
它是 setup的第二个参数,context 是一个普通的 JavaScript 对象,它暴露三个组件的 property:
export default {
setup(props, context) {
// Attribute (非响应式对象)
console.log(context.attrs)
// 插槽 (非响应式对象)
console.log(context.slots)
// 触发事件 (方法)
console.log(context.emit)
}
}
- context是一个普通的JavaScript对象,也就是说,它不是响应式的,可以直接解构
- attrs和slots是内部组件实例上相应值的代理。这样可以确保它们即使在更新后也始终会显示最新值,以便我们可以对它们进行结构分解,而不必担心访问老的引用:
- 但避免对内部的属性进行解构,并始终以attrs.x或slots.x的方式使用