Vue3.0

news/2024/11/30 1:49:44/

Vue3.0


动机与目的

更好的逻辑复用 与 代码组织 (composition组合式api)
optionsAPI(旧) => compositionAPI(新), 效果: 代码组织更方便了, 逻辑复用更方便了 非常利于维护!!
更好的类型推导 (typescript支持)
**vue3 源码用 ts 重写了, vue3 对 ts 的支持更友好了 (ts 可以让代码更加稳定, 类型检测! )**


vue3.0优点

性能方面

  • 打包大小减少
  • 初次渲染快 , 更新渲染快
  • 内存减少

源码方面

  • 移除一些冷门 API,比如 filter、inline-template 等,体积减少
  • 引入 tree-shaking 减少打包体积(通过编译阶段的静态分析,找到没有引入的模块并打上标记,并且移除)
  • 使用 Proxy 代替 defineProperty 实现响应式。
  • Vue3 可以更好的支持 TypeScript
  • Composition API(组合 API)可以按需使用,多余勾子配置不用再次打包

Vue3.0响应式原理

vue2.x 通过 Object.defineProperty()实现的响应式原理存在以下问题

  • 新增属性、删除属性, 监听不到变化从而不是响应式数据,页面也不会改变
  • 直接通过下标修改数组也监听不到。 对此 vue3.0 解决了这些问题

proxy 简介(3.x)

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 对象上。现阶段,某些方法同时在 ObjectReflect 对象上部署,未来的新方法将只部署在 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.deleteProperty(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)},
})

生命周期介绍

Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有2个钩子发生了改变 - beforeDestroy改名为beforeUnmount(卸载前) - destroyed改名为unmounted(卸载) 与vue2不同的是,vue3中是有了el模板之后才会去初始化,而vue2中是先created之后再去找模板
分为2种形式的生命周期勾子


组合式 api(Composition API)

setup

它是 vue3 中一个新的配置项,值为一个函数。所有的组合 api 都要在它里面使用

使用介绍

  1. 使用变量 或者事件 需要把名字 return 出去即可在模板中使用。
export default {setup() {let name = 'zhang'function at() {console.log(1)}return {name,at,}},
}
  1. setup 函数的两种返回值,一种就是上面常规返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用,还有一种就是返回一个函数
// 若返回一个渲染函数:则可以自定义渲染内容
import { h } from 'vue'
export default {setup() {return () => h('h1', '你好')},
}

注意事项:

  1. 注意 vue3 虽然可以向下兼容 vue2,但是尽量不能混合使用
  2. Vue2.x 配置(data、methos、computed...)中可以访问到 setup 中的属性、方法
  3. 由于 setup 中没有 this,所以 setup 中没办法读取 Vue2.x 配置中的数据和方法
  4. 如果有重名, setup 优先
  5. setup 执行的时机是最早的,在 beforeCreate 之前执行,所以此时 this 是 undefined
  6. 参数问题 setup 接收 2 个参数
props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。context:上下文对象
- attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 ```this.$attrs```- slots: 收到的插槽内容, 相当于 ```this.$slots```- emit: 分发自定义事件的函数, 相当于 ```this.$emit```
// 在子组件中
export default {props: ['msg', 'school'],emits: ['hello'],setup(props, context) {// props接收props配置项中的相应式数据{msg:'',school:''}// context相当于上下文对象,里面有三个值attrs,slots,emit//方法function test() {// 调用父组件方法context.emit('hello', 666)}return {test,}},
}

ref 函数

作用: 定义一个响应式的数据(主要针对基础类型数据) 方法:引入 ref 函数,const xxx = ref(initValue) 模板中读取数据: 不需要.value,直接:`<div>{{xxx}}</div>

处理基本数据类型

RefImpl 对象中.value 是基础类型时,用的是 Object.defineProperty 通过 getset 实现的响应式数据

import { ref } from 'vue'
export default {setup() {let name = ref('张三')function change() {console.log(name, 'name')//ref加工之后生成一个 RefImpl引用对象,该对象的原型对象上可以发现,底层其实还是Object.defineProperty通过// get 和set实现的响应式数据// 因此改变基本数据需要用到RefImpl引用对象中的value属性name.value = '小明'}return {name,change,}},
}

处理对象类型

RefImpl 对象中.value 是对象类型,用的是 proxy 代理对象实现的响应式数据

import { ref } from 'vue'
export default {setup() {let obj = ref({name: '小明',age: 20,})function change() {obj.value.name = '小工'obj.value.age++console.log(obj.value)//可以发现是一个Proxy 对象,其本质其实调用的是```reactive```函数实现Proxy代理响应式对象}return {obj,change,}},
}

reactive 函数

作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数) 方法:const x= reactive(源对象)接收一个对象(或数组),返回一个代理对象(Proxy 的实例对象,简称 proxy 对象) 特点:可以实现数组、深层对象的响应式数据,这是 vue2.0 中无法实现的,底层基于 Proxy

export default {setup() {let obj = reactive({name: '小明',age: 20,})function change() {console.log(obj, 'obj')//可以发现obj此时就是一个Proxy的实例对象可以直接修改对象内部属性obj.name = '小三'obj.age++}return {obj,change,}},
}

总结 ref 和 reactive

从定义数据角度对比

  • ref 用来定义:基本类型数据。ref 也可以用来定义对象(或数组)类型数据, 它内部会自动通过reactive转为代理对象
  • reactive 用来定义:对象(或数组)类型数据。

从原理角度对比

  • ref 通过Object.defineProperty()getset来实现响应式(数据劫持)。
  • reactive 通过使用 Proxy 来实现响应式(数据劫持), 并通过 Reflect 操作源对象内部的数据。

http://www.ppmy.cn/news/59036.html

相关文章

什么是Java中的注解?

Java中的注解&#xff08;Annotation&#xff09;是一种元数据&#xff0c;用于为Java代码提供额外的信息和指示&#xff0c;例如代码的作用、编译时处理方式、运行时行为等等。注解可以通过在代码中添加注解元素来指定其属性值&#xff0c;从而对代码进行自定义和扩展。 Java…

LiangGaRy-学习笔记-Day10

1、知识回顾 1.1、rpm依赖报错问题 rpm安装的时候&#xff0c;会有依赖报错rpm安装httpd服务&#xff0c;体现报错 #rpm安装httpd [rootNode1 ~]# rpm -ivh /mnt/cdrom/Packages/httpd-2.4.6-88.el7.centos.x86_64.rpm warning: /mnt/cdrom/Packages/httpd-2.4.6-88.el7.ce…

【数据结构】JDK HashMap源码解析

目录 &#x1f31f;HashMap源码解析 &#x1f308;类的属性 &#x1f308;构造方法 &#x1f308;put方法 &#x1f31f;对比常用Map的子类实现: &#x1f31f;HashMap源码解析 JDK8之前&#xff0c;HashMap就是数组链表&#xff1b; JDK8之后&#xff0c;变成了数组链表红…

基础的文件操作

目录 ❤ 什么是文件&#xff1f; ❤ 为什么要有文件&#xff1f; ❤ 如何用文件&#xff1f; 从硬盘中读取数据 写入数据 ❤ 总结 python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129328397?spm1001.2014.3001.5502 虽然视…

【看表情包学Linux】软硬链接

&#x1f923; 爆笑教程 &#x1f449; 《看表情包学Linux》&#x1f448; 猛戳订阅 &#x1f525; &#x1f4ad; 写在前面&#xff1a;上面我们学到的所有东西&#xff0c;全部都是在内存中的。是不是所有的文件都被打开了呢&#xff1f;不是所有的文件&#xff0c;都被打开…

​kali下搭建WiFi钓鱼热点​

在linux下建立无线热点并不像在windows下开启网络共享或者使用无线网卡驱动设置AP模式即可。 linux下的无线共享要用到两个软件&#xff1a;hostapd(创建无线热点)、dnsmasq(dns服务和dhcp服务). 1.安装以上两个软件&#xff1a; 1 2 apt-get install hostapd apt-get install…

【Windows】git多帐号配置

【Windows】git多帐号配置 &#x1f4d4; 千寻简笔记介绍 千寻简笔记已开源&#xff0c;Gitee与GitHub搜索chihiro-notes&#xff0c;包含笔记源文件.md&#xff0c;以及PDF版本方便阅读&#xff0c;且是用了精美主题&#xff0c;阅读体验更佳&#xff0c;如果文章对你有帮助…

【Java笔试强训 20】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;字符串反…