vue3.0之什么是组合式和选项式,什么是hook,vue3.0和vue2.0的响应式数据原理和区别,Vue2 常见的缺陷,Vue3 的新特性,
vue3.0之什么是组合式和选项式,什么是hook,vue3.0和vue2.0的响应式数据原理和区别,Vue2 常见的缺陷,Vue3 的新特性,
选项式(Options API)
vue2中如何组织代码的:我们会在一个vue文件中data,methods,computed,watch中定义属性和方法,共同处理页面逻辑
优点:新手上手简单
缺点:上图解释了Options API 的缺点,一个功能往往需要在不同的vue配置项中定义属性和方法,比较分散
项目小还好,清晰明了,但是项目大了后,一个methods中可能包含很多个方法,往往分不清哪个方法对应着哪个功能,而且当你想要新增一个功能的时候你可能需要在 data,methods,computed,watch中都要写一些东西,但是这个时候每个选项里面的内容很多你需要上下来回的翻滚,就特别影响效率
组合式(Composition API)
缺点:学习成本可能会增加,以前的思维方式也要转变
优点:Composition API 是根据逻辑相关性组织代码的,提高可读性和可维护性,基于函数组合的 API 更好的重用逻辑代码(在vue2 Options API中通过Mixins重用逻辑代码,容易发生命名冲突且关系不清)
Composition API最大的优点:通俗的讲就是把跟一个功能相关的东西放在一个地方,它是目前最合理也是最容易维护的,你可以随时将功能的一部分拆分出去
你可以将每一个功能相关所有的东西比如methods,computed都放在如上图的function中,这个function可以独立的存在,可以放在一个TS文件中,也可在npm中单独发布,最终Composition API把他们组合起来
参考文章链接:https://juejin.cn/post/6966606592024576013
什么是hook
官方提供的一种函数式钩子
调用他们提供的具有功能的函数 然后把我们的业务函数传入给它
就可以实现组件想用外部功能时 直接引入使用 不想用就不引入
它是一种事件劫持机制,可以比事件更早进行执行处理
钩子可以理解为vue的内置事件,但是这个内置事件需要主动去配置,可以用来处理被拦截的函数调用、事件和消息
hook的代码是写在 vue3.0 的setup函数内部的
vue3中的setup函数的理解
- setup 语法 返回的对象的成员可以在模板中使用 也可以在组件的api中使用,是组合式api的入口, 但是这个函数中不能使用组件api中的东西
- setup是处于beforecreate和created生命周期间的函数
- setup函数中可以声明一些变量或者函数,然后返回出去,供组件使用
- setup函数内部的变量可以去设计为响应式的变量 那么可以使用官方的hook,也就是ref reactive等工具
- setup函数中定义的变量和方法都是需要return出去的,不然没有办法在模板中使用,但如果用语法糖就不需要了
- setup函数可以设计成 script标签中写这个同名单词的属性 然后使整个标签环境都为setup函数环境(脚手架实现的),也就是 setup 的语法糖
- 特点
1.这个函数内部的变量/函数是局部的
2.这个函数的返回值可以被当前组件的任意地方使用
3.这个函数内部不使用this来操作组件数据
4.setup返回的对象中的数据和data中的数据同名了 setup 优先级更高
5.setup在组件加载期间只会运行一次
vue3响应式数据怎么设计的?
ref响应式设计?
就是监听了value的改变 劫持value属性的setter getter
因此ref一般用在基本数据,或者引用数据的嵌套层级不深得数据上
reactive响应式设计?
跟ref一样 但是底层采用的是ES6的Proxy代理了整个引用数据
ref 和 reactive
ref 的作用就是将一个原始数据类型转换成一个响应式数据
原始数据类型共有 7 个,分别是:String、Number、BigInt、Boolean、Symbol、Undefined、Null
当 ref 作为渲染上下文 (从 setup() 中返回的对象) 上的 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加
reactive 的作用就是将一个对象转换成一个响应式对象
toRefs 的作用是将一个响应式对象转化为一个普通对象,把其中每一个属性转化为响应式数据
为什么需要 toRefs ?
reactive 转化的响应式对象在销毁或展开(如解构赋值)的时候,响应式特征就会消失
为了在展开的同时保持其属性的响应式特征,我们可以使用 toRefs
Vue3 数据响应式的原理
Vue3 会对需要转化为响应式的普通 JavaScript 对象转换为 Proxy。proxy 对象对于用户来说是不可见的,但是在内部,它们使 Vue3 能够在 property 的值被访问或修改的情况下进行依赖跟踪和变更通知。并且在 Vue 3 中,响应性数据可以在『独立的包』中使用。
Vue3 中同样每个组件实例都有一个相应的侦听器实例,该实例将在组件渲染期间把“触碰”的所有 property 记录为依赖项。之后,当触发依赖项的 setter 时,它会通知侦听器,从而使得组件重新渲染
vue2响应式数据怎么设计的?
在 Vue2 中,我们只需要把数据放入 data 函数中,Vue2 会遍历 data 中的所有属性,使用 Object.defineProperty 把每个 property 全部转为 getter/setter
getter 用来收集依赖,setter 用来执行 notify,发布更新事件
Vue2 对每个属性创建一个 Dep 对象,作为订阅发布模式的中间机构来收集依赖。Vue 追踪这些依赖,在其被访问和修改时通知变更
Vue2 中每个组件实例都对应一个 Watcher 实例,调用组件的 render 函数,若没有 render 函数,会执行模板编译过程,生成 render 函数
render 函数执行时,会访问定义在模板里的各属性,会触发之前定义的 getter,收集依赖,将当前的 Watcher 注册到 dep 当中。之后当依赖项的 setter 触发时,会通知 Watcher,从而使它关联的组件重新渲染
但是 Vue2 里的数据响应式其实是一个半完全体,它对于对象上新增属性无能为力,对于数组则需要拦截它的原型方法来实现响应式
于是 Vue2 又引入 $set 解决以上问题
vm.$set(vm.someObject,'b',2) // vm.$set 实例方法是全局 Vue.set 方法的别名
Vue.set(vm.someObject, 'b', 2) // 所以也可以这样写
Proxy 和 Object.defineProperty 比较
Proxy 和 Object.defineProperty 的使用方法看起来相似,其实 Proxy 是在 「更高维度」 上去拦截属性的修改的
Object.defineProperty 有两大缺陷
无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;
只能劫持对象的属性,从而需要对每个对象的每个属性进行遍历,如果属性值是对象,还需要深度遍历
Proxy
Proxy 可以劫持整个对象,并返回一个新的对象
Vue2 常见的缺陷
从开发维护的角度考虑:Vue2 使用 Flow.js 做类型校验,但是现在 Flow.js 已经停止维护;并且 Option API 在组织代码较多组件时不易维护
从社区的二次开发难度:Vue2 内部运行时直接执行浏览器 API,这会给 Vue2 的跨端带来问题。只能在 Vue 源码中进行相应的处理(例如 Vue2 中存在 Weex 的文件夹)
从日常使用的角度:Vue2 的响应式并不是真正意义上的代理,而是基于 Object.defineProperty() 实现的。这个 API 是对某个属性进行拦截,因此有很多缺陷(例如无法监听删除数据)
Vue3 的新特性
Vue3 中使用 Proxy API 对数据进行代理(这个 API 是真正的代理,不过存在一些兼容性问题)
Vue3 把响应式、编译和运行时全部独立了(Vue2 内部所有模块都糅合在一起)
Vue3 全部模块使用 TypeScript 重构
Vue3 使用 Composition API(组合式 API)
Vue3 内置了 Fragment、Teleport、Suspense 三个新组件
参考文章链接:https://zhuanlan.zhihu.com/p/357434039
更多推荐
所有评论(0)