vue3 父子组件通信传值

988 阅读2分钟

vue3父子组件传值与vue2大体是一样,vue3的核心是通过definePropsdefineEmits这两个函数方法来进行传递的。defineProps接收的值与props相同,而defineEmits接收的值与emit相同。


父组件向子组件传值:

首先我们来看父组件如何向子组件传值。

父组件可以通过自定义属性和自定义函数的方式向子组件传值。举例如下:

这里还有一个小tip,就是子组件是以大写开头的驼峰法命名的组件,那么父组件可以直接使用拆分为-的方法进行引用,例如子组件是ChildView,那么组件就为<child-view/>

// 父组件引用子组件 FatherView.vue
<child-view
      :father="fatherValue"
    ></child-view>
<script setup>
import { ref } from 'vue'
import ChildView from './ChildView.vue'

const fatherValue = ref('我是从父组件传递过去的值')
</script>

我们定义了值father向子组件传值。

子组件接受父组件的传值:

子组件接收值: vue3中首先需要引入defineProps接收函数,同时注意该函数只能在setup中进行使用。

// ChildView.vue
<template>
  <div>
    <h1>{{ props.father }}</h1>
  </div>
</template>

<script setup>
import { defineProps } from 'vue'
const props = defineProps(['father'])
</script>

除了以数组的形式引入父组件的传值外,也可以使用对象的形式。

<template>
  <div>
    <h1>{{ father }}</h1>
    <h2>{{ father1 }}</h2>
  </div>
</template>

<script setup>
import { defineProps } from 'vue'
defineProps({
  father: {
    type: String,
    default: ''
  },
  father1: {
    type: String,
    default: ''
  },
  modelValue: {
    type: Boolean,
    default: true
  }
})
</script>

子组件调用父组件的方法:

子组件需要调用父组件传递过来的方法,然后再父组件中通过方法修改值。

首先在父组件自定义方法func

<child-view
      :father="fatherValue"
      :father1="fatherValue1"
      @func="clickFun"
    ></child-view>
<script setup>
import { ref } from 'vue'
import ChildView from './ChildView.vue'

const fatherValue = ref('我是从父组件传递过去的值')
const fatherValue1 = ref('我也是从父组件传递过去的值,啦啦啦')
const clickFun = (data) => {
  alert(data)
}
</script>

子组件通过defineEmits方法进行接收:

<template>
  <div>
    <!-- <h1>{{ props.father }}</h1>
    <h2>{{ props.father1 }}</h2> -->
    <h1>{{ father }}</h1>
    <h2>{{ father1 }}</h2>
    <button @click="handleClick">触发子组件的方法啦</button>
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue'
// const props = defineProps(['father', 'father1', 'modelValue'])
defineProps({
  father: {
    type: String,
    default: ''
  },
  father1: {
    type: String,
    default: ''
  },
  modelValue: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['func'])

const handleClick = () => {
  emit('func', 'hello world')
}
</script>

除了父子组件传值外,我们在类似弹窗过程中也会碰到父组件或者子组件点击时触发子组件是否显示的情况,这种情况就需要使用装饰符了,在vue2中使用的sync在vue3中已经被废弃了,因此如何实现的数据双向绑定也是需要去探讨的问题。

双向绑定的核心是modelvalue,我们可以借助modelValue来改变当前的状态。

// 父组件 FatherView.vue
<template>
  <div>
    <child-view
      :father="fatherValue"
      :father1="fatherValue1"
      v-model="showChild"
      v-if="showChild"
      @func="clickFun"
    ></child-view>
    <button @click="clickFun(fatherValue)">触发父组件的方法啦</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import ChildView from './ChildView.vue'

const fatherValue = ref('我是从父组件传递过去的值')
const fatherValue1 = ref('我也是从父组件传递过去的值,啦啦啦')
const showChild = ref(true)

const clickFun = (data) => {
  alert(data)
  showChild.value = true
}
</script>
// ChildView.vue
<template>
  <div :model-value="modelValue">
    <!-- <h1>{{ props.father }}</h1>
    <h2>{{ props.father1 }}</h2> -->
    <h1>{{ father }}</h1>
    <h2>{{ father1 }}</h2>
    <button @click="handleClick">触发子组件的方法啦</button>
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue'
// const props = defineProps(['father', 'father1', 'modelValue'])
defineProps({
  father: {
    type: String,
    default: ''
  },
  father1: {
    type: String,
    default: ''
  },
  modelValue: {
    type: Boolean,
    default: true
  }
})
// console.log(props.modelValue)

const emit = defineEmits(['func', 'update:modelValue'])

const handleClick = () => {
  emit('func', 'hello world')
  emit('update:modelValue', false)
  // console.log(props.modelValue)
}
</script>