vue用组件化简化了我们编写代码的复杂度,组件之间经常会出现数据传递的情况,那么组件之间是怎样通信的呢?

使用props传递数据

组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。父组件的数据需要通过 prop 才能下发到子组件中。

假设我们现有一个这样的父组件
        var vm = new Vue({
            el: "#app",
            data: {
                parentMessage: 'h'
            },
            components: {
                Child
            }
        })

可以看到在该父组件中注册了一个子组件Child,还有一条data数据parentMessage
接下来我们怎样在子组件Child中拿到parentMessage呢?
在子组件中这样写

var Child = {
            //声明当前组件内部能够接受一个message的属性,如果是驼峰式命名,在传参数的时候使用短横线连接的小写
            props: ["message", "myMessage"],
            template: '<span>{{message}} {{myMessage}}</span>'
        }

在子组件中我们在props中写了一个自定义属性mymessage来接收从父组件中传来的数据,然后通过该自定义属性在父组件中传递

<div id="app">
        <child message="hello" :my-message="parentMessage"></child>
        <child message="hi"></child>
        <input type="text" v-model="parentMessage">
    </div>

上述代码中我们使用自定义的属性my-message接收到了父组件中定义的数据parentMessage,然后再将这个数据传递到子组件中去显示,效果如下,我们拿到了父组件中的parentMessage

props接收后对数据的修改

在这里我只记录一下用子组件的计算属性去修改从父组件中拿到的数据

<div id="app">
        <child :size="parentSize"></child>
    </div>
    <script src="./vue.js"></script>
    <script>
        var Child = {
            template: '<div>{{size}}</div>',
            props: ['size'],
        }
        var vm = new Vue({
            el: '#app',
            data: {
                parentSize: 'THREE'
            },
            components: {
                Child
            }
        })
    </script>

如上代码,子组件中利用前面讲到的方法拿到了父组件中传递的parentSize,假如子组件直接写一个方法去修改父组件的数据在vue的单向数据流中是不可能的,这里我们可以将parentSize放到一个计算属性中去操作,相当于另外创建了一个对象
所以我们在子组件Child中写一个computed计算属性,其中写一条属性normalSize,来将size全部转换为小写

computed: {
   normalSize() {
     return this.size.trim().toLowerCase();
   }
}

在子组件的模板中添加上计算属性normalSize的显示

template: '<div>{{size}} {{normalSize}}</div>'

结果如下

遍历并显示父组件传来的数组

在父组件中的data声明了一个数组lis

    var vm = new Vue({
                el: "#app",
                data: {
                    lis: ['a', 'b', 'c']
                },
                components: {
                    List
                }
            })

在子组件中得到并遍历

var List = {
   template: '<div><div v-for="item in lists">{{item}}</div></div>',
   props: ['lists']
}

然后在父组件模板中将子组件显示出来

    <div id="app">
        <list :lists="lis"></list>
    </div>

这里要注意数据传递的过程
首先还是像之前一样通过自定义属性在父组件模板中得到数组,然后传递到子组件的模板中去使用

非父子组件之间的通信

要实现非父子组件之间的通信就不得不说到$emit
发出的可以被自定义监听的事件,这里我通过一个小示例来解释一下

子组件事件实现父组件数据的变化

这里是一个点击子组件让父组件中count统计点击次数的示例

<div id="app">
        {{total}}
        <!--在child组件中添加一个监听事件来监听自定义事件add-parent-total,当触发本事件时执行父组件中的addTotal方法使得total改变-->
        <child @add-parent-total="addTotal"></child>
        <child></child>
    </div>
    <script src="vue.js" charset="utf-8"></script>
    <script>
        var Child = {
            template: '<button @click="add">{{counter}}</button>',//子组件模板的button中添加一个点击事件,来调用子组件中的方法,add
            data() {
                return {
                    counter: 0
                }
            },
            methods: {
            //在子组件中写一个方法来通过$emit触发一个自定义的add-parent-total事件
                add() {
                    this.counter++;
                    this.$emit('add-parent-total');
                }
            }
        }
        var vm = new Vue({
            el: '#app',
            data: {
                total: 0
            },
            methods: {
                addTotal(preload) {//在父组件添加一个方法,来操作父组件中的数据total
                    this.total += 1;
                }
            },
            components: {
                Child
            }
        })
    </script>

在上面的例子中我们还是无法绕过子组件无法改变父组件中内容的事实,但是我们通过触发父组件模板中的一个自定义事件,让父组件自己调用自己的方法,改变了自己的内容,利用了自定义事件和$emit的方式

非父子组件通信

在非父子组件通信的时候我们通过一个空的vue对象来实现
首先声明一个vue实例

var vm = new Vue({
            el: '#app',
            data: {

            },
            components: {
                AppHead,
                AppBody
            }
        })

在实例中注册了两个组件,他们两个算是兄弟组件,我们就让这两个兄弟组件实现通信

接着声明一个空的vue实例

var bus = new Vue()

然后去写两个子组件

var AppHead = {
            template: '<div><button @click="add">添加</button></div>',
            methods: {
                add() {
                    bus.$emit('change', 1)
                }
            }
        }
        var AppBody = {
            template: `<div>{{counter}}</div>`,
            data() {
                return {
                    counter: 0
                }
            },
            created() {
                bus.$on('change', count => {
                    this.counter += count
                })
            }
        }

在AppHead组件中我们让它在被点击是触发一个add方法,这个add 方法用来发出一个基于bus发出的自定义事件change
然后在AppBody中写了一个在AppBody被创建之后就会时刻监听bus 的change事件的方法,这样一旦change事件被触发就会执行这个监听事件,实现了兄弟组件之间的通信

添加上父组件的模板将两个兄弟组件放进去实现效果

 
<div id="app">
        <app-head></app-head>
        <app-body></app-body>
    </div>
 

浅谈vue学习之组件通信的更多相关文章

  1. Vue学习笔记-组件通信-子传父(自定义事件)

    props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中.我们应该如何处理呢?这个时候,我们需要使用自定义事件来完成.什么时候需要自定义事件呢?当子组件需要向父组件传递 ...

  2. Vue学习笔记-组件通信-父传子(props中的驼峰标识)

    在组件中,使用选项props来声明需要从父级接收到的数据.props的值有两种方式:方式一:字符串数组,数组中的字符串就是传递时的名称.方式二:对象,对象可以设置传递时的类型,也可以设置默认值等. & ...

  3. 浅谈Vue不同场景下组件间的数据交流

    浅谈Vue不同场景下组件间的数据“交流”   Vue的官方文档可以说是很详细了.在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完 ...

  4. 【Vue】浅谈Vue不同场景下组件间的数据交流

    浅谈Vue不同场景下组件间的数据“交流”   Vue的官方文档可以说是很详细了.在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完 ...

  5. 浅谈Vue.js

    作为一名Vue.js的忠实用户,我想有必要写点文章来歌颂这一门美好的语言了,我给它的总体评价是“简单却不失优雅,小巧而不乏大匠”,下面将围绕这句话给大家介绍Vue.js,希望能够激发你对Vue.js的 ...

  6. 浅谈Vue响应式(数组变异方法)

    很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗? 查看官方文档才发现,不是女神太高冷,而是你没用对方法. 看来想让女神自己动,关键得用 ...

  7. 浅谈Vue下的components模板

    浅谈Vue下的components模板在我们越来越深入Vue时,我们会发现我们对HTML代码的工程量会越来越少,今天我们来谈谈Vue下的 components模板的 初步使用方法与 应用 我们先来简单 ...

  8. Vue 非父子组件通信方案

    Vue 非父子组件通信方案 概述 在 Vue 中模块间的通信很普遍 如果是单纯的父子组件间传递信息,父组件可以使用 props 将数据向下传递到子组件,而在子组件中可以使用 events (父组件需要 ...

  9. 转:浅谈深度学习(Deep Learning)的基本思想和方法

    浅谈深度学习(Deep Learning)的基本思想和方法  参考:http://blog.csdn.net/xianlingmao/article/details/8478562 深度学习(Deep ...

随机推荐

  1. ui自动化之selenium操作(五)简单元素操作--续

    1. 多窗口切换 有时候需要在多窗口切换,webdriver提供了switch_to_window()方法支持切换窗口: from selenium import webdriver import o ...

  2. 百度贴吧自动回帖的两种方式,使用requests(urllib2)和selenium两种方式回帖

    本文介绍,回复贴吧指定某楼层主的帖子的方法.在这里不介绍无限发主贴和无限回复主贴的方法,无限发主题帖会爆吧,引起别人的反感,并且很容易遭到吧主的封杀:无限回主题帖,会让整个帖子的每楼的回复充满了自己的 ...

  3. Thiago2(TPO AI.ROSTO):集成式AI换脸软件(Autodesk Flame)

    如标题一样,Thiago2 是一款集成式AI换脸软件(TPO AI.ROSTO),需要与Autodesk Flame结合使用,从demo来看完成度还是很高的,算是一种完全GUI版的DeepFaceLa ...

  4. linux安装配置Redis,Swoole扩展

    我是使用的是lnmp环境(php5.6.3) 一.安装redis数据库(参考w3c手册) 下载地址:http://redis.io/download 本教程使用的最新文档版本为 2.8.17,下载并安 ...

  5. html b标签 语法

    html b标签 语法 标签b是什么意思? b的意思是bold,b标签主要用于html中规定粗体文本,该标签内的字符将被设为粗体.B标签所传达的意思只是加粗,没有任何其它的作用. 作用:规定粗体文本. ...

  6. XML to HTML

    本章讲解如何把 XML 数据显示为 HTML. 在 HTML 中显示 XML 数据 在上一节中,我们讲解了如何通过 JavaScript 来解析 XML 并访问 DOM. 本例遍历一个 XML 文件 ...

  7. Intellij Idea Spring Boot 热部署

    1. POM 文件添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  8. 译-使用Scroll Snapping实现CSS控制页面滚动

    特别声明,本文翻译自@alligatorio的Control Page Scroll in CSS Using Scroll Snapping一文,受限于译者能力,译文或存在不足,欢迎大家指出.如需转 ...

  9. socket的补充

  10. MVC的一个简单实例

    基本思路: 一个Regist.jsp注册页面,用于收集用户信息,发送请求给控制器Servlet:控制器层Servlet封装模型层对象 jBean,并调用其方法regiser实现用户信息的保存:模型层J ...