vue 父子间通信 总结

2023-11-11

优化了之前的内容,添加了新的组件通信方式,共7种方式,感兴趣的小伙伴可以慢慢积累,总有用得到的时候。

组件之间通信

组件是 vue.js 强大的功能,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。
根据组件传递数据的方向不同,分为父组件向子组件传值,子组件向父组件传值。
这两种传值方向,是通过props、$ref, $emit,provide和inject,vuex,eventBus,以及 $attrs/ $listeners 来实现的。

父组件向子组件传值(父传子)

props

  • 子组件的props选项能够接收来自父组件数据。
  • props是单向绑定的,即只能父组件向子组件传递,不能反向。
  • 传递的方式也分为两种:一种为静态数据,一种为动态传递

父组件

<template>
<div class="father">
    <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
    <el-form-item label="密码" prop="pass">
        <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
    </el-form-item>
    <el-form-item label="确认密码" prop="checkPass">
        <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
    </el-form-item>
    </el-form>
    <!-- 调用子组件 -->
    <!-- 当父组件数据填写完成之后,点击提交,调用子组件 -->
    <div v-if="show">

      <!-- 1.静态传递 -->
        <Child password='更改成功'></Child>  <!-- 通过自定义属性传递数据 -->

      <!-- 2.动态传递 -->
        <Child :password='this.ruleForm.checkPass'></Child>
        <Child v-bind:password='this.ruleForm.checkPass'></Child>
    </div>
</div>
</template>
<script>
// 引入子组件
import Child from './Child';
 export default {
    data() {
      // 对表单提交,进行简单的校验,可忽略
      var validatePass = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请输入密码'));
        } else {
          if (this.ruleForm.checkPass !== '') {
            this.$refs.ruleForm.validateField('checkPass');
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === '') {
          callback(new Error('请再次输入密码'));
        } else if (value !== this.ruleForm.pass) {
          callback(new Error('两次输入密码不一致!'));
        } else {
          callback();
        }
      };
      // 对表单提交,进行简单的校验,可忽略

      return {
        // 表单中绑定的数据
        ruleForm: {
          pass: '',
          checkPass: '',
          age: ''
        },

      // 对表单提交,进行简单的校验,可忽略
        rules: {
          pass: [
            { validator: validatePass, trigger: 'blur' }
          ],
          checkPass: [
            { validator: validatePass2, trigger: 'blur' }
          ]
        },
      // 对表单提交,进行简单的校验,可忽略

        show: false,
      };
    },
   // 引入子组件
    components: {
        Child
    },
    methods: {

      // 点击提交,调用方法
      submitForm(formName) {
        
      // 对表单提交,进行简单的校验,可忽略
        this.$refs[formName].validate((valid) => {
      // 对表单提交,进行简单的校验,可忽略

          if (valid) {
            // 当校验成功时,显示子组件
            // console.log('submit!');
            this.show = true;
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      }
    }
  }
</script>

子组件

<template>
<div class="child">
    <el-alert
        title="新密码:"
        type="success">
        <span>{{password}}</span>
        <!-- 可直接使用从父组件接收的数据 -->
    </el-alert>
</div>
</template>
<script>
import Child from './Child';
 export default {
    data() {
      return {
        show: false,
        password: ''
      };
    },
    props: {
        password: String
        // 声明一个自定义的属性
    },
  }
</script>

子组件通过props选项来声明一个自定义的属性,然后父组件就可以在嵌套标签的时候,通过这个属性往子组件传递数据了。

实现的效果图

父组件输入密码

在这里插入图片描述

子组件接收数据

在这里插入图片描述

子组件向父组件传值(子传父)

$emit( eventName, […args] )

  • $emit绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数。
  • 也就是子组件绑定父组件中的方法,通过回调,将数据传递给父组件。

子组件

在这里插入图片描述

    methods: {
        handleClick () {
            // 向父组件传值
            this.$emit('getChild', this.message);
        }
    }

父组件

在这里插入图片描述

      // 调用方法,接收传值
      getSuccess (value) {
        console.log(value);
            this.$message({
                message: value,
                type: 'success'
            });
      },

可以定义一个事件来触发响应的$emit,使父组件可以知道有事件改变,进而接收对应的参数。

兄弟组件之间的传值

兄弟组件之间的传值和父子组件之间的传值非常相似,都是通过$emit;
原理是:vue一个新的实例,类似于一个站,连接着两个组件,也就是一个中央事件总线。

子组件

import Child from './Child';
import Brother from './Borther';
methods: {
    handleClick () {
        // 向父组件传值
        this.$emit('getChild', this.message);

        // 兄弟组件传值
        Brother.$emit('getChild', this.message);
        
    }
}

兄弟组件接收方式与父组件接收方式一样。

父组件调用子组件方法并传值

父组件

在这里插入图片描述

            // 调用子组件的方法
            this.$refs.child.getMessage(this.detail);
  • child为子组件在父组件的名称,保持一致。
  • getMessage(this.detail) 中,getMessage为子组件中的方法,this.detail为父组件传给子组件方法的数据。
  • 实现父组件给子组件传参,并调用方法。

上面三种方式是我们常用的vue通信方式,为什么又添加了现在这些方法呢?因为上面三种是基础,后面的方式是进阶。可以慢慢积累起来。

provide和inject

provide和inject组件传值,适用于有跨度的组件传值,比如祖父组件—>孙子组件,跨级访问的情况给下使用。

单向传值,由provide传递给inject

  • provide:是一个对象,或者是一个返回对象的函数。里面呢就包含要给子孙后代的东西,也就是属性和属性值。

  • inject:一个字符串数组,或者是一个对象。属性值可以是一个对象,包含from和default默认值。

// 父组件
  provide() {
    return {
      message: "this is demo",
    };
  },
// 孙组件、子组件
inject: ["message"],

关于provide和inject的传参,在实际应用场景中很方便,但是在使用的过程中,因为项目中可能有很多组件需要传参,如果用provide可能会导致我们inject拿到参数的时候,不知道是哪个组件传递的。(仅代表个人研发过程中的观点)

事件车——非父子之间传值

  1. 创建eventBus.js文件
import Vue from "vue";
export default new Vue()

2.注册事件车

在main.js中将事件绑定在vue上

import Vue from "vue";
Vue.prototype.$eventBus = new Vue();

到这一步已经创建好了eventBus事件车了,接下来可以使用了

$emit触发一个事件,自定义一个事件,第二个参数是我们将要传递的数据

this.$eventBus.$emit("myFun", data);

$on接收传递的参数

this.$eventBus.$on("myFun", (data) => {
   console.log(data)
   // 这个地方可以写接收data后想要执行的方法和操作
 });

vuex

vuex是状态管理,数据存储,项目需要的话可以使用vuex

$attrs和 $listeners

$attrs: 包含了父作用域中不被prop所识别的特性绑定,当组件没有声明任何prop时,这里会包含所有的父作用域的绑定,通过v-bind=‘ $attrs’ 传入内部组件,配个interitAttrs选项一起使用

$listeners

$listeners:包含了父作用域中的v-on事件监听器,可以通过v-on=’ $listeners’ 传入内部组件
需要关闭自动性挂在在组件根元素的没有prop声明的属性
interitAttrs: false

总结

  1. 父子组件通信需要一定的媒介,也就是中间站。
  2. 调用方法进行传值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue 父子间通信 总结 的相关文章

随机推荐

  • 在服务器Linux系统中搭建JavaWeb环境

    目录 软件安装 安装JDK 安装Tomcat 本文使用的服务器是阿里云的云服务器ECS 软件安装 安装JDK 通过SSH软件把jdk安装包 任意版本皆可 传至指定位置 这里选择 home soft 将压缩包解压至 usr java 需提前创
  • qt使用自定义属性方法让子控件动态改变qss样式

    用动态改变QLabel样式为例 分为QLabel选择状态和未选择状态 1 自定义类继承自QLabel 用Q PROPERTY宏注册一个名称为select属性 2 QSS文件中预先设置QLabel属性 QLabel label2 select
  • 腾讯云coding平台平台inda目录遍历漏洞复现

    前言 其实就是一个python的库可以遍历到 并不能遍历到别的路径下 后续可利用性不大 并且目前这个平台私有部署量不多 大多都是用腾讯云在线部署的 CODING DevOps 是面向软件研发团队的一站式研发协作管理平台 提供从需求到设计 开
  • springmvc控制器的三种实现方式

    方式一 实现Controller接口 public class Test01 implements Controller Override public ModelAndView handleRequest HttpServletReque
  • vue实现element-ui自定义主题色切换(简单版)

    需求 通过点击图标实现了白天和黑夜的页面效果的实现 可以自定义颜色 手写 比较简单 如果需要复杂功能 根据颜色选择器实现element ui全部的主题色切换可以看我另一篇 还在写 效果 1 定义个图标用于切换主题 div div
  • Element el-table-column宽度设置百分比无效

    问题 使用Element table组件时 给列设置百分比宽度无效 width 30 解决 用属性min width 3 代替属性width 30 且每一列都必须设置 原因 el table 组件会被 vue 解析成 html width
  • android wifimanager实时scan,天博体育和BOB为什么不封 -官网

    内容管理 bin bash 挂载yum仓库 read p 请输入你yum仓库的挂载点 direcho 正在挂载光盘 mount grep q dev sr0 umount dev sr0 d dir mkdir dirmount dev s
  • 怎么把桌面添加到计算机的收藏夹,电脑浏览器怎么把书签添加到桌面

    把个人喜欢的网页保存到桌面 下次直接进入网页就十分便捷了 以下就是网页保存到桌面的几种方法 方法一 1 打开360浏览器 选择文件选项 2 保存网页桌面快捷方式 3 等待生成桌面快捷方式 4 生成了桌面快捷方式 直接打开就可以进入经常使用的
  • IDEA在使用maven命令时,控制台出现中文乱码的解决方式

    今天在进行maven打包的时候 由于项目路径有中文名称 然后控制台出现了中文乱码 如图所示 这种情况下 本狗试过很多种方法 比如在setting gt encoding中设置字符集为UTF 8等等方法 但是都没有用 后来经过大量百度 找到了
  • Secret File ctf web php伪协议

    Secret File php伪协议 打开网页并没有太多提示 查看一下网页源码 可以看到一个新的页面 Archive room php 尝试访问一下 这是就跳出了这样一个页面 点击SECRET 出现如下页面 比较之前的网页源码并没有什么变化
  • 成功解决:RuntimeError: DataLoader worker (pid(s) XXX) exited unexpectedly

    跑着跑着出现Bug RuntimeError DataLoader worker pid s x x x x exited unexpectedly 加上 if name main
  • 【数模】基于PageRank算法的学术论文重要性排序问题(matlab实现)

    基于PageRank算法的学术论文排序问题 matlab实现 问题描述 六篇学术论文的引用关系如图 A 指向 B 表示 A 引用 B 试排出它们重要性的顺序 问题分析 就是给节点来个重要性排序 PageRank简介 PageRank 又称网
  • oracle表空间迁移transport_tablespace的使用

    问题描述 如果某个表空间有多个用户 那么我们在迁移的时候如果按用户导出导入的话 那将是一个麻烦费事的活 这个时候我们可以通过transport tablespace参数进行表空间迁移 达到一次性迁移整个表空间的目的 下面通过一个实验来讲解整
  • layui table 跨页、翻页记忆选择

    示例 table class layui table table layui 需要初始化的 form layui form layfilter layui layfilter table render
  • linux du命令

    百度百科查到 du show disk usage 查看磁盘使用情况 个人用的比较多的命令是 du h max depth 1 查看这个目录下的文件目录大小 du ah max depth 1查看这个目录下的文件目录包括文件的大小 具体的命
  • 项目经验分享:基于昇思MindSpore实现手写汉字识别

    项目信息Program Info 项目要求 基于MindSpore的实现在线手写汉字识别 主要包括手写汉字检测和手写汉字识别 能较准确的对标准字体的手写文字进行识别 识别后通过人工干预对文本进行适当修正 需要有一定的创新特性 代码达到合入社
  • Android开发学习【Button控件】

    Android开发学习 Day02 Button 与TextView相比 Button增加了两个新属性 书写一个点击显示当前时间的按钮 获取当前时间的java类 xml主界面 MainActivity类 点击事件和长按事件 使用setOnC
  • C++中的头文件.h 和 源文件.cpp 的关系

    在VS中 C 项目 我创建了一个类 会自动创建头文件和源文件 这两个文件有什么关系 如何快速切换 在头文件 h文件中声明的类方法 如何快速在源文件中进行具体实现 在 Visual Studio 中创建 C 项目时 当你添加一个新的类 它会自
  • 游戏外挂内存数据读取

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 源地址 http hi baidu com probill blog item 1d07d11efbd641f01ad576f3 html网络游戏 每一个数据比如你的血值
  • vue 父子间通信 总结

    vue 父子间通信 总结 组件之间通信 父组件向子组件传值 父传子 props 父组件 子组件 实现的效果图 父组件输入密码 子组件接收数据 子组件向父组件传值 子传父 emit eventName args 子组件 父组件 兄弟组件之间的