目錄
- 常規示例
- 子元件: /components/testCom1.vue
- 父元件: App.vue
- 監聽defineExpose返回的資料的變化實現子元件向父元件傳遞資料
- 父元件中修改子元件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>