defineProps
和defineEmits
都是只能在中使用的编译器宏。他们不需要导入,且会随着
的处理过程一同被编译掉。
接收父组件传递的参数
父页面
<template>
<p>父组件</p>
<child :num="num"></child>
</template>
子页面
<template>
<p>我是子组件接收的num:{{ num }}</p>
</template>
<script lang="ts" setup>
let Props = defineProps({
num: {
type: Number,
default: 0,
},
})
console.log('Props',Props,Props.num)
</script>
想在子组件中使用参数值需要用变量Props
接收defineProps
。
使用的时候直接Props.num
,在html中直接使用num
即可无需加上变量名称。
defineProps
两种写法:
let Props = defineProps({
num: {
type: Number,
default: 0,
},
})
defineProps<{
title:string,
data:number[]
}>()
TS 特有的默认值方式:withDefaults
是个函数也是无须引入开箱即用接受一个props
函数第二个参数是一个对象设置默认值。
withDefaults(defineProps<{
title:string,
data:number[]
}>(),{
title:'张三',
data()=>[1,2,3]
})
子组件向父组件派发数据
父页面
<template>
<p>父组件</p>
<child :num="num" @fn="addNum" @fn2="paramsNum"></child>
</template>
<script lang="ts" setup>
========= vue2需要使用component挂载组件,vue3 不需要! 引入就直接可以使用!!!=========
import Child from './child.vue'
import { ref } from 'vue'
let num = ref(20)
========= 子传父回调 =========
let addNum = () => {
num.value++
}
========= 子传父带参数 =========
let paramsNum = (id: any) => {
console.log('子传父带参数 id', id)
}
</script>
子页面
<template>
<p>我是子组件接收的num:{{ num }}</p>
<button @click="add">add</button>
<button @click="parameter">add带参数</button>
</template>
<script lang="ts" setup>
let Props = defineProps({
num: {
type: Number,
default: 0,
},
})
console.log('Props',Props,Props.num)
// 子传父 需要先定义好emit方法 这点区别比较大 然后调用
let emit = defineEmits<{
(event: 'fn'): void
(event: 'fn2', id: number): void
}>()
let add = () => {
emit('fn')
}
let parameter = () => {
emit('fn2', Props.num)
}
</script>
defineEmits
两种写法:
const emit = defineEmits(['fn','fn2'])
let emit = defineEmits<{
(event: 'fn'): void
(event: 'fn2', id: number): void
}>()
//不带参数
let add = () => {
emit('fn')
}
//带参数
let parameter = () => {
emit('fn2', Props.num)
}
使用
的组件是默认关闭的——即通过模板引用或者
$parent
链获取到的组件的公开实例,不会暴露任何在中声明的绑定。
可以通过defineExpose
编译器宏来显式指定在组件中要暴露出去的属性。
通过defineExpose
,我们从父组件获取子组件实例通过ref
父组件
<MenuCom ref="refMenu"></MenuCom >
//这样获取是有代码提示的
<script setup lang="ts">
import MenuCom from '../xxxxxxx.vue'
//注意这儿的typeof里面放的是组件名字(MenuCom)不是ref的名字 ref的名字对应开头的变量名(refMenu)
const refMenu = ref<InstanceType<typeof MenuCom>>()
//打印子组件属性
console.log(refMenu.value.list )
</script>
这时候父组件想要读到子组件的属性可以通过 defineExpose
暴露
子组件
const list = reactive<number[]>([4, 5, 6])
defineExpose({
list
})