每一个.vue 文件就是一个 组件,组件和组件相互组合,就成了一个应用,这就涉及到的组件和组件之间的通信,最常用的就是父子之间的通信。在vue 中, 在一个组件中通过 import 引入另一个组件,这个组件就是父组件,被引入的组件就是子组件。

【一】父组件→子组件

(1)父组件传递数据

 在vue-cli 项目中,src 文件夹下有一个App.vue 文件,它的script标签中

  1. import HelloDemo from './components/HelloDemo'

那么 App.vue 就是父组件,components 文件夹下的HelloDemo.vue 就是子组件。父组件通过props 向子组件传递数据,子组件通过自定义事件向父组件传递数据。

 父组件向子组件传值, 它主要是通过元素的属性进行的. 在App.vue 的template中,有一个

  1. <hello-demo></hello-demo>

这就是我们引入的子组件.  给其添加属性如

  1. <hello-demo :mes-father="mesFather"></hello-demo>

父组件数据mesFather为

  1. return {
  2. 'mesFather':'message from father,我是来自父组件的数据'
  3. }

父组件将数据传递进去,子组件需要接收才能使用. 怎样接收呢?

(2)子组件接收数据

在HelloDemo.vue 中, export default 后面的对象中,添加一个字段props, 它是一个数组, 专门用来接收父组件传递过来的数据. props: ["mesFather"], 这里定义了mesFather 字符串, 和父组件中定义的元素的属性一一对应。

  1. export default{
  2. props:['mesFather']
  3. }

但是我们在父组件,就是在 <hello-demo> 元素中定义的属性是mes-father, 没有一一对应啊?  这主要是因为,在html 元素中大小写是不敏感的。

如果我们写

  1. <hello-demo :mesFather="mesFather"></hello-demo>

里面的mesFather  就会转化成mesfather, 相当于我们向子组件传递了一个mesfather数据, 如果在js 文件中,我们定义 props: ["mesFather"],我们是接受不到数据的,因为js 是区分大小写的, 所以只能写成props: ["mesfather"]。

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

App.vue 的template 更改如下:

  1. ①<hello-demo :mes-father="mesFather"></hello-demo>
  2.  
  3. import HelloDemo from './components/HelloDemo'
  4. export default{
  5. name: 'App',
  1. data(){
    return {
    'mesFather':'message from father,我是来自父组件的数据'
    }
    },
  1. components: {HelloDemo}
    }

HelloDemo.vue组件:

  1. <template>
  2. <div>
  3. <h1>Hello页面</h1>
  4. <p>{{mesFather}}</p>
  5. </div>
  6. </template>
  7. <script>
  8. export default{
  9. props:['mesFather']
  10. }
  11. </script>

这时,在页面中看到 ‘message from father,我是来自父组件的数据’ 字样,父元素向子元素传递数据成功。

【二】子组件→父组件

子组件向父组件传递数据,需要用到自定义事件。 例如,我们在HelloDemo.vue ,写入一个input, 接收用户输入,我们想把用户输入的数据传给父组件。这时,input 需要先绑定一个keypress 事件,获取用户的输入,同时还要发射自定义事件,如valueUp, 父组件只要监听这个自定义事件,就可以知道子组件要向他传递数据了。子组件在发射自定义事件时,还可以携带参数,父组件在监听该事件时,还可以接受参数,参数就是要传递的数据。

 在 HelloDemo.vue的template中,添加一个input输入框,给它一个v-model 获取用户的输入,再添加keypress的事件,用于发射事件和传输数据。script 中添加data,定义变量来获取用户的输入,添加methods 来处理keypress事件的处理函数enter, 整个HelloDemo.vue 文件如下

(1)子组件发射事件和传输数据

  1. <template>
  2. <div style="margin: 10px;border: 1px solid red;padding: 10px;background: rgba(0,0,0,0.3)">
  3. <h1>Hello页面</h1>
  4. <p>{{message}}</p>
  5. <p>{{mesFather}}</p>
  6. 子组件输入框:<input type="text" placeholder="请输入..." v-model="inputValue" v-on:keypress.enter="enterFn"/>
  7. 输入元素伪:{{inputValue}}
  8. </div>
  9. </template>
  10. <script>
  11. export default{
  12. props:['mesFather'],
  13. data(){
  14. return {
  15. message:'我是Hello本页面展示信息',
  16. inputValue:''// 添加inputValue,用户输入绑定到inputValue变量,从而获取用户输入
  17. }
  18. },
  19. methods:{
  20. enterFn(val){
  21. this.$emit('valueUp',this.inputValue);
  22. //子组件发射自定义事件valueUp, 并携带要传递给父组件的值
  23. //如果要传递给父组件很多值,这些值要作为参数依次列出 如 this.$emit('valueUp', this.inputValue, this.mesFather);
  24. }
  25. }
  26. }
  27. </script>

结果:

(2)父组件监听发射事件和展示接收数据

在App.vue 中, template中hello-demo组件绑定一个自定义事件,@valueUp =“receive”, 用于监听子组件发射的事件,再写一个 p 元素,用于展示子组件传递过来的数据,<p>子组件传递过来的数据 {{ childMes }}</p>

相应地,在scrpit中,data 中,定义一个变量childMes, 并在 methods 中,定义一个事件处理函数reciever。整个App.vue修改如下:

  1. <!--添加自定义事件valueUp-->
    <hello-demo :mes-father="mesFather" v-on:valueUp="recieve"></hello-demo>
  2. <!-- p元素,用于展示子组件传递过来的数据 -->
    <p>子组件传递过来的数据 {{childMes}}</p>
  3.  
  4. import HelloDemo from './components/HelloDemo'
  5. export default{
  6. name: 'App',
  7. data(){
  8. return {
  9. 'mesFather':'message from father,我是来自父组件的数据',
  10. childMes:''
  11. }
  12. },
  13. components: {HelloDemo},
  14. methods:{
  15. recieve(mes){
  16. // recieve 事件需要设置参数,这些参数就是子组件传递过来的数据,因此,参数的个数,也要和子元素传递过来的一致。
  17. this.childMes = mes;
  18. }
  19. }
  20. }

这时在input中输入内容,然后按enter键,就以看到子组件传递过来的数据,子组件向父组件传递数据成功。

结果:

(3)分析:

①子组件input发射事件

  1. <input type="text" placeholder="请输入..." v-model="inputValue" v-on:keypress.enter="enterFn"/>

当在input输入框中输入数据,并按enter键时,它会触发keypress.enter事件,从而调用事件处理函数enterFn

在enterFn 中, 我们发射了一个事件valueUp, 并携带了一个参数

  1. methods:{
  2. enterFn(val){
  3. this.$emit('valueUp',this.inputValue);
  4. //子组件发射自定义事件valueUp, 并携带要传递给父组件的值
  5. //如果要传递给父组件很多值,这些值要作为参数依次列出 如 this.$emit('valueUp', this.inputValue, this.mesFather);
  6. }
  7. }

②父组件监听事件、接收展示数据

  1. <hello-demo :mes-father="mesFather" v-on:valueUp="recieve"></hello-demo>

由于在父组件中, 我们绑定valueUp 事件,所以父组件在时刻监听valueUp 事件, 当子组件发射value 事件时,父组件立刻捕获到,并立即调用它的回调函数receive, 在receive 中,我们获取到子组件传递过来的数据,并赋值了父组件data 中的变量childMes, 由于data 数据发生变化,从而触发dom更新,页面中就显示子组件传递过来的内容。

  1. <!-- p元素,用于展示子组件传递过来的数据 -->
  2. <p>子组件传递过来的数据 {{childMes}}</p>
  3.  
  4. data(){
  5. return {
  6. childMes:''
  7. }
  8. }

(4)props验证

在子组件中, props 最好的写法是props 验证,我们在子组件HelloDemo.vue中写 props:['mesFather'], 只是表达出,它接受一个参数mesFather, 如果写成props 验证,不仅能表达出它需要什么参数,还能表达参数类型,并且如有错误,vue 会做出警告。现在把props 改成props 验证的写法, HelloDemo.vue 中的js中的props修改如下:

  1. props:{
  2. 'mesFather':{
  3. type: String,
  4. default: 'from father来自父级的数据',
  5. required:true
  6. }
  7. }

如果是组件与组件之间的通信非常复杂,不光是父子组件,还有兄弟组件,那就需要用到状态管理vuex,稍后讲解。

.

单文件组件.vue---父子组件通信的更多相关文章

  1. 【转】vue父子组件之间的通信

    vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使 ...

  2. vue 父子组件通信详解

    这是一篇详细讲解vue父子组件之间通信的文章,初始学习vue的时候,总是搞不清楚几个情况 通过props在父子组件传值时,v-bind:data="data",props接收的到底 ...

  3. 总结Vue第二天:自定义子组件、父子组件通信、插槽

    总结Vue第二天:自定义子组件.父子组件通信.插槽 一.组件: 组件目录 1.注册组件(全局组件.局部组件和小demo) 2.组件数据存放 3.父子组件通信(父级向子级传递数据.子级向父级传递数据) ...

  4. Vue父子组件通信(父级向子级传递数据、子级向父级传递数据、Vue父子组件存储到data数据的访问)

    Vue父子组件通信(父级向子级传递数据.子级向父级传递数据.Vue父子组件存储到data数据的访问) 一.父级向子级传递数据[Prop]: ● Prop:子组件在自身标签上,使用自定义的属性来接收外界 ...

  5. 简述在Vue脚手架中,组件以及父子组件(非父子组件)之间的传值

    1.组件的定义 组成: template:包裹HTML模板片段(反映了数据与最终呈现给用户视图之间的映射关系) 只支持单个template标签: 支持lang配置多种模板语法: script:配置Vu ...

  6. Vue父子组件数据双向绑定,子组件可修改props

    第一种,子组件通过监听父组件数据,子组件改变数据之后通知给父组件 原文链接:https://blog.csdn.net/m0_37728716/article/details/81776929 父组件 ...

  7. vue组件定义方式,vue父子组件间的传值

    vue组件定义方式,vue父子组件间的传值 <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...

  8. vue父子组件

    vue父子组件 新建 模板 小书匠  为什么要厘清哪个是父组件,哪个是子组件? 一开始浏览器接收和要显示的数据非常少,此时无需划分区域进行布局.随着页面数据量的增加,如果单纯一个窗口来加载和显示数据, ...

  9. vue父子组件状态同步的最佳方式续章(v-model篇)

    大家好!我是木瓜太香!一名前端工程师,之前写过一篇<vue父子组件状态同步的最佳方式>,这篇文章描述了大多数情况下的父子组件同步的最佳方式,也是被开源中国官方推荐了,在这里表示感谢! 这次 ...

  10. vue父子组件之间传值

    vue父子组件进行传值 vue中的父子组件,什么是父组件什么是子组件呢?就跟html标签一样,谁包裹着谁谁就是父组件,被包裹的元素就是子组件. 父组件向子组件传值 下面用的script引入的方式,那种 ...

随机推荐

  1. svn问题:在eclipse里面使用SVN,怎么实现版本回滚呢?

    共有4个答案 我要回答» JustForFly 回答于 2012-04-27 10:20 举报   想回到SVN服务器端的最新版本就使用 team->还原.. 想回到SVN服务器端的其它版本使用 ...

  2. 自定义View分类与流程

    自定义View分类与流程(进阶篇)## 转载出处: http://www.gcssloop.com/customview/CustomViewProcess/ 自定义View绘制流程函数调用链(简化版 ...

  3. [Usaco2015 OPEN] Palindromic Paths

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4098 [算法] 显然 , 回文路径中第i个字母的位置(x , y)必然满足 : x ...

  4. 基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现

    设计概述 服务端通信组件的设计是一项非常严谨的工作,其中性能.伸缩性和稳定性是必须考虑的硬性质量指标,若要把组件设计为通用组件提供给多种已知或未知的上层应用使用,则设计的难度更会大大增加,通用性.可用 ...

  5. 从0开始学习Hadoop(2) 环境准备-Win7主机与Ubuntu虚拟机共享文件夹设置

    主机要跟虚拟机共享文件夹设置有很多种办法,这里提供一种本地用户的方式 1. 新增一个本地用户,密码等其他设置如下 2.选择文件目录,这是共享属性 Ubuntu端设置: 文件夹->连接到网络-&g ...

  6. 解决weblogic页面和控制台乱码问题

    转自:https://blog.csdn.net/u010995831/article/details/53283746 之前一直有碰到weblogic各种乱码问题,要不就是页面乱码,要不就是控制台乱 ...

  7. 视图模板中 使用boottstrap 将各表单字段排成一行

    如果需要创建一个表单,它的所有元素是内联的,向左对齐的,标签是并排的,请向 <form> 标签添加 class .form-inline. <form class="for ...

  8. 将json文件转换成insert语句的sql文件

    引入是要的maven依赖: <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <depend ...

  9. MFC project for a non-Unicode character set is deprecated

    error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must chang ...

  10. wamp的手动安装

    Wamp的手动安装 (http://www.cnblogs.com/homezzm/archive/2012/08/01/2618062.html) 一.Apache2.4安装 1.修改\Apache ...