Appearance
Vue3-基础
1. 认识 ref 全家桶
1.1 ref
typescript
function ref<T>(value: T): Ref<UnwrapRef<T>>
interface Ref<T> {
value: T
}
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。
⚠️ 如果将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包。若要避免这种深层次的转换,请使用 shallowRef() 来替代。
无响应式数据,不能发生变化:
vue
<script setup lang="ts">
import { ref, reactive } from 'vue'
let msg = '我是App.vue'
const changeMsg = () => {
msg = '我被改变了'
}
</script>
<template>
<button @click="changeMsg">change</button>
<div>{{ msg }}</div>
</template>
我们这样操作是无法改变 message 的值 应为 message 不是响应式的无法被 vue 跟踪要改成 ref
改为 ref
vue
<script setup lang="ts">
import { ref, reactive } from 'vue'
let msg = ref('我是App.vue')
const changeMsg = () => {
msg.value = '我被改变了'
}
</script>
<template>
<button @click="changeMsg">change</button>
<div>{{ msg }}</div>
</template>
注意:被 ref 包装之后需要.value 来进行赋值
👉 调试技巧:
打开浏览器控制台 → 点击齿轮设置 → 在首选项中 → 勾选"启用自定义格式化程序"
未设置之前查看 ref 信息
设置之后查看信息
2. 认识 reactive 全家桶
2.1 reactive
用来绑定复杂的数据类型 例如 对象 数组 Map Set 等
为什么 reactive 只能绑定引用类型数据?
因为在源码中约束了数据类型
reactive 的基础用法
2.2 readOnly
拷贝一份 proxy 对象将其设置为只读
3. toRef, toRefs, toRaw
3.1 toRef
特点:
- toRef 只能修改响应式对象的值, 非响应式对象无法修改.
- 只能接受引用类型数据, 不能接受基本类型数据
- 创建的 ref 与其源属性保持同步: 改变源属性的值将更新 ref 的值, 反之亦然。
toRef 一般用在把一个 prop 的 ref 传递给一个组合式函数, 即使源属性当前不存在,toRef() 也会返回一个可用的 ref。这让它在处理可选 props 的时候格外实用,相比之下 toRefs 就不会为可选 props 创建对应的 refs。
javascript
const useDemo = toRef(man, 'gender')
3.2 toRefs
描述: 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。
特点:
- 当从组合式函数中返回响应式对象时, toRefs 相当有用。使用它, 消费者组件可以解构/展开返回的对象而不会失去响应性;
- toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref, 请改用 toRef。
3.3 toRaw
描述:toRaw
将一个响应式对象转换为其原始对象, 会丢失响应性。
特点:是一个可以用于临时读取而不引起代理访问/跟踪开销, 或是写入而不触发更改的特殊方法。不建议保存对原始对象的持久引用, 请谨慎使用。
4. 组合式函数_hooks
“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。
一个鼠标坐标显示案例,如果我们要直接在组件中使用组合式 API 实现鼠标跟踪功能,它会是这样的:
vue
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const x = ref(0)
const y = ref(0)
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
</script>
<template>Mouse position is at: {{ x }}, {{ y }}</template>
但是,如果我们想在多个组件中复用这个相同的逻辑呢?我们可以把这个逻辑以一个组合式函数的形式提取到外部文件中:
ts
// mouse.ts
import { ref, onMounted, onUnmounted } from 'vue'
// 按照惯例,组合式函数名以“use”开头
export function useMouse() {
// 被组合式函数封装和管理的状态
const x = ref(0)
const y = ref(0)
// 组合式函数可以随时更改其状态。
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
// 一个组合式函数也可以挂靠在所属组件的生命周期上
// 来启动和卸载副作用
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
// 通过返回值暴露所管理的状态
return { x, y }
}
下面是它在组件中使用的方式:
vue
<script setup>
import { useMouse } from './mouse.js'
const { x, y } = useMouse()
</script>
<template>Mouse position is at: {{ x }}, {{ y }}</template>
Mouse position is at: 0, 0
更多的 demo 可查阅官网:https://cn.vuejs.org/guide/reusability/composables.html