vue3-父子组件传参

98 阅读2分钟

父组件传参,子组件接收

// 接受父组件传递过来的值

// 方式一:注意与下列传统方式的区别,区别在于"定义属性的位置"
 const prop = defineProps({
   title: {
     type: String,
     default: 'ssd',
   },
 });

// 方式二:
// 1、ts特有的定义属性方式
// 2、withDefaults是ts特有的定义默认值方式,只能接受"ts方式定义属性的defineProps"
interface props {
  title: number;
}
const prop = withDefaults(defineProps<props>(), { title: 123 });

// script里调用(template调用时可直接使用title,无需加prop前缀)
console.log(prop.title);

子组件传参,父组件接收

// 向父组件传递值
// 方式一:数组定义事件
const emit = defineEmits(['onClick']);

// 方式二:
// 1、ts特有的定义事件defineEmits
interface emits {
  (e: 'onClick', name: string): void;
}
const emit = defineEmits<emits>();

// 触发
const handleClick = () => {
  emit('onClick', 'menffy');
};

子组件对父组件暴露方法或变量

defineExpose({
  exposeValue: '123',
  exposeOpen: () => console.log('子组件暴露的方法被调用啦!!!!!'),
  showClientSize: () => {
    console.log('clientLeft', document.body.clientLeft);
    console.log('clientHeight', document.body.clientHeight);
    console.log('clientTop', document.body.clientTop);
    console.log('clientWidth', document.body.clientWidth);
  },
});

完整例子

父组件
<template>
  <div>
    <test ref="TestRef" :title="12" @on-click="getSub" />
    <t-button @click="handleExpose">子组件暴露的方法或变量</t-button>
  </div>
</template>

<script lang="ts">
export default {
  name: 'ApplyAWSIndex',
};
</script>
<script setup lang="ts">
import { ref } from 'vue';
import Test from './test.vue';

// TestRef的类型为Test组件的实例类型
const TestRef = ref<InstanceType<typeof Test>>();

const getSub = (args) => {
  console.log(args);
};

// 父组件通过TestRef来调用子组件暴露的方法或变量
const handleExpose = () => {
  console.log('暴露的子组件变量:', TestRef.value?.exposeValue);
  console.log('暴露的子组件方法:', TestRef.value?.exposeOpen());
  console.log('暴露的子组件方法:', TestRef.value?.showClientSize());
};
</script>

<style scoped></style>
子组件
<template>
  <div>
    <span>{{ title }}</span>
    <t-button @click="handleClick">传递给父组件</t-button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// !!!接受父组件传递过来的值!!!

// 方式一:注意与下列传统方式的区别,区别在于"定义属性的位置"
// const prop = defineProps({
//   title: {
//     type: String,
//     default: 'ssd',
//   },
// });

// 方式二:
// 1、ts特有的定义属性方式
// 2、withDefaults是ts特有的定义默认值方式,只能接受"ts方式定义属性的defineProps"
interface props {
  title: number;
}
const prop = withDefaults(defineProps<props>(), { title: 123 });

// script里调用(template调用时可直接使用title,无需加prop前缀)
console.log(prop.title);

// ######################################################

// !!!向父组件传递值!!!

// 方式一:数组定义事件
// const emit = defineEmits(['onClick']);

// 方式二:
// 1、ts特有的定义事件defineEmits
interface emits {
  (e: 'onClick', name: string): void;
}
const emit = defineEmits<emits>();

// 触发
const handleClick = () => {
  emit('onClick', 'menffy');
};

// ######################################################

// !!!子组件对父组件暴露方法或变量!!!
defineExpose({
  exposeValue: '123',
  exposeOpen: () => console.log('子组件暴露的方法被调用啦!!!!!'),
  showClientSize: () => {
    console.log('clientLeft', document.body.clientLeft);
    console.log('clientHeight', document.body.clientHeight);
    console.log('clientTop', document.body.clientTop);
    console.log('clientWidth', document.body.clientWidth);
  },
});
</script>
<style scoped></style>