当前位置:首页 > 英文周记 > 正文内容

compositionapi的简单介绍

更新时间:2026-07-18 12:45:08 周记网3年前 (2023-02-25)英文周记135

Composition API介绍

Composition API字面意思是组合API,它是为了实现基于函数的逻辑复用机制而产生的。

方案一:

compositionapi的简单介绍

方案二:

在head标签中引入以下

官方文档:

composition api

其他文档:

vue2 + Composition API 实践

我们习惯了ES6的对象解构风格,但这在 composition- api 里可能会有陷阱。因为结构可能会让你的响应式对象失去预期中的响应特性。

比如这里,button的click时候,不会得到预期的 count 的增加。因为setup执行返回的 count 并不是响应式的。

也就是说,虽然你的click事件确实的改变了 data.count 的值,但是这个值并没有响应式的去改变其他引用这个值的地方。怎么去验证我们这个解释呢?

我们可以开着chrome的vue插件,定位到你的组件。然后你可以点击一下button,可以看到 count 并没有变化, data 呢?看起来好像也没有变化?这不是不符合逻辑吗?甚至我们在click的回调函数里打印一下发现是有执行data.count+1 这个操作的。

事实是, data.count 确实是执行了的,但是因为不是 reactive 的,所以插件里没有及时更新这个新数据。如果你把插件先切到别的组件上去,再切回来。你就会发现,data.count是符合预期的!

click操作前的插件看到的数据:

我做了2次click后,现在插件里把光标切到别的组件上,再切回来。就可以看到data的变化:

只是引用了 data.count 的地方没有被更新,这就说明引用 data.count 的地方是非 reactive 的。

我们要要做的,就是改造一下引用 data.count 的地方。我们在 setup 里的返回,可以用 computed 和 toRefs 来改造一下返回值。

再看一下toRefs改造后的demo:

第二个问题来了: toRefs 一定是安全应对解构的方案么?

不是的,因为 toRefs 的结构是浅解构的,对于我们demo里的这种简单的对象是work的。但是如果是一个嵌套很深的复杂Object,还是会有解构后响应式断裂的问题。如果数据的层级比较复杂,建议使用 computed 。

watchEffect 很像React里的 useEffect ,是一个副作用函数。用法也基本一致。

watch 的话,接收2个参数。第一个参数是 watch 的target,看ts结构,必须是一个 ref 对象或者 computedRef 对象;第二个参数是watch的回调函数。

React的hooks出来之后,有个很好用的东西就是Context,很像一个微型Redux,可以很好的跨组件传值,尤其是在组件粒度很细的时候,我们的组件间通信频率也会升高。

之前vue2的时代,其实一直有 provide 和 inject 可以用。但是 provide 和 inject 的对象一般是非响应式的。官网是这么记载的:

vue2的时候,我们一般不太注重如何把一个数据变成响应式的(也不是没有办法,比如 Vue.observable(obj) 可以把一个对象变成响应式的。如果我们把这个对象provide出去,那么传递的数据也就一直是响应式的了)。

vue3(或者vue2 + @vue/composition-api )后,我们更多的关注到了数据的 reactive 特性。比如用 ref 或者 reactive 关键字来构造一个响应式的对象。我们如果再用 provide 直接传递一个 reactive 的对象,岂不是可以模拟出类似React的 useContext 这样的结构?

本身vue3(or vue2 + @vue/composition-api )也是支持hooks的。

这样我们就可以按照React hooks的开发习惯去给vue抽hooks了。

20.compositionApi介绍和setup函数的参数和返回值

在Vue2中,我们编写组件的方式是Options API:

那么既然知道Composition API想要帮助我们做什么事情,接下来看一下到底是怎么做呢?

我们先来研究一个setup函数的参数,它主要有两个参数:

attrs :为一个对象,存储着所有的从父组件传递过来的非props的attribute;

slots :父组件传递过来的插槽(这个在以渲染函数返回时会有作用,后面会讲到);

emit :当我们组件内部需要发出事件时会用到emit(因为我们不能访问this,所以不可以通过 this.$emit发出事件);

setup既然是一个函数,那么它也可以有返回值,它的返回值用来做什么呢?

甚至是我们可以返回一个 执行函数 来代替在 methods 中定义的 方法 :

但是,如果我们将 counter 在 increment 或者 decrement进行操作时,是否可以实现界面的响应式呢?

App.vue

所有在 template模板 中使用的 变量 或 方法 (除了 props 和 $attrs 中的属性),都得在 setup函数中 返回

Home.vue

父组件传递给子组件的 非props属性 在 template 中使用,这些属性都存储在 $attrs 对象中,可以通过 attrs.属性名 获取

父组件传递给子组件的 非props属性 在 setup函数 中获取,这些属性都存储在 setup函数 的第二个参数对象 context 的 attrs 属性中,可以通过 context.attrs.属性名 获取

父组件传递给子组件的 props属性 在 setup函数 中获取,这些属性都存储在 setup函数 的 第一个参数对象props 中,可以通过 props.属性名 获取

在setup函数中,子组件向父组件发射事件,可以通过 context.emit 发射事件

官方关于this有这样一段

标签: compositionapi

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。