Appearance
宏函数
defineExpose()
在 <script setup>
内声明的数据或函数默认是私有的,当父组件通过 ref 获取到子组件的引用后,无法通过 ref 直接访问子组件中声明的数据或函数。
此时,我们可以通过 defineExpose
编译器宏来显式指定在 <script setup>
组件中要暴露出去的属性:
vue
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(0)
const increment = (step = 1) => {
b.value += step
}
defineExpose({
a,
b,
increment
})
</script>
当父组件通过 ref 获取到子组件的引用之后,可以通过 子组件引用.value
访问到暴露的数据或函数:
vue
<script setup>
import MyCom from './components/05.自定义插件/03.defineExpose.vue'
import { ref, onMounted, watch } from 'vue'
// 1. 声明引用对象
const myComRef = ref(null)
// 3. 在 js 中,需要在父组件挂载完成后,才能访问到子组件的 ref 引用
onMounted(() => {
// 获取子组件通过 defineExpose 暴露的数据
console.log(myComRef.value)
// 侦听子组件中的响应式数据的变化
// 必须在 onMounted 中使用 watch 侦听子组件
// 否则,子组件还没有创建完毕,无法获取数据
watch(
() => myComRef.value.b,
(newValue, oldValue) => {
console.log(newValue, oldValue)
}
)
})
</script>
<template>
<div>
<div class="app-title">App.vue</div>
<!-- 4. 在模板区域,直接 ref 会自动解包,不需要使用 .value 属性 -->
<button @click="myComRef.b++">b++</button>
<hr />
<!-- 2. 建立引用关系 -->
<MyCom ref="myComRef" />
</div>
</template>
<style scoped>
.app-title {
font-size: 30px;
}
</style>
响应式 API 的工具函数
toRefs()
对 reactive
创建的响应式数据使用解构赋值的操作时,会导致解构出来的数据丢失响应性的问题。我们可以使用 toRefs()
这个 API 对 reactive 数据进行包裹,这样解构出来的数据依然具有响应性。
vue
<template>
<p>{{ info }}</p>
<p>年龄:{{ age }}</p>
<button @click="age++">age++</button>
</template>
<script setup>
import { reactive, toRefs } from 'vue'
const info = reactive({
name: 'zs',
age: 18
})
// 这里的解构会丢失响应性
// const { age } = info
// age 具有响应性
const { age } = toRefs(info)
console.log(age)
</script>