vue3 父子组件通信

82 阅读2分钟

父子组件通信,有 数据方法

一两个月没有写vue忘记一些细节,写一篇文章回忆下,主要看官方文档

基础: v-modelv-bindv-on

1.1 v-model 双向绑定 update:xxx

官方链接:cn.vuejs.org/guide/compo…

  • 发送:v-model不能简写, 属性名可以有一个默认值:modelValue
// Parent.vue 父组件中
<Child v-model="parentMessage" v-model:msg="parentMessage" v-model:code="code">
   <!-- 默认的只有一个对应 modelValue -->
</Child>
  • 接受:props的数据是只读的

// 选项式api: 关键点 propsemit

// Child.vue 子组件中
<template>
 ...
</template>

<script>
export default {
  props: {
    modelValue: String,
    msg: String,
    code:  [String,Number]
  },

 <!-- props: {
    modelValue: {
        type: String,
        default: ""
    },
    msg: {
        type: String,
        default: "javascript"
    },
    code: {
        type: [String,Number],
        default: 300,
    }
  }, -->

  data() {
    return {
      value: this.modelValue,
      message: this.msg,
      status: this.code,
    }
  },

  methods(){
    updata(event){
        emit('update:modelValue', event.target.value);
    },
    updataMsg(event){
        emit('update:msg', event.target.value);
    }
  },
}
</script>

emit 发送数据有两种方式:

1. emit("xxx", data); // xxx对应子组件属性的 @xxx(data) 方法
2. emit('update:modelValue', data);  // Vue 3 中的 v-model 语法糖会自动绑定 modelValue prop 和 @update:modelValue(data) 事件

// 组合式api:关键点:definePropsdefineEmits

// Child.vue 子组件中
<template>
  <div>
    <h1>{{ msg }}</h1>
    <p>{{ modelValue }}</p>
    <p>{{ code }}</p>
  </div>
</template>

<script setup>
import { defineProps } from 'vue'  // defineProps 可以隐式

const props = defineProps(['modelValue', 'msg', 'code'])
const emit  = defineProps(['update:modelValue', 'update:msg'])

const updateValue = (event) => {
  emit('update:modelValue', event.target.value);
  emit('update:msg', event.target.value);
};

<!-- const props = defineProps({
    modelValue: String,
    msg: String,
    code:  [String,Number],
}) -->
</script>

// 组合式api:关键点:defineProps

结合了 propsemit

多个 v-model, 就定义多个 defineModel

// 声明 "modelValue" prop,由父组件通过 v-model 使用
const model = defineModel()
// 或者:声明带选项的 "modelValue" prop
const model = defineModel({ type: String })
// 声明 "count" prop,由父组件通过 v-model:count 使用
const count = defineModel("count")
// 或者:声明带选项的 "count" prop
const count = defineModel("count", { type: Number, default: 0 })

const user = defineModel({
  prop: 'user',
  event: 'update:user',
  type: Object,
  default: () => ({})
});

const items = defineModel({
  prop: 'items',
  event: 'update:items',
  type: Array,
  default: () => []
});

如果 改动了监听事件 event: 'update:itemsEvent', 需要父组件手动监听 update:itemsEvent 事件

<template>
  <ChildComponent
    v-model="modelValue"
    :count="count"
    @update:itemsEvent="updateCount"
  />
</template>

1.2 v-bind 简写形式 :

官方链接:cn.vuejs.org/api/built-i…

单向的

动态的绑定一个或多个 attribute,也可以是组件的 prop。

1.3 其他:

defineExpose 、defineProps、defineEmits、defineModel 是vue3的写法

<script setup> 中可用的编译宏命令,并不需要显式地导入;

defineExpose({ open, }); defineExpose 来显式指定在 <script setup> 组件 中要暴露出去的属性。

Using Provide/Inject