一、父传子 defineProps
1、父组件传递
父: App.vue, 通过使用组件 <导入的组件名 :属性名1=“” :属性名2=“”></导入的组件名>,传递给子组件
传递了一个字符串类型是不需要v-bind,也就是不需要冒号,非字符串类型的必须加 v-bind ( : )
<template>
<div>父集</div>
<hr>
<!--v-bind:属性名 或者 简写 :属性名
平时绑定的数据可以直接赋值,也可以使用v-bind来进行动态绑定
下面:
如果使用 title="name", 那么传递的的值就是name
如果使用 :title="name", 那么传递的的值就是下面定义的lvmanba
-->
<waterFall title="name" :arr="[1,2,3]"></waterFall>
</template>
<script setup lang='ts'>
import {
ref,reactive } from 'vue'
import waterFall from './components/water-fall.vue';
let name = "lvmanba"
</script>
2、子组件接收
通过defineProps来接收父传递过来的属性。defineProps是无须引入的直接使用即可
<template>
<div>子集</div>
<div>接收的字符串值为: {
{
title }}</div>
<div>接收的数组值为: {
{
arr }}</div>
</template>
<script setup lang='ts'>
import {
ref,reactive } from 'vue'
//方法1:接收父组件传递过来的值使用 defineProps函数。他接收一个对象,里面的属性就是父传递过来的参数。
defineProps({
title:{
type: String,
default: "默认值",
required:true //必须要求填写数据
},
arr:{
type: Array<Number>, //或者使用Number[]
}
})
//上面可以完成在模版中使用,如果想在ts中使用,则赋值给一个变量即可以在模版,也可以在ts中使用
const props = defineProps({
title:{
type: String,
default: "默认值",
required:true
},
arr:{
type: Array<Number>,
}
})
console.log(props.title) //这样就可以读取到了。
// 方法2:有了ts 可以直接使用泛型自变量的形式来接收
//接受一个泛型,里面是对象
defineProps<{
title:string,
arr: number[]
}>()
// 赋值给变量,就可以在ts中使用了。
const props = defineProps<{
title: string,
arr: number[]
}>()
/*
方法3, 如果父类没有传递过来参数,就会报错,需要设置默认值。可以在方法2的基础上修改,使用ts特有的 withDefaults
它是一个函数,两个参数
1、第一个参数只能接受defineProps的返回值。
2、第二个参数是一个对象,用来设置默认值的, 如果类型复杂,需要使用一个函数来返回的。
如 arr:()=>{}
*/
const props = withDefaults(defineProps<{
title: string,
arr: number[]
}>(),{
title: "我是默认值",
arr: ()=>[0]
})
//上面的写法也可以分开写,单独定义类型,然后直接使用defineProps
type prop = {
title: string,
arr: number[]
}
const props = withDefaults(defineProps<prop>(),{
title: "我是默认值",
arr: ()=>[0]
})
</script>
还有另外几种比较高级的用法
<template>
<div>{
{name}}</div>
</template>
<script generic="T" setup lang='ts'>
import {
ref,reactive } from 'vue'
//如果name类型比较复杂,如果传递的是一个字符串数组,可以用下面方法接收
//方法1,使用PropType
import type {
PropType } from 'vue';
const props = defineProps({
name:{
type: Array as PropType<string[]>,
required: true
}
})
// 方法2 在<script generic="T" setup lang='ts'>,它是Vue3 对defineProps的改进,新增泛型支持。
defineProps<{
name:T[]
}>()
</script>
<style scoped>
</style>
二、子传父 defineEmits
1、方法一
子组件传值给父组件主要是子组件通过defineEmits注册一个自定义事件,而后触发emit去调用该自定义事件,并传递参
数给父组件。defineEmits 是一个组合式 API,用于在组件中定义可以触发的事件。
四步骤:注册事件,传递参数,组件中使用事件,接收参数
子组件代码
<template>
<div>子集</div>
<button @click="send">给父组件传值</button>
</template>
<script setup lang='ts'>
import {
ref,reactive } from 'vue'
/*
第一种方式:
使用用defineEmits 注册一个自定义事件,帮助你定义组件能触发的事件。
格式为: 子组件waterFall.vue
const emit = defineEmits(['方法1','方法2'...])
const xxx = () =>{ //xxx 子组件中某按钮绑定的时间名称
emit('方法1','参数1','参数2'...)
emit('方法2','参数1','参数2'...)
}
父组件中接收
<waterFall @方法1="mymethod1" @方法2="mymethod2" ></waterFall>
const mymethod1 = () =>{
}
const mymethod2 = () =>{
}
*/