download:https://www.sisuoit.com/3386.html
简介
vue3.0 向下兼容 vue2.x 版本,优化了主要核心双向绑定原理和体积大小,并且更加友好的兼容 ts 语法。
工程创建
vue-cil 创建
选择 vue3.0 生成项目即可
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve
复制代码
使用 vite 创建
Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。(这里不详细研究)
通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目。
# npm 6.x
$ npm init vite@latest <project-name> --template vue
# npm 7+,需要加上额外的双短横线
$ npm init vite@latest <project-name> -- --template vue
$ cd <project-name>
$ npm install
$ npm run dev
复制代码
对比两种方式创建项目
vite 优势如下:
- 开发环境中,无需打包操作,可快速的冷启动。
- 轻量快速的热重载(HMR)。
- 真正的按需编译,不再等待整个应用编译完成。 传统 webpack 编译:每次执行编译时,都会通过入口 entry 先去找到各个路由,再去加载每个路由各自的模块,然后会进行打包成为 bundle.js 文件,最后才通知服务器热更新。所以换句话说就是等所有文件加载就绪之后才去渲染更新页面的==》较慢
\
vite 编译:与传统构建不同的是,vite 会先准备好服务器更新,再去找到入口文件然后再动态的找到需要加载的路由去编译那个路由下的模块,类似于按需加载,总体体积较小且更新更快。
\
vue3.0 优点
性能方面
- 打包大小减少\
- 初次渲染快 , 更新渲染快\
- 内存减少\
源码方面
- 移除一些冷门 API,比如 filter、inline-template 等,体积减少
- 引入 tree-shaking 减少打包体积(通过编译阶段的静态分析,找到没有引入的模块并打上标记,并且移除)
- 使用 Proxy 代替 defineProperty 实现响应式。
- Vue3 可以更好的支持 TypeScript
- Composition API(组合 API)可以按需使用,多余勾子配置不用再次打包。
vue3.0 响应式原理
vue2.x 通过 Object.defineProperty()实现的响应式原理存在以下问题
- 新增属性、删除属性, 监听不到变化从而不是响应式数据,页面也不会改变
- 直接通过下标修改数组也监听不到。 对此 vue3.0 解决了这些问题
proxy 简介
vue 响应式原理本质就是 ES6 新语法 proxy 实现的。 Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写. 接收两个参数,var proxy = new Proxy(target, handler); target 参数表示所要拦截的目标对象,handler 参数也是一个对象,用来定制拦截行为。
// 源对象
let obj = {
name: 'haha',
age: 18,
}
// handler作为拦截配置对象
const p = new Proxy(obj, {
// 读取操作
get(target, propName) {
// get方法接收2个参数 target指源对象,就是obj,propName就是你当前操作的属性
// 返回当前读取的值
return target[propName]
},
// 修改操作,新增属性操作时都会触发
set(target, propName, value) {
// set方法接收3个参数 target指源对象,前面2个与上相同,第三个参数是修改的值
// 通知原对象修改数据
target[propName] = value
},
//删除操作
deleteProperty(target, propName) {
return delete target[propName]
},
})
// 以上 即可实现对象的增删改查的监听,实现数据的相应式
复制代码
Reflect 简介
Reflect 对象与 Proxy 对象一样,也是 ES6 为了操作对象而提供的新 API。具有反射的意思。 将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty),放到 Reflect 对象上。现阶段,某些方法同时在 Object 和 Reflect 对象上部署,未来的新方法将只部署在 Reflect 对象上。也就是说,从 Reflect 对象上可以拿到语言内部的方法。
修改某些 Object 方法的返回结果,让其变得更合理,会有一个布尔返回值,易于捕捉错误(js 单线程,报错会阻塞进程)
// 老写法
try {
Object.defineProperty(target, property, attributes)
// success
} catch (e) {
// failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
let obj = {
name: 'haha',
age: 18,
}
// 三个静态方法:
Reflect.get(obj, 'name') // 返回 haha 读取对象的某个属性的值
Reflect.set(obj, 'name', '小明') // 返回布尔 修改某个属性的值
Reflect.defineProperty(obj, 'name') // 返回布尔 删除某个属性
const p = new Proxy(obj, {
//有人读取p的某个属性时调用
get(target, propName) {
return Reflect.get(target, propName)
},
//有人修改p的某个属性、或给p追加某个属性时调用
set(target, propName, value) {
Reflect.set(target, propName, value)
},
//有人删除p的某个属性时调用
deleteProperty(target, propName) {
return Reflect.deleteProperty(target, propName)
},
})