前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Vue3.0抢先学》系列之:更多响应式API示例

《Vue3.0抢先学》系列之:更多响应式API示例

作者头像
一斤代码
发布2019-10-29 16:01:22
9530
发布2019-10-29 16:01:22
举报
文章被收录于专栏:大前端开发大前端开发

这几天,我们陆续学习了解了关于Vue3.0的一些新特性,尤其是新的Composition API的用法。这套新的API中最重要、最核心的部分,恐怕就是实现响应式功能的这一块了。而且,这套响应式API不仅可以在Vue3.0环境下使用,也可以独立使用。

响应式API主要由2大类组成:

  • 针对原始的数据,将其包装成可观察数据的API (ref、reactive)
  • 针对可观察数据的变动,执行监听和响应动作的API (effect、computed)

包装API和监听API这2者之间互相协同工作,组成一个完整的响应式系统。下面我们来通过一些简单的例子,观察和了解一下它们是如何进行协同工作的。

示例一:ref + effect

在前面的文章中我们提到过,ref 函数可以将一个数据包装成一个响应式数据对象(Ref类型),该函数的TypeScript类型定义如下:

代码语言:javascript
复制
function ref<T>(raw: T): Ref<T>

effect 函数则可以接受一个监听函数,如果这个监听函数中存在对响应式数据对象的访问,则一旦这些响应式数据对象的值发生变化,该监听函数就会被执行。

来看一个简单的代码示例:

代码语言:javascript
复制
const { ref, effect } = Vue

// 创建观察对象
const greeting = ref("Hello,World!")

// 监听数据变化
effect(() => {
    console.log(greeting.value)
})

// 再让数据改变一下吧
greeting.value = "Are you OK?"

以上这段代码先使用 ref 函数创建了一个名为 greeting 的可观察对象,然后通过 effect 函数创建对 greeting 值变化的监听器,对值进行打印。这段代码的执行结果是打印出:

Hello,World! Are you OK?

这个还是很好理解的,因为这个 greeting 包含的值一共变化了2次,第一次是初始化时设置的 “Hello,World!”,第二次是后面设置的 "Are you OK?"。

示例二:ref 作用于数组数据

在Vue2.x中,对一个数组中的每个元素进行响应式变化监听,做起来还是稍微有点麻烦和不优雅的。在Vue3.0中,这个问题被很好的解决了。

代码语言:javascript
复制
const { ref, effect } = Vue

// 创建一个对数组的观察对象
const arr = ref([1, 2, 3])

effect(() => {
    console.log(arr.value[0])
})

// 改变整个数组
arr.value = [5, 6, 7]

// 改变数组中的第一个元素
arr.value[0] = 111

上面这段代码示例输出的结果是:

1 5 111

由此可以说明,在这段代码中,无论是对整个数组重新赋值,还是对数组中的某个元素赋值,都可以被精准的监听到。

示例三:ref 的嵌套

由 ref 函数创建的可观察对象可以嵌套使用。

代码语言:javascript
复制
const { ref, effect } = Vue

const a = ref(1)
const b = ref(2)
const c = ref({ x: a, y: b })

effect(() => {
    console.log(c.value.x + c.value.y)
})

// 从c对象上去间接改变a和b值
c.value.x = 5
c.value.y = 10

// 直接改变a和b的值
a.value = 20
b.value = 60

可以看到,可观察对象 c 中包含了对其他2个可观察对象 a 和 b的引用。这段代码的最终执行结果为如下:

3 7 15 30 80

由此可见,无论是通过嵌套引用来改变可观察对象值,或是直接改变可观察对象值,effect 创建的监听器都能正确响应这些变化。

示例四:reactive + effect

之前的文章中也提到过,除了 ref 函数,reactive 是Composition API中的另一个可用于创建可观察对象的函数。最简单的用法如下:

代码语言:javascript
复制
const { reactive, effect } = Vue

const state = reactive({ a: 1, b: 'Hello' })

effect(() => {
    console.log(state.a)
})

state.a = 2

使用 reactive 的好处是一次性可以观察多个属性。不过,自从ES6+流行后,我们在实际的代码编写过程中,是不是经常会用到对象解构操作?比如像这样:

代码语言:javascript
复制
const obj = { a: 1, b: 2 }
const { a, b } = obj

而在对可观察对象进行操作的时候,你一定也会自然而然的想这么干:

代码语言:javascript
复制
const state = reactive({ a: 1, b })
let { a, b } = state

state.a = 123 //可以
a = 123 // 行不通!变成不可观察了

为什么将可观察对象中的属性解构出来后,变成不再可观察了呢?因为通过 reactive 函数创建的可观察对象,内部的属性本身并不是可观察类型的,对他们访问和观察其实都是通过Proxy代理访问来实现的。如果将这些属性解构,这些属性就不再通过原对象的代理来访问了,就无法再进行观察。

不过,Composition API也考虑到了这一点,提供了方法来解决这一个问题:

代码语言:javascript
复制
const { reactive, effect, toRefs } = Vue

const state = reactive({ a: 1, b: 2 })

// 这里的a和b都是Ref类型对象
const { a, b } = toRefs(state)

effect(() => {
    console.log(a.value)
})

a.value = 123

通过引入一个 toRefs 函数,它可以将 reactive 创建的可观察对象中的属性都转换成可观察的 Ref 对象,这样一来,即使解构后,也可以被独立进行观察了。

示例五:computed

用过Vue的朋友,一定对计算属性不陌生,一般用于定义一个虚拟属性,这个虚拟属性的值来源于一个或多个可观察对象的变化而产生。在Composition API中也有对应的功能:

代码语言:javascript
复制
const { computed, ref } = Vue

// 可观察对象
const num = ref(1)

// 计算属性
const text = computed(() => {
    return `Value is ${num.value}`
})

console.log(text.value)

// 改动可观察对象的值
num.value = 2

console.log(text.value)

这个例子中,我们根据数字类型的 num,来生成新的字符串 text,实现了一个比较方便的数据生成转换。

总结

Vue 3.0的Composition API提供了上文示例中所展示的这些简单而有效的函数,实现了响应式功能。其实它们还提供了一些可选项参数,用于实现更为丰富的功能,大家可以自己阅读源码深入研究一下,非常有意思,同时也可以从优秀的源码中学习和提高自己的编程水平。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.10.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 示例一:ref + effect
  • 示例二:ref 作用于数组数据
  • 示例三:ref 的嵌套
  • 示例四:reactive + effect
  • 示例五:computed
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档