vue3(四)父子组件传值

299 阅读1分钟

父子组件传值

###父组件给子组件传值

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>