组件子传父Expose
透传、props、组件v-model、Provide、emit(emit只能传递函数)都是参数向下传递,属父参子用。
如果参数向上传递,子参父用如何实现?
一、ref-Expose标识与暴露
子组件通过defineExpose函数向父标签暴露参数
父组件通过ref标识引用子被暴露的参数。<script setup>
的组件是默认关闭的——即所有定义的变量和函数默认是私有的,不能从组件外部访问。你需要使用 defineExpose 显式地暴露它们,才能供他人使用。
1、defineExpose书写规范
数组式写法:defineExpose([变量,DOM对象,func函数,基本类型])
对象式写法:defineExpose({变量,DOM对象,func函数,aa:基本类型})
基本类型是字符时,要加引号
对象式写法基本类型要添加属性名
数组式写法在父组件只能用数组索引的方式写:父ref标识.value[索引]
对象式写法在父组件用属性的方式写:父ref标识.value.变量名
2、子父响应性
引用型变量:父子互相响应更新。
基本类型变量: 父子互不响应更新。
3、DOM响应性
响应性对象:父组件继承子变量的响应性,因此父组件也会DOM响应。
非响应性对象: 父组件变量不具响应性,但能利用连带更新实现手动DOM响应。
4、生命周期
父组件使用子参是通过父标签的ref标识,因此一定要等父标签渲染完成才可使用子参。
在<template>
使用,ref标识需定义为ref响应性变量,如果引用的是子参的子属性要避免‘无法读取未定义属性’警告。在<script setup>
下引用需放在onMounted生命函数之上的函数体内,在<script setup>
下引用不需担心未定义属性’警告。
避免未渲染引用报警
可采用给子属性上一级定义空对象法消除报警。注意定义的是子属性的上一级。
如引用子DOM对象的子属性,就要定义到子属性上一级的DOM空对象。
如引用变量的子属性就要定义到子属性上一级的变量名空对象,如是孙属性就要定义到孙属性上一级的子属性空对象。
如是引用函数,要定义一个空函数。
如:const wowo=ref({wo:{},oi(){},data:{}})
实力如下如下:
父组件
<template>
<HelloWor ref="wowo" /><br>
父函数{{wowo.oi()}} <br>父dom的子属性{{wowo.wo.outerHTML}}<br>
父响{{wowo.data}}<br>父非响子属性{{wowo.dat.uiu}}<br>父基{{wowo.woo}}<br>
<button @click="ooo">操作父值</button>
</template>
<script setup>
import HelloWor from './Hello.vue'
import {ref,onMounted,watch} from 'vue'
const wowo=ref({wo:{},oi(){},dat:{}})
function ooo(){wowo.value.data='父响应变量改变',wowo.value.dat.uiu='父非响应变量改变',wowo.value.woo='父基本类型改变'}
</script>
子组件
<template>
<button ref="wo" @click="oii">操作子参</button><br>
子响{{data}}<br>子非响{{dat.uiu}}<br>子基{{woo}}<br>
</template>
<script setup>
import {ref} from 'vue'
const data=ref('响应变量')
const dat={uiu:'非响应变量'}
const wo=ref("ref标识")
var woo="基本类型"
function oi(){return '我是函数'}
function oii(){data.value='子响应变量改变',dat.uiu='子非响应变量改变',woo='子基本类型改变'}
defineExpose({
data,
dat,
woo,
wo,
oi
})
</script>
二、DOM对象不需Expose子传父
DOM对象除了使用Expose暴露法子传父外,还有一种不需Expose暴露即可子传父。
1、书写规范
父组件通过ref标识引用子dom。父ref标识.$refs.子dom.子属性
2、子父响应性
是引用型变量,因此父子互相响应更新。
3、DOM响应性
子DOM虽然是采用了ref,但只有本体DOM具有响应性,其它DOM不具响应性,因此父组件变量不具响应性,但能利用连带更新实现手动DOM响应(父连带更新父,子连带更新子)。
4、生命周期
父模版上引用子DOM对象,在父组件上要采用定义空对象法消除报警。
注意要带$refs!如:const bb=ref({$refs:{wowo:{}}})
操作和引用子DOM对象如下:
父组件
<template>
<HelloWor ref="wowo" /><br>
父变量{{wowo.$refs.wow.value}}<br>
<button @click="uu">刷新{{ee}}</button>
</template>
<script setup>
import HelloWor from './Hello.vue'
import {ref} from 'vue'
const wowo=ref({$refs:{wow:{}}})
const ee=ref(1)
function uu(){ee.value++}
</script>
子组件
<template>
<input ref="wow" type="text" value="我会变吗" > <br>
子变量{{wow.value}} <br>
<button @click="uu">改变ref变量的value值</button><br>
</template>
<script setup>
import {ref} from 'vue'
const wow=ref({})
function uu(){wow.value.value='我变了'}
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。