浅析 Vue 3.0 的组装式 API(一)
(一)响应式数据
1.简单例子
从最简单的数据绑定开始,在Vue2.0中,我们这样将一个数据绑定到模板的指定位置:
在组件创建参数的data构造函数中返回一个用来绑定的数据对象,其中有个now字段,会被渲染到模板内的.app>p内。
Helloworld!
Nowis:{{now.toString()}}
用Vue3的组装API实现的话,则是这样:
//Vue3.0 exportdefault{ setup(){ return{ now:newDate(), }; }, };
2.更新数据
奇怪,看起来好像没啥区别,只是把data改成了setup吗?
并不是,假如我们现在对这个DEMO做个小改动,让它每秒钟刷新一次时间,用Vue2大概是这样实现:
//Vue2.0 exportdefault{ data(){ return{ now:newDate(), }; }, mounted(){ setInterval(()=>this.now=newDate(),1000); }, };
而Vue3的等效实现则为:
//Vue3.0 import{ref,onMounted}from'vue'; exportdefault{ setup(){ constnow=ref(newDate()); onMounted(()=>{ setInterval(()=>now.value=newDate(),1000); }); return{ now, }; }, };
3.对比分析
写了太多Vue的我们可能已经忘了,Vue2的代码从标准JS模块的角度来看有多奇怪:
- mounted中修改的this.now数据是在哪创建的?我们在模块default对象的成员里并没有找到对应字段,倒是在data内返回的另一个对象中有这个字段;
- 而data中返回的now也不是真正的this.now,而是this.now的初始值,在data中setInterval修改now并不能更新渲染出来的时间;
- 如果想复用这个数据和它的更新逻辑,你必须将这样的结构单独写一份,然后通过特殊的mixin函数混入到当前组件的构造参数内。
这一切,是因为整个模块default对象其实是vm对象的构造参数。其背后隐藏了对象的创建逻辑,在构造对象时构造参数中的一些不同层级的字段被绑定到了vm对象上。
不少新手可能都犯过一个错误,在data中返回的数据字段和props、methods或者computed中的字段命名撞车(尤其是使用名为data的字段),在编码阶段并不能被IDE直接发现。就是因为上面的原因,这些字段创建时隶属于不同的位置,在之后构造时才被绑在了同一个对象上,导致了运行时才能发现的冲突。
Vue3中,改成提供ref、reactive、toRef、onMounted等函数的形式实现,例子中:
- 在setup中看到的now即是用于绑定的this.now;
- 修改now.value即可看到页面状态的更新;
- 如果要封装这份数据处理,只需要将now和onMounted处理提取到同一个函数内,再将now返回即可,不再需要黑盒的mixin处理。
可以说Vue3是直接将响应数据的创建决定权、生命周期的通知回调,都通过API的形式交给了开发者,更直观明了和可控。
4.API说明
下面详细说说常用的几个响应式数据相关API:ref,reactive和toRefs。
(1)ref
上面例子中使用到的ref,可以将一个数据包装成响应式数据代理对象。
constcount=ref(0); console.log(count.value);//=>0 count.value++; console.log(count.value);//=>1
当你修改代理对象的count.value属性时,模板中使用到count的位置将响应数据的变化,更新视图中的数据状态。
(2)reactive
对于对象的响应式封装,使用ref稍显麻烦:
conststate=ref({ count:0, }); console.log(state.value.count);//=>0 state.value.count++; console.log(state.value.count);//=>1
这时可以改为使用reactive,像操作普通对象的字段一样修改count即可更新视图:
conststate=reactive({ count:0, }); console.log(state.count);//=>0 state.count++; console.log(state.count);//=>1
对代理对象state添加新的字段也可触发视图更新。
(3)toRefs
有时候,对象的名字过长,我们想直接在模板内使用对象内部字段,直接使用解构是不行的:
import{reactive}from'vue'; exportdefault{ setup(){ constposition=reactive({ x:0, y:0, }); return{ //错误,解构出来的x,y并没有响应式代理。绑定到模板上后,数据变化无法触发视图更新 ...position, }; }, };
这个情况下,使用toRefs处理后再解构赋值即可:
import{reactive,toRefs}from'vue'; exportdefault{ setup(){ constposition=reactive({ x:0, y:0, }); return{ ...toRefs(position), }; }, };
但需要注意,toRefs只处理调用时position的现有字段,如果在之后对position增加新字段,将无法触发视图更新。
以上就是浅析Vue3.0的组装式API(一)的详细内容,更多关于Vue组装式API的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。