vue3学习笔记——第二节

1. 组合式API

1. provide与inject

  • 官方文档:provide 和 inject 启用依赖注入。这两者只能在使用当前活动实例的 setup() 期间被调用。
  • 作用:实现祖组件后代组件间通信(两级以上)
  • 使用方式:祖组件使用 provide 提供数据;后代组件使用 inject 接受数据
// 祖组件使用provide提供数据
let person = 'wmh'       
provide('person', person)

// 后代组件使用inject接收数据
let person = inject('person')

2. 生命周期钩子

可以通过直接导入 onX 函数来注册生命周期钩子:(X表示原有选项式 API)

import { onMounted, onUpdated, onUnmounted } from 'vue'

const MyComponent = {
  	setup() {
    	onMounted(() => {
     		console.log('mounted!')
    	})
    	onUpdated(() => {
      		console.log('updated!')
    	})
    	onUnmounted(() => {
      		console.log('unmounted!')
    	})
  	}
}

生命周期钩子对应关系

2. 响应式API

1. toRef和toRefs函数

1. toRef
  • 官方文档:可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
import { toRef } from 'vue'
  • 简单说:创建一个ref对象,其value值指向另一个对象的某个属性,这两个值互相联系
let state = reactive({
  foo: 1,
  bar: 2
})

let fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 输出:2

state.foo++
console.log(fooRef.value) // 输出:3

应用场景:需要将响应式对象中的某个值单独提供给外部,或是提供给某个方法时

useSomeFeature(toRef(state, 'foo'))

需要注意的是,即使源property(例如上述的state.foo)不存在,toRef也会返回一个可用的ref

2. toRefs
  • 官方文档:将响应式对象转换为普通对象(ref对象),其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。
const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:
{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// ref 和原始 property 已经“链接”起来了
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3

2. readonly和shallowReadonly函数

1. readonly
  • 官方文档:接受一个对象 (响应式或纯对象) 或 ref 并返回原始对象的只读代理。只读代理是深层的:任何被访问的嵌套 property 也是只读的。
import { readonly, shallowReadonly } from 'vue'
  • 理解:包裹一个响应式数据返回该数据的只读代理
const original = reactive({ count: 0 })
const copy = readonly(original)

// 变更 original 正常执行
original.count++

// 变更副本将失败并导致警告
copy.count++ // 警告!

只读代理是深层的:任何被访问的嵌套 property 也是只读的。

2. shallowReadonly
  • 官方文档:创建一个 proxy,使其自身的 property 为只读,但不执行嵌套对象的深度只读转换 (暴露原始值)。
const state = shallowReadonly({
  foo: 1,
  nested: {
    bar: 2
  }
})

// 改变 state 本身的 property 将失败
state.foo++
// ...但适用于嵌套对象
isReadonly(state.nested) // false
state.nested.bar++ // 正常执行
  • 理解:浅层的readonly,只会影响源数据自身的property,不影响嵌套对象

3. shallowRef和shallowReactive函数

1. shallowRef
  • 官方文档:创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的。
  • 理解:只处理基本类型的响应式,不进行对象的响应式处理
2. shallowReactive
  • 官方文档:创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (暴露原始值)。
  • 理解:只处理对象最外层的响应式(浅响应式)
const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2
  }
})

// 改变 state 本身的性质是响应式的
state.foo++
// ...但是不转换嵌套对象
isReactive(state.nested) // false
state.nested.bar++ // 非响应式

4. toRaw和markRaw函数

1. toRaw(请谨慎使用)
  • 官方文档:返回 reactive 或 readonly 代理的原始对象。
import { toRaw, markRaw } from 'vue'
  • 理解:将一个由 reactive 或 readonly 生成的响应式对象转为普通对象,对这个普通对象的所有操作,不会引起页面更新(数据会发生改变)
const foo = {}
const reactiveFoo = reactive(foo)

console.log(toRaw(reactiveFoo) === foo) // true
2. markRaw
  • 官方文档:标记一个对象,使其永远不会转换为 proxy,返回对象本身。
const foo = markRaw({})
console.log(isReactive(reactive(foo))) // false

// 嵌套在其他响应式对象中时也可以使用
const bar = reactive({ foo })
console.log(isReactive(bar.foo)) // false

markRaw 和上述的 shallowXXX API 使你可以有选择地退出默认的深度响应式/只读转换模式,并将原始的,未被代理的对象嵌入状态图中。

3. customRef
  • 官方文档:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。
  • 典例:使用自定义 ref 通过 v-model 实现 debounce 的示例:
<input v-model="text" />

function useDebouncedRef(value, delay = 200) {
  	let timeout //定义延迟
  	return customRef((track, trigger) => {
    	return {
      		get() {
        		track() 
        		return value
      		},
      		set(newValue) {
        		clearTimeout(timeout)
        		timeout = setTimeout(() => {
          			value = newValue
          			trigger()
        		}, delay)
      		}
    	}
  	})
}

export default {
  	setup() {
    	return {
      		text: useDebouncedRef('hello')
    	}
  	}
}

5. 响应式数据的判断

  • isRef:判断一个值是否为一个ref对象
  • isReactive:判断一个对象是否是由Reactive创建的响应式代理
  • isReadonly:判断一个对象是否是由readonly创建的响应式代理
  • isProxy:判断一个对象是否是由Reactive或readonly创建的响应式代理
let name = ref('wmh')
isRef(name) // true
isReactive(name) // false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值