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

总结一下对vue组件通信的理解和使用。

一、组件目录结构

  • 父组件:app.vue
  • 子组件:page1.vue
  • 子组件:page2.vue

父组件 app.vue

<template>
  <div id="app">
    <p>请输入单价: <input type="text" v-model="price"></p>
    <page1 :price="price" @downPrice="downPrice"></page1>
    <page2></page2>
  </div>
</template>

<script>
import Page1 from "./components/page1";
import Page2 from "./components/page2";
export default {
  name: "App",
  data() {
    return {
      price: ""
    };
  },
  components: {
    Page1,
    Page2
  },
  methods: {
    downPrice() {
      this.price = (this.price - 1).toString();
    }
  }
};
</script>

子组件 page1.vue

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

    </div>
</template>
<script>
import bus from  '../eventBus.js'
export default {
    props:{
        price:{
            type:String,
            default:''
        }
    },
    data(){
        return{
            count:10
        }
    },
    methods:{
        downPrice(){
            this.$emit('downPrice')
        }
    },
    watch:{
       price(newPrice){
          bus.$emit('priceChange',newPrice,this.count) 
       } 
    }
}
</script>

子组件 page2.vue

<template>
    <div>
        <p>
            <span>总金额:{{totalMoney}}元 </span>剩余金额:
            <span>{{balance}}元</span>
        </p>
    </div>
</template>
<script>
import bus from "../eventBus.js";
export default {
  data() {
    return {
      balance: 1000,
      totalMoney: 1000
    };
  },
  mounted() {
    bus.$on("priceChange", (price, count) => {
      this.balance = this.totalMoney - price * count;
    });
  }
};
</script>

二、通信过程介绍

1.父组件向子组件传值

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

import Page1 from "./components/page1";

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

components: {
    Page1
  }

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

<page1></page1>

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

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

//  此处的price则是传递给子组件的值

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

props:{
        price:{
            type:String,
            default:''
        }
  }

1.6 在子组件中使用该值

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

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

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

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

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

downPrice(count){
            this.$emit('downPrice',count)
  }

// downPrice 是传递给父组件的事件,父组件触发并相应这个方法
// count 传递给父组件的参数,在父组件中,可以对和这个参数进行相应操作

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

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

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

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

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

方法一:

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

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

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

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

打印出获取到的子组件信息:

image.png

方法二:

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

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

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

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

this.$parent.父组件方法

打印出的父组件信息


image.png

5、平级组件通信

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

5.1 定义一个公共文件 eventBus.js

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

import Vue from 'vue'
export default new Vue()

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

import bus from '../eventBus.js'

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

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

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

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

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

demo查看
原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343