父组件给子组件传值
父组件通过 v-bind给子组件绑定一个数据
// parent.vue
<template>
<div>
<children :params="params"></children>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import children from './children'
const params = ref<string>('我是传递过来的数据')
</script>
子组件通过defineProps接收父组件传递过来的数据
defineProps 是vue3的写法并且是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入;在vue3的非语法糖setup和在vue2中的写法是 props 。
注意: 因为所有的 props 都遵循着
单向数据流原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。所以子组件无法直接修改父组件传递过来的值
// children.vue
<template>
<div>
{{ params }}
</div>
</template>
<script setup lang="ts">
const props = defineProps({
params: String,
title: {
type: String,
default: '我是默认值'
}
})
// 如果使用ts,可以通过泛型标注来声明 props
const props = defineProps<{
params?: string // 非必传
}>()
// 如果使用ts且需要设置默认值 可以通过withDefaults
const props = withDefaults(defineProps<{
params?: string,
arr: string[],
}>(), {
// 默认值
arr: () => ['默认值1', '默认值2']
})
</script>
子组件给父组件传值
通过defineEmits派发一个事件,通过事件传递参数
defineEmits 是vue3的写法并且是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入;在vue3的非语法糖setup中的写法是 emits 。
// children.vue
<template>
<div>
<button @click="handleSendParams">派发事件给父组件</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const emit = defineEmits(['onSendParams'])
const handleSendParams = () => {
emit('onSendParams', '传递给父组件的数据')
}
// 如果使用ts,可以通过泛型标注来声明 emit
const emit = defineEmits<{
(e: 'onSendParams', params: string): void
}>
</script>
父组件通过v-on监听子组件派发的事件
// parent.vue
<template>
<div>
<children @onSendParams="handleGetParams"></children>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import children from './children'
const handleGetParams = (params) => {
console.log(params) // 传递给父组件的数据
}
</script>
子组件向父组件暴露属性或方法
使用 <script setup> 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。即我们无法通过ref获取到组件的任何属性或方法
可以通过 defineExpose 来显式指定在 <script setup> 组件中要暴露出去的属性:
// children.vue
<script setup lang="ts">
import { reactive } from 'vue'
const list = reactive<number[]>(['1', '2', '3'])
const handle = () => {
console.log('handle')
}
defineExpose({
list,
handle
})
</script>
父组件通过ref获取子组件暴露出来的属性
// parent.vue
<template>
<div>
<children ref=""childrenRef></children>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import children from './children'
// 声明一个同名的ref,获得组件的引用
const childrenRef = ref()
console.log(childrenRef.value) // { list: ['1', '2', '3'] }
childrenRef.handle() // 调用子组件的方法
</script>