Vue3父子组件通信

一,父传子:props

  • 单向数据流原则
  • 禁止子组件直接修改 prop
  • 通过自定义事件通知父组件更新

App.vue

<template>
  <h2>我是父组件h2>
  <Comp :message = "parentMessage" :user = "user">Comp>
  <button @click = "updateParent">更新父组件数据,传递到子组件了button>
template>
<script setup lang="ts">
  import { ref,reactive } from 'vue'
  import Comp from './Comp.vue'
  const parentMessage = ref('初始消息')
  const user = reactive({name:'andy',age:13})
  const updateParent = () => {
    parentMessage.value = '点击了更新消息'
    user.age++
  }
script>

Comp.vue

<template>
  <div>
    <h3>我是子组件h3>
    <p>接收到的信息是:{{ message }}p>
    <div style="border:1px solid red;">
      <p>用户信息:{{ user.name }},{{ user.age }}岁啦p>
    div>
  div>
template>
<script setup>
const props = defineProps({
  message : String,
  user : Object
})
script>

二,子传父:emits

  • 事件机制
  • 父组件监听子组件上的get-user事件,触发后调用自己方法showUser

App.vue

<template>
  <h2>我是父组件h2>
  <Comp @get-user='showUser'>Comp>
  <P>子组件传来的数据:{{ childData }}P>
template>
<script setup lang="ts">
  import { ref,reactive } from 'vue'
  import Comp from './Comp.vue'
  const childData = ref('')
  const showUser = (data) => {
    childData.value = data
  }
script>

Comp.vue

<template>
  <div>
    <h3>我是子组件h3>
    <div style="border:1px solid red;">
      <button @click = "sendDataToParent">向父组件发送数据button>
    div>
  div>
template>
<script setup>
const emit = defineEmits(['get-user'])
const sendDataToParent = () => {
  emit('get-user','我是来自子组件的用户数据哈')
}
script>

三,双向绑定

1.推荐方法 v-model
  • 单个v-model
    App.vue
<template>
  <h2>我是父组件h2>
  <p>输入框值: {{ inputValue }}p>
  <Comp v-model = "inputValue">Comp>
template>
<script setup lang="ts">
  import { ref} from 'vue'
  import Comp from './Comp.vue'
  const inputValue = ref('')
script>

Comp.vue

<template>
  <div>
    <h3>我是子组件h3>
    <div style="border:1px solid red;">
    	<input type="text" :value='modelValue' @input = "emitInput($event.target.value)">
    div>
  div>
template>
<script setup>
const props = defineProps({
  modelValue:String
})  
const emit = defineEmits(['update:modelValue'])
const emitInput = (value) => {
  emit('update:modelValue',value)
}
script>

  • 多个绑定
    App.vue
<template>
  <h2>我是父组件h2>
  <p>用户名: {{ username }}p>
  <p>年龄: {{ age }}p>
  <Comp v-model:username = "username" v-model:age = "age">Comp>
template>
<script setup lang="ts">
  import { ref} from 'vue'
  import Comp from './Comp.vue'
  const username = ref('张三丰')
  const age = ref('13')
script>

Comp.vue

<template>
  <div>
    <h3>我是子组件h3>
    <div style="border:1px solid red;">
    	<input type="text" :value='username' @input = "updateUsername($event.target.value)" placeholder="请输入姓名">
      <input type="text" :value='age' @input = "updateAge($event.target.value)" placeholder="请输入年龄">
    div>
  div>
template>
<script setup>
const props = defineProps({
  username:String,
  age:Number
})  
const emit = defineEmits(['update:username','update:age'])
const updateUsername = (value) => {
  emit('update:username',value)
}
const updateAge = (value) => {
  emit('update:age',parseInt(value))
}
script>

四,父组件调用子组件方法

  • 父组件 ref 引用
  • 子组件 defineExpose 暴露方法

<template>
  <button @click="callChildMethod">调用子组件方法button>
  <Child ref="childRef" />
template>

<script setup>
import { ref, onMounted } from 'vue';
import Child from './Child.vue';

const childRef = ref(null);

const callChildMethod = () => {
  childRef.value?.getChildData();
};

onMounted(() => {
  // 组件挂载后可以访问子组件实例
});
script>

<script setup>
import { defineExpose } from 'vue';

const getChildData = () => {
  return { name: '子组件数据' };
};

// 暴露方法供父组件访问
defineExpose({
  getChildData
});
script>

五,子组件调用父组件方法

  • 通过事件或者依赖注入
  • 推荐事件触发

<template>
  <button @click="callParentMethod">调用父方法button>
template>

<script setup>
const emits = defineEmits(['parentMethod']);

const callParentMethod = () => {
  emits('parentMethod', '参数');
};
script>

<template>
  <Child @parentMethod="handleParentMethod" />
template>

<script setup>
const handleParentMethod = (param) => {
  console.log('父方法被调用', param);
};
script>

你可能感兴趣的:(前端,vue.js,javascript,前端)