vue组件间通信、数据传递(父子组件,同级组件)

时间:2024-11-16 18:57:00

一、组件目录结构

  • 父组件:
  • 子组件:
  • 子组件:

父组件 app.vue

  1. <template>
  2. <div id="app">
  3. <p>请输入单价: <input type="text" v-model="price"></p>
  4. <page1 :price="price" @downPrice="downPrice"></page1>
  5. <page2></page2>
  6. </div>
  7. </template>
  8. <script>
  9. import Page1 from "./components/page1";
  10. import Page2 from "./components/page2";
  11. export default {
  12. name: "App",
  13. data() {
  14. return {
  15. price: ""
  16. };
  17. },
  18. components: {
  19. Page1,
  20. Page2
  21. },
  22. methods: {
  23. downPrice() {
  24. this.price = (this.price - 1).toString();
  25. }
  26. }
  27. };
  28. </script>

 子组件

  1. <template>
  2. <div>
  3. <p><span>单价:</span><span>{{price}}</span> <button @click="downPrice">降价1元</button></p>
  4. <p>数量: {{count}} </p>
  5. </div>
  6. </template>
  7. <script>
  8. import bus from '../'
  9. export default {
  10. props:{
  11. price:{
  12. type:String,
  13. default:''
  14. }
  15. },
  16. data(){
  17. return{
  18. count:10
  19. }
  20. },
  21. methods:{
  22. downPrice(){
  23. this.$emit('downPrice')
  24. }
  25. },
  26. watch:{
  27. price(newPrice){
  28. bus.$emit('priceChange',newPrice,this.count)
  29. }
  30. }
  31. }
  32. </script>

子组件

  1. <template>
  2. <div>
  3. <p>
  4. <span>总金额:{{totalMoney}}元 </span>剩余金额:
  5. <span>{{balance}}元</span>
  6. </p>
  7. </div>
  8. </template>
  9. <script>
  10. import bus from "../";
  11. export default {
  12. data() {
  13. return {
  14. balance: 1000,
  15. totalMoney: 1000
  16. };
  17. },
  18. mounted() {
  19. bus.$on("priceChange", (price, count) => {
  20. this.balance = this.totalMoney - price * count;
  21. });
  22. }
  23. };
  24. </script>

二、通信过程介绍

1.父组件向子组件传值

1.1在父组件中引入需要通信的子组件

import Page1 from "./components/page1";

1.2 在父组件的components中注册该子组件

  1. components: {
  2. Page1
  3. }

1.3 在父组件的template中使用子组件

<page1></page1>

1.4 将需要传递给子组件的值通过v-bind(如果传递的是固定值,则不需要v-bind,直接属性名,属性值传递即可)

  1. <page1 :price="price"></page1>
  2. // 此处的price则是传递给子组件的值

1.5 在对应的子组件中,通过props属性接收传递过来的值

  1. props:{
  2. price:{
  3. type:String,
  4. default:''
  5. }
  6. }

1.6 在子组件中使用该值

<p><span>单价:</span><span>{{price}}</span></p>

 但是在js 文件中,像这种两个单词拼成的数据,我们习惯用驼峰命名法,所以vue 做了一个转化,如果在组件中属性是 - 表示,它 自动会转化成驼峰式。  传进来的数据是mes-father, 转化成mesFather, 我们在js 里面写mesFather, 一一对应,子组件可以接受到组件。 props 属性是和data, methods 属性并列的,属同一级别。 props 属性里面定义的变量,在 子组件中的template 中可以直接使用。

2.子组件向父组件中传值

2.1 在中,通过触发子组件的方法(这里是自定义的downPrice方法),

 <p><span>单价:</span><span>{{price}}</span> <button @click="downPrice">降价1元</button></p>

2.2 在子组件的methodsdownPrice中,通过this.$emit(),将事件和参数传递给父组件

  1. downPrice(count){
  2. this.$emit('downPrice',count)
  3. }
  4. // downPrice 是传递给父组件的事件,父组件触发并相应这个方法
  5. // count 传递给父组件的参数,在父组件中,可以对和这个参数进行相应操作

2.3 在父组件中接受子组件传递的事件downPrice和数据

<page1 :price="price" @downPrice="downPrice"></page1>

2.4 父组件对接收到的事件和数据做出响应

  1. downPrice(count) {
  2. this.price = (this.price - 1).toString();
  3. // = ( - count).toString();
  4. }

3、父组件调用子组件方法

方法一:

3.1 在使用子组件时,给子组件加一个ref引用

<page1 :price="price" @downPrice="downPrice" ref="page1"></page1>

3.2 父组件通过this.$refs即可找到该子组件,也可以操作子组件的方法

this.$refs.page1.子组件方法

方法二:

3.3 通过$children,可以获取到所有子组件的集合

this.$children[0].某个方法

4、子组件调用父组件方法

4.1 通过 $parent可以找到父组件,进而调用其方法

this.$parent.父组件方法

5、平级组件通信

同级组件不能直接传值,需要一个中间桥梁,可以先将数据传递给公共的父组件,然后父组件再将数据传递给需要的子组件。

5.1 定义一个公共文件 

代码很简单(就2句),只是创建一个空的vue实例

  1. import Vue from 'vue'
  2. export default new Vue()

5.2 在需要通信的同级组件中分别引入文件

import bus from  '../'

5.3 在中,通过$emit将事件和参数传递给

  1. price(newPrice){
  2. bus.$emit('priceChange',newPrice,this.count)
  3. }

5.4 在 中,通过$on接收接收参数和相应事件

  1. bus.$on("priceChange", (price, count) => {
  2. this.balance = this.totalMoney - price * count;
  3. });

一般大型的项目,推荐使用Vuex来管理组件之间的通信