Vue3 响应式专题 ---- 简单做个笔记吧^-^

Vue3 响应式专题

Vue3是使用Proxy来创建响应式对象,Proxy可以劫持整个data对象,然后递归返回属性的值的代理。Vue3还引入了新的Reactivity API,包括refreactive等新的API,使得响应式系统更加灵活和易用。ref用于对单个值进行响应式处理,reactive用于对对象进行响应式处理

Proxy是什么

Proxy是一种代理,它可以代表其他对象或函数进行操作。在JavaScript中,Proxy是一个构造函数,它可以创建一个对象,这个对象可以拦截对目标对象的访问和修改。Proxy的作用是可以自定义一些基本操作的行为,比如属性读取、赋值、枚举、函数调用等

toRefs()

toRefs() 可以把一个响应式对象转换成一个普通对象,其中每个属性都是一个指向原始对象相应属性的 ref。这在处理可选属性或者把一个对象解构成单独的变量时很有用。

例如,如果你想在 script setup 中使用 props,你可以这样写

<script setup>
import { toRefs } from 'vue'
const props = defineProps({
  name: String,
  age: Number
})
const { name, age } = toRefs(props)
</script>

这样就可以保持 props 的响应性,而不需要每次都写 props.name 或者 props.age。

如果你想看更多的示例,你可以观看这个视频

Ref()

ref 是一个特殊的属性,类似于 v-for 章节中讨论的 key 属性。它可以让我们在组件挂载后获取一个指向特定 DOM 元素或子组件实例的直接引用。这在你想要,比如,聚焦一个输入框或者在一个元素上初始化一个第三方库时很有用。

例如,如果你想在模板中引用一个 input 元素,你可以这样写

<template>
  <div>
    <input ref="usernameInput" />
    <button @click="focus">Focus</button>
  </div>
</template>

<script>
export default {
  setup() {
    const usernameInput = ref(null)

    function focus() {
      usernameInput.value.focus()
    }

    return {
      usernameInput,
      focus
    }
  }
}
</script>

这样就可以通过 usernameInput.value 来访问 input 元素,并调用它的 focus 方法。

ref 还有另一个用法,就是把基本类型(String, Boolean, Number 等)转换成响应式对象。这时候 ref 返回的是一个包含 value 属性的对象,而不是直接返回基本类型的值

例如,如果你想创建一个响应式的字符串变量,你可以这样写:

const message = ref('Hello')
console.log(message.value) // 'Hello'
message.value = 'World'
console.log(message.value) // 'World'

reactive

reactive 是一个函数,它可以把一个普通的 JavaScript 对象转换成一个响应式的代理对象。这意味着当对象的属性发生变化时,Vue 会自动更新依赖于这些属性的视图层

例如,如果你想创建一个响应式的用户对象,你可以这样写:

const user = reactive({
  name: 'Alice',
  age: 25
})

这样就可以在模板中使用 user.name 和 user.age,并且当它们改变时,视图也会重新渲染。

reactive 和 ref 的区别是,reactive 只能用于对象,而 ref 可以用于基本类型。另外,reactive 返回的是原始对象的代理,而 ref 返回的是包含 value 属性的对象

computed

computed 是一个函数,它可以创建一个计算属性,用于根据其他值来修改、操作和显示数据。这个特性可以让我们在模板中复用这些计算和转换的结果,并且提高代码的可读性和效率

例如,如果你想创建一个计算属性,用于根据用户的年龄显示不同的信息,你可以这样写:

const user = reactive({
  name: 'Alice',
  age: 25
})

const message = computed(() => {
  if (user.age < 18) {
    return 'You are too young.'
  } else if (user.age >= 18 && user.age < 30) {
    return 'You are in your prime.'
  } else {
    return 'You are wise and experienced.'
  }
})

这样就可以在模板中使用 message.value 来显示不同的信息,并且当 user.age 改变时,message.value 也会自动更新。

computed 还可以接受一个对象作为参数,包含 get 和 set 方法3。这样就可以自定义计算属性的读取和写入逻辑。

例如,如果你想创建一个计算属性,用于设置用户的全名,你可以这样写:

const user = reactive({
  firstName: 'Alice',
  lastName: 'Smith'
})

const fullName = computed({
  get() {
    return `${user.firstName} ${user.lastName}`
  },
  set(value) {
    const [firstName, lastName] = value.split(' ')
    user.firstName = firstName
    user.lastName = lastName
  }
})

这样就可以在模板中使用 fullName.value 来获取或设置用户的全名,并且当 user.firstName 或 user.lastName 改变时,fullName.value 也会自动更新。

watch

watch 是一个函数,它可以让我们观察一个或多个响应式数据,并且当它们发生变化时,执行一些副作用。它相当于一个事件监听器,用于响应数据的变化

例如,如果你想观察用户的年龄,并且当它改变时,发送一个 API 请求,你可以这样写:

const user = reactive({
  name: 'Alice',
  age: 25
})

watch(() => user.age, async (newAge) => {
  const response = await fetch(`https://example.com/api/user/${user.name}/age/${newAge}`)
  const data = await response.json()
  // do something with data
})

这样就可以在每次 user.age 改变时,调用 watch 的回调函数,并传入新的值和旧的值

watch 还可以接受一个对象作为参数,包含 source、handler 和其他选项。source 可以是一个 ref、reactive 或者一个返回值的函数。handler 是一个回调函数,用于处理数据变化。其他选项包括 deep、immediate 和 flush 等。

例如,如果你想深度观察用户对象,并且立即执行回调函数,你可以这样写:

const user = reactive({
  name: 'Alice',
  age: 25
})

watch(user, async (newUser) => {
  const response = await fetch(`https://example.com/api/user/${newUser.name}/age/${newUser.age}`)
  const data = await response.json()
  // do something with data
}, { deep: true, immediate: true })

这样就可以在每次 user 对象或其属性改变时,调用 watch 的回调函数,并传入新的对象和旧的对象。

watchEffect

watchEffect 是一个函数,它可以让我们执行一个副作用函数,并且自动追踪它内部使用的响应式数据当这些数据发生变化时,watchEffect 会重新执行这个副作用函数

例如,如果你想执行一个副作用函数,并且根据用户的年龄显示不同的信息,你可以这样写:

const user = reactive({
  name: 'Alice',
  age: 25
})

watchEffect(() => {
  if (user.age < 18) {
    console.log('You are too young.')
  } else if (user.age >= 18 && user.age < 30) {
    console.log('You are in your prime.')
  } else {
    console.log('You are wise and experienced.')
  }
})

这样就可以在每次 user.age 改变时,重新执行 watchEffect 的回调函数,并打印不同的信息。

watchEffect 和 watch 的主要区别是,watch 只追踪显式指定的源数据,而 watchEffect 追踪所有在回调函数中访问的数据另外,watch 的回调函数只在源数据真正改变时触发,而 watchEffect 的回调函数在每次渲染时都会触发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值