vue3_defineExpose的用法
目录
defineExpose
用于子组件向其父组件传值.
常规示例
子组件: /components/testCom1.vue
<template>
<div id="a_container"></div>
</template>
<script setup>
import { ref, reactive, defineExpose } from 'vue'
const a = ref(Math.round(Math.random() * 100))
const b = reactive({
num: Math.round(Math.random() * 100),
})
const c = 77
defineExpose({ a, b, c })
</script>
<style scoped lang="scss"></style>
- 在子组件中声明了一个a变量保存随机生成数据, 通过
父组件: App.vue
<template>
<div id="app">
<test-com1 ref="testCom1Ref"></test-com1>
</div>
</template>
<script setup>
import testCom1 from './components/testCom1.vue'
import { ref, onMounted } from 'vue'
const testCom1Ref = ref(null)
onMounted(() => {
console.log(testCom1Ref.value)
const { a, b, c } = testCom1Ref.value
console.log(a) // 随机数
console.log(b) // {num : 随机数}
console.log(c) // 77
})
</script>
<style></style>
监听defineExpose返回的数据的变化实现子组件向父组件传递数据
- 如下: 子组件抛出数据, 并在指定时间后更新数据; 父组件在onMounted中通过watch监听数据, 只能监听到reactive定义的数据的变化; 因此可以通过defineExpose来返回子组件中的reactive定义的proxy对象, 然后在父组件中通过watch来监听该数据的变化, 实现子组件向父组件传递数据
// components/testCom1.vue
<template>
<div id="a_container"></div>
</template>
<script setup>
import { ref, reactive, defineExpose } from 'vue'
const a = ref(10) // 获取一个随机数
const b = reactive({
num: 20 // 获取一个随机数
})
let c = 30
setTimeout(() => {
a.value = 100
b.num = 200
c = 300
}, 2000)
defineExpose({ a, b, c })
</script>
<style scoped lang="scss"></style>
// App.vue
<template>
<div id="app">
<test-com1 ref="testCom1Ref"></test-com1>
</div>
</template>
<script setup>
import testCom1 from './components/testCom1.vue'
import { ref, onMounted, watch, onBeforeMount } from 'vue'
const testCom1Ref = ref(null)
onMounted(() => {
const { a, b, c, d } = testCom1Ref.value
console.log(typeof a) // number
console.log(typeof b) // object
console.log(typeof c) // number
console.log(typeof d) // object
console.log(a) // 10
console.log(b.num) // 20
console.log(c) // 30
console.log(d.num) // 40
watch(b, () => {
console.log('b更新')
console.log(b) //{num:200}
})
watch(
() => d,
() => {
// 不执行, 因为watch只对监听proxy对象有反应
console.log('d更新')
console.log(d)
}
)
setTimeout(() => {
console.log(a) // 10
console.log(b.num) // 200
console.log(c) //30
console.log(d.num) // 400
}, 3000)
})
</script>
<style></style>
父组件中修改子组件defineExpose抛出的数据, 实现父组件向子组件回传数据
- 子组件中通过
reactive
定义的数据, 通过defineExpose
抛出后可以在父组件中获取得到; - 父组件中修改
defineExpose
抛出的, 在子组件中通过reactive
定义的数据, 可以触发子组件的数据响应
// components/testCom1.vue
<template>
<div id="a_container">
<p key="hasdhj">{{ a }}</p>
<!-- b由20变化为200, 变化为2000 -->
<p key="asasda">{{ b.num }}</p>
<p key="zxcwwd">{{ c }}</p>
<p key="xcqweq">{{ d.num }}</p>
</div>
</template>
<script setup>
import { ref, reactive, defineExpose } from 'vue'
const a = ref(10) // 获取一个随机数
const b = reactive({
num: 20 // 获取一个随机数
})
let c = 30
const d = { num: 40 }
setTimeout(() => {
a.value = 100
b.num = 200
c = 300 // 因为a,b响应式数据被更新, 所以c也会因为页面更新而更新, 但它本身不具有响应式
d.num = 400 // 因为a,b响应式数据被更新, 所以d也会因为页面更新而更新, 但它本身不具有响应式
}, 2000)
defineExpose({ a, b, c, d })
</script>
<style scoped lang="scss"></style>
// App.vue
<template>
<div id="app">
<test-com1 ref="testCom1Ref"></test-com1>
</div>
</template>
<script setup>
import testCom1 from './components/testCom1.vue'
import { ref, onMounted, watch, onBeforeMount } from 'vue'
const testCom1Ref = ref(null)
onMounted(() => {
const { a, b, c, d } = testCom1Ref.value
console.log(typeof a) // number
console.log(typeof b) // object
console.log(typeof c) // number
console.log(typeof d) // object
console.log(a) // 10
console.log(b.num) // 20
console.log(c) // 30
console.log(d.num) // 40
watch(b, () => {
// 每次更新都会执行
console.log('b更新')
console.log(b)
})
watch(
() => d,
() => {
// 不执行, 因为watch只对监听proxy对象有反应
console.log('d更新')
console.log(d)
}
)
setTimeout(() => {
console.log(a) // 10
console.log(b.num) // 200
console.log(c) //30
}, 3000)
// setTimeout(() => {
// b.num = 2000
// d.num = 4000 // 不具有响应式, 但因为响应式数据b变化, 页面重新渲染, d数据也会被重新渲染, 造成该数据有响应式的假象
// }, 5000);
setTimeout(() => {
b.num = 2000
}, 5000)
setTimeout(() => {
d.num = 4000 // 不具有响应式, 且子组件数据变化但页面并不更新
}, 5000)
})
</script>
<style></style>