如果使用的是Vue3.0 的Composition,该怎么规避这个问题呢?如上图所示,假设它是一个组件实例,我们使用useMouse函数并返回了X和Y两个变量。从左边代码可以看到useMouse函数就是根,它监听了鼠标的移动事件之后,返回了鼠标的XY坐标。通过这种方式来组织代码,就可以很明确的知道这个函数返回的变量和改变的值。
接下来我们再看一个Composition的例子:左边是在Vue2中最常用的一段代码,首先在data里边声明first name和last name,然后在回帖的时候去请求接口,拿到接口返回到值,在computed之后获取他的full Name。那么,这段代码的问题是什么呢?
这里的computed,因为我们不知道返回的full Name的逻辑是什么。在获取了data之后,是希望通过data的返回值来拿到它的first name和last name,然后来获取它的full name。但是这一段代码的逻辑在获取接口之后就已经断掉,这就是Vue2.0 设计不合理的一个地方,导致我们的逻辑是分裂派的,分裂在个配置下。那么,如果用Composition的话,怎么样实现呢?
请求接口之后,直接拿到它的返回数据,然后把这个返回数据的值赋给computed函数里,这里就可以拿到full Name。通过这段代码可以看到,逻辑是更加的聚合了。
如何做到使用useMouse函数,里边的变量也是可响应的。在Vue 3.0中提供了两个函数:reactive和ref。reactive可以传一个对象进去,然后这个函数返回之后的state,是可响应的;ref是直接传一个值进去,然后返回到看法对象,它也是可响应的。如果我们在setup函数里边返回一个可响应值的对象,是可以在字符串模板渲染的时候使用。比如,有时候我们直接在修改data的时候,视图也会相应的改变。
Vue2中,一般会采用mixins来复用逻辑代码,但存在一些问题:例如代码来源不清晰、方法属性等冲突。基于此,在vue3中引入了Composition API(组合API),使用纯函数分隔复用代码,和React中的hooks的概念很相似。
Composition的优点是暴露给模板的属性来源清晰,它是从函数返回的;第二,可以进行逻辑重用;第三,返回值可以被任意的命名,不存在秘密空间的冲突;第四,没有创建额外的组件实力带来的性能损耗。
以前我们如果想要获取一个响应式的data,我们必须要把这个data放在component里边,然后在data里边进行声明,这样的话才能使这个对象是可响应的,现在可直接使用reactive和ref函数就可以使被保变成可响应的。
Fragment在书写vue2时,由于组件必须只有一个根节点,很多时候会添加一些没有意义的节点用于包裹。Fragment组件就是用于解决这个问题的(这和React中的Fragment组件是一样的)。
Fragment其实就是在Vue2的一个组间里边,它的template必须要有一个根的DIV把它包住,然后再写里边的you。在Vue3,我们就不需要这个根的DIV来把这个组件包住了。上图就是2和3的对比。
TeleportTeleport其实就是React中的Portal。Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。Teleport提供一个Teleport的组件,会指定一个目标的元素,比如说这里指定的是body,然后Teleport任何的内容都会渲染到这个目标元素中,也就是说下面的这一部分Teleport代码,它会直接渲染到body。