Vue3中新增API的见解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3中新增API的见解相关的知识,希望对你有一定的参考价值。
参考技术A 一般来说, ref 被用来定义简单的字符串或者数值,而reactive被用来定义对象数组等ref 定义对象时, value 返回的是 proxy , reactive 定义对象时返回的也是 proxy ,而这确实存在一些联系
ref 来定义数据时,会对里面的数据类型进行一层判断,当遇到复杂的引用类型时,还是会使用 reactive 来进行处理
那么能否使用 reactive 来定义普通类型?答案是不行会出现警告,因此 reactive 只能被用来定义对象
如果非要用 reactive 定义基本数据类型的话,我们需要在 reactive 中将数据包装一下
但是使用 reactive 定义的数据和ref定义的数据打印结果有一些差异
注意 ref 定义的数据需要用 .value 获取,但 template 模板中不需要直接写入 return 出去的值即可
Vue3提供了一个新的API: toRef/toRefs ,它可以将一个响应型对象( reactive object ) 转化为普通对象( plain object ),同时又把该对象中的每一个属性转化成对应的响应式属性( ref )。说白了就是放弃该对象( Object )本身的响应式特性( reactivity ),转而给对象里的属性赋予响应式特性( reactivity )。
其实这个不是和 ref 一个意思吗
setup 的执行时组件对象还没有创建,此时不能使用this来访问 setup 里的数据或者操作router和vuex等
我们可以通过 getCurrentInstance 这个函数来返回当前组件的实例对象,也就是当前 Vue 这个实例对象,从而去操作一些数据与方法, getCurrentInstance 函数里的 ctx /proxy 就相当于 this
Java 16 中新增的 Stream 接口的一些思考
这里先提一个题外话,如果想看 JDK 不同版本之间有何差异,增加或者删除了哪些 API,可以通过下面这个链接查看:
- https://javaalmanac.io/jdk/17/apidiff/11/
路径中的两个版本就是要对比的两个版本,其界面如下:
同时,我们也可以通过 JDK 内置 jdeps 工具查找过期以及废弃API以及对应的替换
jdeps --jdk-internals -R --class-path 'libs/*' $project
libs是你的所有依赖的目录,$project是你的项目jar包,示例输出:
...
JDK Internal API Suggested Replacement
---------------- ---------------------
sun.misc.BASE64Encoder Use java.util.Base64 @since 1.8
sun.reflect.Reflection Use java.lang.StackWalker @since 9
Java 16 中针对 Stream API 有两个更新:
增加了 mapMulti
和 toList
这两个 API。
mapMulti
mapMulti
其实主要是对现有的 flatMap
在某些场景使用起来不够合适的补充。flatMap
是将一个对象映射为多个对象之后继续 Stream,例如将 List<List<Integer>>
里面的每一个数字取出,转换成一个新的 List<Integer>
:
integerLists.stream().flatMap(integers -> integers.stream()).collect(Collectors.toList());
这对于每个元素本身就是集合类型的场景来说,非常适用。我们再来看一个例子,假设有邮件这个 Record 类,包含 id,以及发送到的邮箱和抄送到的邮箱:
record Mail(int id, Set<String> sendTo, Set<String> cc)
我们想找到一批邮件的所有不同的联系人,最后放到一个 List 中,可能会这么写:
Set<String> collect = mails.stream().flatMap(mail ->
Set<String> result = new HashSet<>();
result.addAll(mail.sendTo());
result.addAll(mail.cc());
return result.stream();
).collect(Collectors.toSet());
但是,这样写显然很不优雅,首先是对于每一个 Mail 都创建了额外的 Set 和对应的 Stream,并且,对于每个 mail 的 sendTo 还有 cc 都遍历了两遍(addAll 一遍,后续 Stream 又一遍)。其实我们的目前只是将 mail 中的 cc 以及 sendTo 取出来,用于参与后续的 Stream。在这种场景下,就非常适合用 mapMulti:
Set<String> collect = mails.stream().<String>mapMulti((mail, consumer) ->
mail.cc().forEach(consumer::accept);
mail.sendTo().forEach(consumer::accept);
).collect(Collectors.toSet());
可以看出:
- mapMulti 的入参是一个
BiConsumer
,其实就是使用其参数中的 consumer 接收参与 Stream 后续的对象 - mapMulti 的思路就是将参数中的需要参与后续 Stream 的对象传入 consumer 来继续 Stream
- consumer 没有限制对象类型,想要限制必须加上形参
<String>
否则最后返回的是Set<Object>
而不是Set<String>
假设 mail 的 sendTo 还有 cc 都需要去其他地方获取,使用 mapMulti 还可以实现:
Set<String> collect = mailIds.stream().<String>mapMulti((mailId, consumer) ->
mailService.getCCById(mailId).forEach(consumer::accept);
mailService.getSendToById(mailId).forEach(consumer::accept);
).collect(Collectors.toSet());
还有一些比较有意思的用法,例如混合类型的 List 转换成统一类型:
class C
static void expandIterable(Object e, Consumer<Object> c)
if (e instanceof Iterable<?> elements)
for (Object ie : elements)
expandIterable(ie, c);
else if (e != null)
c.accept(e);
public static void main(String[] args)
var nestedList = List.of(1, List.of(2, List.of(3, 4)), 5);
Stream<Object> expandedStream = nestedList.stream().mapMulti(C::expandIterable);
活用 Optional.ifPresent(Consumer<? super T> action)
方法:
Stream.of(Optional.of("0"), Optional.of("1"), Optional.empty())
.mapMulti(Optional::ifPresent)
.forEach(System.out::print);
toList
对于 Stream 增加了 toList 直接转换成 List,由于不涉及 collect 里面的截断操作,所以比 collect 占用的内存更小,需要的操作更少并且更快。
之前转换成 List,需要 collect(Collectors.toList())
,生成的 List 是 ArrayList
,是可变的
但是这次新加的 Api,toList 生成的是 UnmodifiableList
,是不可变的。
所以这两个 API 不能直接互相替换,需要做一些检查确认没有更改才能替换。
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:
以上是关于Vue3中新增API的见解的主要内容,如果未能解决你的问题,请参考以下文章