父子组件传值
###父组件给子组件传值
js
父组件,通过v-bind,简写":",绑定一个数据
<template>
<HelloWorld :msg="message"></HelloWorld>
</template>
<script setup>
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const message = ref('我是父组件message')
</script>
<style scoped>
</style>
子组件,通过defineProps接收
<template>
<div>
这里是子组件
</div>
<div>
{{ msg }}
</div>
</template>
<script setup>
const props = defineProps({
msg: {
default: "默认值",
type: String
}
})
</script>
Ts
父组件还是一样
<template>
<HelloWorld :msg="message" :data="data"></HelloWorld>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const message = ref('我是父组件message')
const data = reactive<number[]>([1, 2, 3])
</script>
子组件写法稍微有点不同
<template>
<div>
这里是子组件
</div>
<div>
{{ msg }}
{{ data }}
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
msg: string
data?: number[]
}>()
console.log(props);
</script>
还有一种ts特有的默认值方式:withDefaults,因为 defineProps 声明的没有给props 提供默认值的方式。为了解决这个问题,可以使用 withDefaults
type Props = {
msg?: string,
data?: number[]
}
const props = withDefaults(defineProps<Props>(),
{
msg: '默认值',
// 引用数据类型需要通过函数返回的方式设置默认值
data: () => [1, 2, 3]
}
)
console.log(props);
</script>
子组件给父组件传值
在子组件中绑定一个 click 事件,通过 defineEmits 注册一个自定义事件(返回一个emit),通过点击 click 触发 emit 事件传递参数
<template>
<div>
这里是子组件
{{ msg }}
{{ data }}
</div>
<button @click="change">改变文字</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{
msg: string,
data: number[]
}>()
const childMsg = '文字文字文字'
const emit = defineEmits(["change"])
const change = () => {
emit('change', childMsg)
}
// 如果是ts也可以这种方式
// const emit = defineEmits<{
// (e: "change", childMsg: string): void
// }>()
</script>
父组件通过 "@change="parentChange" 接受子组件自定义的 change 事件,后面是父组件自定义的函数名称,调用可获取子组件传过来的参数
<template>
<HelloWorld :msg="message" :data="data" @change="parentChange"></HelloWorld>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const message = ref('我是父组件message')
const data = reactive<number[]>([1, 2, 3])
const parentChange = (msg: string) => {
console.log('父组件接收的参数:', msg);
}
</script>
子组件还可以通过 defineExpose 把属性和方法暴露出去给父组件
子组件:
<template>
我是子组件
</template>
<script setup lang='ts'>
const list = [1, 2, 3]
const childPrint = () => {
console.log('我是子组件的方法')
}
defineExpose({
list,
childPrint
})
</script>
父组件使用 ref 获取子组件暴露的属性和方法, child.value.childPrint()
<template>
<HelloWorld ref="child"></HelloWorld>
<button @click="onClick">调用子组件方法</button>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import HelloWorld from '../components/HelloWorld.vue'
const child = ref()
const onClick = () => {
child.value.childPrint()
}
onMounted(() => {
console.log(child.value.list);
})
</script>