Vue.js 父子组件数据传递:props 和事件

Vue.js 父子组件数据传递:props 和事件

今天我们来聊聊 Vue.js 中父子组件之间的数据传递。这是组件化开发的核心之一,理解并掌握它,能让你写出结构清晰的 Vue 应用。

Vue 提供了两个主要的机制来实现父子组件通信:

  1. props:父组件向子组件传递数据。
  2. 事件:子组件向父组件发送消息。

让我们一步步来看这两个机制的用法吧!

一、通过 props 传递数据

props 是 Vue 提供的一种机制,用来从父组件向子组件传递数据。子组件通过 props 接收数据,并将它作为只读属性使用。

示例:父组件向子组件传递标题

1. 定义子组件
vue 复制代码
<template>
  <div>
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    title: {
      type: String,
      required: true
    }
  }
};
</script>

这里子组件定义了一个 props 属性 title,它接收父组件传递的字符串数据。

2. 使用子组件
vue 复制代码
<template>
  <div>
    <ChildComponent title="这是父组件传递的标题" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  name: 'ParentComponent',
  components: {
    ChildComponent
  }
};
</script>

注意事项

  • 子组件的 props 是只读的,不能直接修改。
  • 可以通过 typerequired 等属性对 props 进行类型校验。

二、通过事件发送消息

如果需要从子组件将消息传递给父组件,可以通过自定义事件实现。

示例:子组件发送点击事件

1. 定义子组件
vue 复制代码
<template>
  <button @click="notifyParent">点击我</button>
</template>

<script>
export default {
  name: 'ChildComponent',
  methods: {
    notifyParent() {
      this.$emit('button-clicked', '子组件按钮被点击了!');
    }
  }
};
</script>

这里子组件在按钮点击时,使用 $emit 方法触发了一个自定义事件 button-clicked,并传递了一个消息。

2. 使用子组件
vue 复制代码
<template>
  <div>
    <ChildComponent @button-clicked="handleButtonClick" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  name: 'ParentComponent',
  components: {
    ChildComponent
  },
  methods: {
    handleButtonClick(message) {
      alert(message);
    }
  }
};
</script>

父组件通过 @button-clicked 监听子组件的事件,并调用 handleButtonClick 方法处理事件。

小结

  • $emit 用于在子组件中触发自定义事件。
  • 父组件使用 @事件名v-on:事件名 来监听子组件事件。

三、双向绑定的简化写法(v-model

在某些场景下,父子组件之间需要实现双向数据绑定,比如表单输入。这时可以用 v-model 提供的简化写法。

示例:子组件支持双向绑定

1. 定义子组件
vue 复制代码
<template>
  <input :value="value" @input="$emit('update:modelValue', $event)" />
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    modelValue: String
  }
};
</script>

这里通过 v-model 绑定的规范:props 接收 modelValue,事件触发 update:modelValue

2. 使用子组件
vue 复制代码
<template>
  <div>
    <ChildComponent v-model="inputValue" />
    <p>输入的内容是:{{ inputValue }}</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  name: 'ParentComponent',
  components: {
    ChildComponent
  },
  data() {
    return {
      inputValue: ''
    };
  }
};
</script>

小结

  • v-model 是父子组件实现双向绑定的快捷方式。
  • 子组件中需要监听 modelValue 的变化,并通过事件更新值。

四、综合示例:父子双向通信

我们把上面的知识点整合起来,写一个父子双向通信的完整例子。

父组件和子组件的代码

子组件:Counter
vue 复制代码
<template>
  <div>
    <button @click="decrement">-</button>
    <span>{{ count }}</span>
    <button @click="increment">+</button>
  </div>
</template>

<script>
export default {
  name: 'Counter',
  props: {
    count: Number
  },
  methods: {
    increment() {
      this.$emit('update:count', this.count + 1);
    },
    decrement() {
      this.$emit('update:count', this.count - 1);
    }
  }
};
</script>
父组件:App
vue 复制代码
<template>
  <div>
    <Counter v-model:count="totalCount" />
    <p>当前计数:{{ totalCount }}</p>
  </div>
</template>

<script>
import Counter from './Counter.vue';

export default {
  name: 'App',
  components: {
    Counter
  },
  data() {
    return {
      totalCount: 0
    };
  }
};
</script>

效果

  • 父组件通过 v-model 绑定计数值。
  • 子组件负责增减计数,并通知父组件更新值。

五、总结

父子组件通信是 Vue 的基础功能,主要依靠两种机制:

  1. props:从父组件向子组件传递数据(单向数据流)。
  2. 事件 :子组件通过 $emit 通知父组件,支持双向通信。

此外,v-model 是简化父子组件双向绑定的快捷方式。

相关推荐
coding随想几秒前
JavaScript中的原始值包装类型:让基本类型也能“变身”对象
开发语言·javascript·ecmascript
zhangxingchao3 分钟前
Flutter入门:Flutter开发必备Dart基础
前端
佚名猫13 分钟前
vue3+vite+pnpm项目 使用monaco-editor常见问题
前端·vue3·vite·monacoeditor
满分观测网友z15 分钟前
vue的<router-link>的to里面的query和params的区别
前端·javascript·vue.js
BillKu17 分钟前
Vue3 + TypeSrcipt 防抖、防止重复点击实例
前端·javascript·vue.js
鱼樱前端18 分钟前
Vue3结合three和babylonjs实现3D数字展厅效果
前端·vue.js
Themberfue21 分钟前
Vue ⑥-路由
前端·javascript·vue.js
whatever who cares23 分钟前
React hook之useRef
前端·javascript·react.js
kooboo china.32 分钟前
Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(八):异步处理逻辑详解
前端·css·人工智能·编辑器·html·交互