Vue3-02 响应式API

本文介绍了Vue3中的响应式API,包括响应式系统API、响应式系统工具集及高级响应式系统API。讨论了`ref`、`reactive`、`toRef`、`toRefs`等工具的使用,并对比了Vue2.x中的API。文中提到了在Vue3中,基础类型值也能变得响应式,以及如何处理响应式对象的只读和深层响应式转换。还涉及了副作用管理,如`watchEffect`和`watch`的使用及其在组件生命周期中的执行时机。最后,文章探讨了调试方法和最佳实践,帮助开发者更好地理解和运用Vue3的响应式系统。
摘要由CSDN通过智能技术生成

响应式系统API

reactive

const obj = reactive({ count: 0 })

相当于Vue 2.x中的Vue.observable()API,返回一个普通对象的响应式代理,响应式转换是深层的,会影响对象内部嵌套的属性,基于ES2015的Proxy实现,返回的代理对象不等于原始对象,要避免使用原始对象

经过试验,Vue3中可以通过修改数组下标来响应式的更改数组成员的值了

reactive将自动解构所有深层次的refs,同时维持ref的响应性

const count = ref(1)
const obj = reactive({ count })

// ref 会被解构
console.log(obj.count === count.value) // true

// 它会更新 `obj.value`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2

ref

ref的引入是为了以变量形式传递响应式的值而不再依赖访问this:

const count = ref(0)

接受一个参数,返回一个响应式可改变的ref对象,ref对象拥有一个指向内部值的单一属性.value

ref主要目的是保证基本类型值的响应式,如果传入的参数不是基本类型,会调用reative方法进行深层响应式转换

ref使用时:

  • ref的返回值setup中返回应用在模板中时,会自动解构,不需要书写.value
  • ref作为reactive对象的属性被修改或访问时,也会自动解构,不需要书写.value
  • 通过ArrayMap等原声集合类中范围ref时,不会自动解构,需要使用.value获取值

reactive VS ref

使用refreactive的区别可以通过如何撰写编撰的JavaScript逻辑比较

// 风格 1: 将变量分离
let x = 0
let y = 0

function updatePosition(e) {
  x = e.pageX
  y = e.pageY
}

// --- 与下面的相比较 ---

// 风格 2: 单个对象
const pos = {
  x: 0,
  y: 0,
}

function updatePosition(e) {
  pos.x = e.pageX
  pos.y = e.pageY
}

使用ref就是将将风格(1)转换为使用ref,让基础类型值也具有响应性,使用reactive和风格(2)一致

只使用reactive的问题是,使用组合函数的时候必须始终保持对这个组合函数返回对象的引用以保持响应性,这个对象不能够被解构或者展开

// 组合函数:
function useMousePosition() {
  const pos = reactive({
    x: 0,
    y: 0,
  })

  // ...
  return pos
}

// 消费者组件
export default {
  setup() {
    // 这里会丢失响应性!
    const { x, y } = useMousePosition()
    return {
      x,
      y,
    }

    // 这里会丢失响应性!
    return {
      ...useMousePosition(),
    }

    // 这是保持响应性的唯一办法!
    // 你必须返回 `pos` 本身,并按 `pos.x` 和 `pos.y` 的方式在模板中引用 x 和 y。
    return {
      pos: useMousePosition(),
    }
  },
}

解决方法是使用toRefs将响应式对象的每个对象都转换为响应的ref

function useMousePosition() {
  const pos = reactive({
    x: 0,
    y: 0,
  })

  // ...
  return toRefs(pos)
}

// x & y 现在是 ref 形式了!
const { x, y } = useMousePosition()

目前阶段可以从下面两种风格二选其一:

(1)如果在普通的JavaScript中声明基础变量类型与对象变量时一样区别使用refreacitve,也就是说如果声明响应式的基础类型使用ref,如果声明响应式对象变量使用reactive

(2)全部使用reactive,然后在组合函数返回对象时使用toRefs

目前(2020.08.01)官方对refreactive的最佳实践还没有建议,自己选择更适合自己的风格使用,我会选择风格1使用。

readonly

如果我们希望一个响应式对象在某些情况下被改变,例如我们提供了一个Provide的响应式对象,不希望它在被注入时被改变,这时就可以基于原始对象创建一个只读的Proxy对象


                
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值