Vue组件化常用方法之组件传值与通信

相关知识点

  • 父组件传值到子组件
  • 子组件传值到父组件
  • 兄弟组件之间传值
  • 祖代和后代之间传值
  • 任意两个组件之间传值

父组件传值到子组件

父组件传值到子组件基本方法有三个,分别为:

  • 属性 props
  • 引用 $refs
  • 子元素 $children

日常开发中,我们用到 props 和 $refs 频率比较多,$children 相对较少些(我就没怎么使用过~)。

属性 props

在父组件中添加属性,在子组件中接收使用,例如:

父组件:

<HelloWorld msg="Welcome to Your Vue.js App" />

子组件:

<h1>{{ msg }}</h1>

props: {
 msg: String
}

引用 $refs

在父组件中可以使用 this.$refs.xxx 获取子组件中定义的数据或者方法,并使用。

父组件:

<HelloWorld ref="hw" />

mounted() {
 this.$refs.hw.foo = "bar";
}

子组件:

<p>{{ foo }}</p>

data() {
 return {
 foo: "foo"
 };
}

注意事项:

this.$refs.xxx 不能在 created 生命周期中使用,因为真实的 DOM 还没有挂载完毕,如果非要想,可以使用 vm.$nextTick 来访问 DOM。或者也可以这样理解,父组件先于子组件创建,在父组件的 created 生命周期中子组件还没有创建,所以获取不到子组件。

在 Vue 中组件生命周期调用顺序如下:

组建的调用顺序都是 先父后子,渲染完成的顺序是 先子后父

组件的销毁操作是 先父后子,销毁完成的顺序是 先子后父

加载渲染过程

  • 父 beforeCreate
  • 父 created
  • 父 beforeMount
  • 子 beforeCreate
  • 子 created
  • 子 beforeMount
  • 子 mounted
  • 父 mounted

子组件更新过程

  • 父 beforeUpdate
  • 子 beforeUpdate
  • 子 updated
  • 父 updated

父组件更新过程

  • 父 beforeUpdate
  • 父 updated

销毁过程

  • 父 beforeDestroy
  • 子 beforeDestroy
  • 子 destroyed
  • 父 destroyed
created() {
 console.log("第一个执行");
 console.log(this.$refs.hw); // undefined
 this.$nextTick(() => {
 console.log("第三个执行");
 console.log(this.$refs.hw); // 此时可以获取到
 });
}

mounted() {
 console.log("第二个执行");
 this.$refs.hw.foo = "bar";
}

子元素 $children

父组件:

this.$children[0].xx = "xxx";

注意事项:

$children 获取当前实例的直接子组件。如果父组件中存在多个子组件,需要注意 $children 并不保证顺序,也不是响应式的。

子组件传值到父组件

子组件传值到父组件使用的方法是自定义事件。在子组件中派发,在父组件中监听。

注意事项: 事件的派发者是谁,事件的监听者就是谁,只不过声明的时候声明在父组件中了。

分为三种情况:不传递参数、传递一个参数、传递多个参数。

不传递参数

子组件:

this.$emit('childFoo');

父组件:

<HelloWorld2 @childFoo="onChildFoo"></HelloWorld2>

methods: {
 onChildFoo() {
 console.log("====== onChildFoo ========");
 }
}

传递一个参数

在父组件中使用 $event 接收参数。

子组件:

this.$emit('childFooSingle', 'foo');

父组件:

<HelloWorld2 @childFooSingle="onChildFooSingle($event)"></HelloWorld2>

methods: {
 onChildFooSingle(e) {
 console.log(e); // foo
 }
}

传递多个参数

在父组件中使用 arguments 接收参数,会以数组的形式传递。

子组件:

this.$emit('childFooMultiple', 'foo', 'bar', 'dong');

父组件:

<HelloWorld2 @childFooSingle="onChildFooMultiple(arguments)"></HelloWorld2>

methods: {
 onChildFooMultiple(msg) {
 console.log(msg[0]); // foo
 console.log(msg[1]); // bar
 console.log(msg[2]); // dong
 }
}

兄弟组件之间传值

兄弟组件之间传值可以通过共同的父辈组件搭桥进行传递,例如:$parent、$root。

兄弟组件1:

this.$parent.$on('foo', handle);

兄弟组件2:

this.$parent.$emit('foo');

祖代和后代之间传值

由于组件嵌套层数过多,使用 props 进行传递不切实际,vue 提供了 provide/inject API 完成该任务。

provide/inject 能够实现祖先给后代传值。

祖代:

provide() {
 return {foo: 'foo'}
}

后代:

inject: ['foo']

注意:provide 和 inject 主要为高阶组件/组件库提供用例,并不推荐直接用于应用程序代码中,我们更多会在开源组件库中见到。但是,反过来想要后代给祖代传值,这种方案就不行了!!!

官方提示:provide 和 inject 绑定并不是响应式的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应式的。

祖代:

provide() {
 return {
 dong: this.home
 };
},
data() {
 return {
 home: ["App home"]
 };
}

后代:

inject: ["dong"]

this.dong = ["App data"]; // 会报错,Avoid mutating an injected value directly since the changes will be overwritten whenever the provided component re-renders
this.dong.push("App data"); // 可以修改成功

任意两个组件之间传值

任意两个组件之间传值有两种方案:事件总线、Vuex。

事件总线

创建一个 Bus 类负责事件派发、监听和回调管理。

首先创建一个 bus.js,并在 main.js 中引入,然后在组件中使用:

第一步:新建 plugins/bus.js

class Bus{
 constructor(){
 this.callbacks = {}
 }
 $on(name, fn){
 this.callbacks[name] = this.callbacks[name] || []
 this.callbacks[name].push(fn)
 }
 $emit(name, args){
 if(this.callbacks[name]){
  this.callbacks[name].forEach(cb => cb(args))
 }
 }
}

export default Bus;

第二步:main.js 中引入

import Bus from "./plugins/bus";
Vue.prototype.$bus = new Bus()

第三步:在组件中使用

组件1:

this.$bus.$on('foo', handle)

组件2:

this.$bus.$emit('foo')

Vuex

创建唯一的全局数据管理者 store,通过它管理数据并通知组件状态变更。可以自行先了解一下官方文档Vuex,具体详细使用后续会写一个专题~

总结

到此这篇关于Vue组件化常用方法之组件传值与通信的文章就介绍到这了,更多相关Vue组件传值与通信内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解vue组件之间相互传值的方式

    概述 我们都知道 Vue 作为一个轻量级的前端框架,其核心就是组件化开发.Vue 就是由一个一个的组件构成的,组件化是它的精髓,也是最强大的功能之一.而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用. 但在实际项目开发过程中,我们需要访问其他组件的数据,这样就就有了组件通信的问题.在 vue 中组件之间的关系有:父子,兄弟,隔代.针对不同的关系,怎么实现数据传递,就是接下来要讲的. 一.父组件向子组件传值 即父组件通过属性的方式向子组件传值,子组件通过 props 来接收

  • 浅谈vue中子组件传值的默认值情况

    当父组件中的content值没有传入时,子组件利用default属性设置默认值,此情况时,页面会显示default value. 当传入content的值时,default属性的默认值不生效,界面显示为: 补充知识:Vue父组件向子组件传值遇到的BUG 当子组件中含有props属性,使用ref对其中的prop属性赋值时报错 Avoid mutating a prop directly since the value will be overwritten whenever the parent

  • Vue组件传值过程中丢失数据的分析与解决方案

    前言 在上一篇文章 JavaScript 中的两种数据类型中,分别介绍了基本类型和引用类型,以及引用类型的浅拷贝与深拷贝.这里需要注意的是,该文章中深拷贝引用类型值的方法,并不是完美的,引用类型值中的某些属性值,仍不能完整地复制到新的变量中.比如函数值,在深拷贝过程中,就会丢失. 问题 在实际项目中,假如使用了二次封装的组件,并且封装的组件内部做了一些属性值的深拷贝操作,就有极有可能因为传入的属性值是引用类型的值,导致丢失部分数据. 举例 以基于 el-table 封装的 ak-table 组件

  • vue组件中传值EventBus的使用及注意事项说明

    主要想说下非父子组件之间的通信. 项目场景: 在app.vue里写了一个公共的顶部导航navbar,然后右侧有个分享按钮,而这个分享按钮只有在特定的页面才展示,项目里是在lottery.vue页面,然后想实现app.vue里点击分享按钮,触发lottery.vue里的分享方法. 解决:使用eventBus 1.创建一个event-bus.js import Vue from 'vue' export const EventBus = new Vue() 2.在app.vue引入eventbus,

  • Vue 组件的挂载与父子组件的传值实例

    1:将需要挂载的组件放置在component之中 2:全局挂载在main.js之中 import Vue from 'vue' import App from './App.vue' import getTime from './component/child/getTime' //全局注册 整个项目的组件都可以使用 //注册给整个vue 对象 //引入需要注册的全局组件 //在vue类的方法 component里面进行注册 Vue.component('v-times',getTime); V

  • VUE子组件向父组件传值详解(含传多值及添加额外参数场景)

    一.子组件向父组件传递一个值 子组件: this.$emit('change', this.value); 父组件: <!-- 在父组件中使用子组件 --> <editable-cell :text="text" :inputType="inputType" @change="costPlannedAmountChange($event)" /> // 事件处理函数 async costPlannedAmountChang

  • Vue父子组件传值的一些坑

    在用 Vue 的父子组件传值时遇到一个冷门的问题,子组件改变值后父组件的值也随之改变了,特此记录下原因和解决方式. 再系统梳理下 JavaScript 的深拷贝与浅拷贝相关知识点. 1. 问题描述 父组件传值给子组件,子组件改变传过来的值后,父组件的值也会跟着改变. 这个问题比较冷门,平时如果对组件通信使用得比较简单,一般不会遇到. 2. 原因剖析 核心:双向绑定 父子组件传值的时候涉及双向绑定,当传值为 object 类型时,传值之后数据源会被改变. 深拷贝与浅拷贝 下文详细讲. 3. 解决方

  • vue 子组件和父组件传值的示例

    一.子组件向父组件传值 1:子组件中(例:) 2:父组件中(例:) 二.父组件向子组件传值 1:父组件中(例:) 2:子组件中(例:) 以上就是vue 子组件和父组件传值的示例的详细内容,更多关于vue 子组件和父组件传值的资料请关注我们其它相关文章!

  • vue父子组件的互相传值和调用

    1.父传值给子组件 父组件: <template> <div> <p class="father">父组件</p> <child :sid="id"></child> </div> </template> <script> import child from './child' export default { components: { child }, d

  • Vue组件化常用方法之组件传值与通信

    相关知识点 父组件传值到子组件 子组件传值到父组件 兄弟组件之间传值 祖代和后代之间传值 任意两个组件之间传值 父组件传值到子组件 父组件传值到子组件基本方法有三个,分别为: 属性 props 引用 $refs 子元素 $children 日常开发中,我们用到 props 和 $refs 频率比较多,$children 相对较少些(我就没怎么使用过~). 属性 props 在父组件中添加属性,在子组件中接收使用,例如: 父组件: <HelloWorld msg="Welcome to Yo

  • 前端组件化基础知识详细讲解

    目录 组件的基本概念 对象与组件的区别 组件 Component 特性 Attribute Attribute 对比 Property Attribute: Property: Class 属性 Style 属性 Href 属性 Input 和 value 如何设计组件状态 组件生命周期 Lifecycle Children 结束语 这里我们一起来学习前端组件化的知识,而组件化在前端架构里面是最重要的一个部分. 讲到前端架构,其实前端架构中最热门的就有两个话题,一个就是组件化,另一个就是架构模式

  • iOS组件化开发实战记录

    1. 组件化需求来源 起初的这个项目,App只有一条产品线,代码逻辑相对比较清晰,后期随着公司业务的迅速发展,现在App里面承载了大概五六条产品线,每个产品线的流程有部分是一样的,也有部分是不一样的,这就需要做各种各样的判断及定制化需求.大概做了一年多后,出现了不同产品线提过来的需求,开发人员都需要在主工程中开发,但是开发人员开发的是不同的产品线,也得将整个工程跑起来,代码管理.并行开发效率.分支管理.上线时间明显有所限制.大概就在去年底,我们的领导提出了这个问题,希望作成组件化,将代码重构拆分

  • Android开发组件化架构设计原理到实战

    目录 为什么需要组件化 组件化和模块化 模块化架构 组件化架构 组件化带来的优势 组件化需解决的问题 资源冲突解决 AndroidManifest 独立调试 单工程方案 多工程方案 页面跳转 Arouter 实现组件间方法调用 组件化的消息通信方式选择 广播 事件总线 Application生命周期分发 为什么需要组件化 小项目是不需要组件化的.当一个项目有数十个人开发,编译项目要花费10分钟,修改一个bug就可能会影响到其他业务,小小的改动就需要进行回归测试,如果是这种项目,那么我们需要进行组

  • Android组件化原理详细介绍

    目录 什么是组件化? 为什么使用组件化? 一步步搭建组件化 1.新建模块 2.统一Gradle版本号 3.创建基础库 4.组件模式和集成模式转换 5.AndroidManifest的切换 6.*业务Application切换 组件之间的跳转 1.添加依赖 2.初始化ARouter 3.添加跳转 组件之间的数据传递 1.定义接口 2.实现接口 组件Application的动态切换 1.定义抽象类 BaseApplication 继承 Application 2.所有的组件的 Application

  • 基于Vue组件化的日期联动选择器功能的实现代码

    我们的社区前端工程用的是element组件库,后台管理系统用的是iview,组件库都很棒,但是日期.时间选择器没有那种" 年份 - 月份 -天数 " 联动选择的组件.虽然两个组件库给出的相关组件也很棒,但是有时候确实不是太好用,不太明白为什么很多组件库都抛弃了日期联动选择.因此考虑自己动手做一个. 将时间戳转换成日期格式 // timestamp 为时间戳 new Date(timestamp) //获取到时间标砖对象,如:Sun Sep 02 2018 00:00:00 GMT+08

  • Vue关于组件化开发知识点详解

    全局组件注册 Vue.component('first-component', { data: function () { return { count: 0 } }, template: '<button @click="count++">{{ count }}</button>' }) data 必须是一个函数 组件模板内容必须是单个根元素 组件模板内容可以是模板字符串 全局组件可以嵌套全局组件 组件命名方式 Vue.component('first-com

  • 详解vue.js组件化开发实践

    前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然成为了第一个问题.鉴于目前web前端mvvm框架以及组件化开发方式的流行,决定技术栈采用:vue + es6 + 组件化. 这里首先简单说下web前端组件化开发方式的历程: 最早的组件化结构,代码结构可能如下: - lib/components/calendar |- calendar.css |-

  • 浅谈Vue父子组件和非父子组件传值问题

    本文介绍了浅谈Vue父子组件和非父子组件传值问题,分享给大家,具体如下: 1.如何创建组件 1.新建一个组件,如:在goods文件夹下新建goodsList.vue <template> <div class='tmpl'> goodsList组件 </div> </template> <style> </style> <script> export default { data() { return{} }, creat

  • Vue组件化通讯的实例代码

    1. Vue的组成文件(.vue) 分为三部分,分别对应html,js,css <template></template> <script></script> <style></style> 2. Vue的生命周期函数 beforeCreate() 创建数据之前 created() 创建数据 我们在这里的得到我们在data里面创建的数据 beforeMount() // Dom渲染完成前 mounted() //Dom渲染完成 bef

随机推荐