组件子传父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>

百分之一百零八
15 声望3 粉丝