NO5 defineProps 、defineEmits 和 defineExpose

2,649 阅读1分钟
    defineProps 和 defineEmits 只能在<script setup>中使用,是编译器宏(???), 传入到defineProps 和 defineEmits的选项会从setup中提升到模块的范围。
     
    definneExpose API
    在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在 script-setup 模式下,所有数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref 变量获取子组件的数据。
    如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,这个操作,就是由 expose 来完成。
    expose 也是 context 的一个组件成员,原来的用法是从 useContext 里导出。由于 useContext 会在未来版本里移除,所以新增了 defineExpose API 来实现 expose 的功能。父组件就可以通过 ref API 去拿到子组件暴露出来的数据了。 
父组件
<script setup lang="ts">

import TestPropsEmit from './components/test-props-emit/index.vue'

import {ref, onMounted} from 'vue'

const msg = ref('hello world')


const handleChange = (params: string) => {

  console.log(params)

}


const propsEmitRef = ref()

onMounted(() => {

  console.log(propsEmitRef.value.child)

  console.log(propsEmitRef.value.childNode()) 

})

</script>


<template>

  <TestPropsEmit ref="propsEmitRef" :msg="msg" @on-change="handleChange"></TestPropsEmit>

</template>
    

子组件
<script setup lang="ts">

    const props = defineProps({
        msg: {
            typeString,
            default() => '默认值1'
        }
    })

    const emit = defineEmits(['on-change'])

    const handleClick = () => {

        emit('on-change''父组件方法被调用了')

    } 

    
    const childNode = () => {

        console.log('子组件方法被调用了')

    }

    defineExpose({

        child'我是暴露的子组件',

        childNode

    })

</script>


<template>

    <p>{{msg}}</p> 

    <p>{{props.msg}}</p> 

    <button @click="handleClick">点击我调用父组件的方法</button>

</template>