Vue EventBus自定义组件事件传递


Posted in Javascript onJune 25, 2018

前言

组件化应用构建是Vue的特点之一,因此我们在Vue的实际开发过程中会经常需要封装自定义组件,以提高开发的效率。 而组件在大部分情况下并不会孤立的存在,它必然会与父组件和兄弟组件产生数据的交互。所以在这里为大家总结两种组件数据交互的方式:EventBus和利用Vuex框架进行状态管理。

我会通过两种不同的交互方式,它们对于父子组件间数据交互和兄弟组件间数据交互。

由于篇幅关系,本文主要介绍EventBus进行数据消息传递;关于运用Vuex框架进行状态管理在下一篇文章中介绍。

案例介绍

本章节会有大量的代码示例,为了让读者阅读轻松,做如下目录和组件介绍。本章节主要运用了两个子组件和一个父组件。

子组件文件名:SearchInput.vueSearchItem.vue

父组件文件名:StateView.vue

目录结构展示:

Vue EventBus自定义组件事件传递

1、SearchInput.vue

组件介绍:一个输入框,它会onInput方法去监听输入内容,并调用方法,将输入框内的数据传递出去。

代码展示:

<template>
 <div>
 <input placeholder="搜索内容" v-model="searchContent"/>
 </div>
</template>

<script type="text/ecmascript-6">
 export default{
 data(){
  return{
  searchContent:""
  }
 },
 props:{

 }
 }
</script>

<style lang="stylus" rel="stylesheet/stylus">

</style>

SearchItem.vue

组件介绍:一个span,它主要用来接收父组件传递的内容和接收同胞组件输入框传递的内容,并进行展示。

代码示例:

<template>
 <span class="item">
  {{content}}
 </span>
</template>

<script type="text/ecmascript-6">
 export default{
 data(){
  return{
  content:this.itemContent
  }
 },
 props:{
  itemContent:{
  type:String,
  required:true
  }
 }
 }
</script>

<style lang="stylus" rel="stylesheet/stylus">
 .item
 background #f4f4f4
 padding 3px 5px
 box-sizing border-box
 display inline-block
 cursor pointer
</style>

StateView.vue

组件介绍:父组件,主要展示页面和加载子组件

代码示例:

<template>
 <div>
 <search-view></search-view>
 <div>
  <search-item :itemContent="content"/>
  <search-item itemContent="热门搜索2"/>
  <search-item itemContent="热门搜索3"/>
 </div>
 <div>{{content}}</div>

 </div>
</template>

<script type="text/ecmascript-6">
import searchView from '../components/SearchInput.vue'
import searchItem from '../components/SearchItem.vue'

export default{
 data () {
 return {
  content:"接收输入框的值"
 }
 },
 components: {
 searchView,
 searchItem
 }
}

</script>

<style lang="stylus" rel="stylesheet/stylus">

</style>

正文

EventBus

1、父组件发送数据给子组件,可以通过子组件定义的 props 自定义属性,去传递数据

2、EventBus其实就是通过实例化一个Vue实例,然后通过该实例的 $emit 方法发送数据消息和 $on 方法接收数据消息。它适用在子组件发送消息给父组件或子组件发送消息给兄弟组件。

我们看下一个下面案例主要展示了:

1、通过 props 父组件(StateView)去为子组件(SearchItem)传递数据;

2、子组件(SearchInput)通过 EventBus 和父组件(StateView)、兄弟组件(SearchItem)传递数据;

目录结构展示

Vue EventBus自定义组件事件传递 

效果展示

Vue EventBus自定义组件事件传递

代码展示:(粗体表示变化部分)

 1、第一步:自定义一个EventBus(SearchEvent.js)

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

在这里我们 new 了一个Vue的实例,并将它输出。

第二步:子组件通过EventBus发送数据消息

<template>
 <div>
 <input placeholder="搜索内容" @input="sendEvent" v-model="searchContent"/> //增加了@input=“sendEvent”,去监听onInput事件,并回调sendEvent方法
 </div>
</template>

<script type="text/ecmascript-6">
 import searchEvent from '../event/SearchEvent'  //导入EventBus
 export default{
 data(){
  return{
  searchContent:""
  }
 },
 methods:{
  sendEvent:function(){  //定义sendEvent方法,在input中监听onInput,并回调该方法
   /**
   * 通过导入的searchEvent调用$emit方法去发送数据消息。
   * 第一个参数为事件名,到时候我们要通过该事件名去接收数
   * 第二个参数为数据值,如果只有一个参数,我们可以直接传递该参数
   * 如果有两个及以上的参数,我们可以通过对象的形式去传递。
   */
  searchEvent.$emit("search",this.searchContent)
  //多个参数传递的示例:
  //searchEvent.$emit("search",{"content":this.searchContent,"valTwo":"valTow"})
  }
 },
 props:{

 }
 }
</script>

<style lang="stylus" rel="stylesheet/stylus">

</style>

在上面的示例我们主要做了以下事情: 1、导入EventBus

2、通过 @input="sendEvent" 去监听 onInput 事件,并发现输入框内内容有改变时,回调 sendEvent 方法,调用 EventBus.emit() 方法把数据消息发送出去

第三步父组件(StateView)和子组件(SearchItem)接收数据消息

StateView.vue

<template>
 <div>
 <search-view></search-view>
 <div>
  <search-item :itemContent="content"/> //通过props去为子组件传递(动态数据:content)数据
  <search-item itemContent="热门搜索2"/> //通过props去为子组件传递(固定数据:热门搜索2)数据
  <search-item itemContent="热门搜索3"/>
 </div>
 <div>{{content}}</div>

 </div>
</template>

<script type="text/ecmascript-6">
import searchView from '../components/SearchInput.vue'
import searchItem from '../components/SearchItem.vue'
import searchEvent from '../event/SearchEvent' //导入EventBus
export default{
 data () {
 return {
  content:"接收输入框的值"
 }
 },
 mounted(){
 /**
  * 在mounted接受数据消息,$on接受两个参数。
  * 第一个参数是消息事件名,应该与发送数据消息的第一个参数相同,否则接收不到数据消息
  * 第二个参数是一个函数,对数据消息事件做处理;该函数带一个参数,则是数据。
  */
 searchEvent.$on('search',(val)=>{
  this.content=val;
  //示例:如果数据传递的是对象形式
  // this.content=val.content;
 })
 },
 components: {
 searchView,
 searchItem
 }
}

</script>

<style lang="stylus" rel="stylesheet/stylus">

</style>

在上面的示例我们主要做了以下事情:

1、在父组件,我们通过SearchItem的 props 去传递了数据。

2、通过在组件 mounted 生命周期中调用 EventBus.on() 方法去接收子组件(SearchInput)的数据消息,并对content进行修改值

SearchItem.vue

<template>
 <span class="item">
  {{content}}
 </span>
</template>

<script type="text/ecmascript-6">
 import searchEvent from '../event/SearchEvent' //导入EventBus
 export default{
 data(){
  return{
  content:this.itemContent
  }
 },
 props:{
  itemContent:{
  type:String,
  required:true
  }
 },
 mounted(){
 /**
  * 在mounted接受数据消息,$on接受两个参数。
  * 第一个参数是消息事件名,应该与发送数据消息的第一个参数相同,否则接收不到数据消息
  * 第二个参数是一个函数,对数据消息事件做处理;该函数带一个参数,则是数据。
  */
  searchEvent.$on('search',(val)=>{
  this.content=val;
  })
 }
 }
</script>

<style lang="stylus" rel="stylesheet/stylus">
 .item
 background #f4f4f4
 padding 3px 5px
 box-sizing border-box
 display inline-block
 cursor pointer
</style>

在上面的示例我们主要做了一事情:

通过在组件 mounted 生命周期中调用 EventBus.on() 方法去接收子组件(SearchInput)的数据消息,并对content进行修改值。

我们可以感受到 SearchInput一发送数据消息,所有注册接收 search 事件的地方都会接收到数据消息

复盘:

1、父组件给子组件进行数据传递可以通过 props 进行传递。

2、子组件给父组件进行消息传递或子组件给兄弟组件进行消息传递可以通过EventBus去实例化一个Vue,并通过该实例的 $emit$on 方法去传递和接收数据消息。

3、数据消息一旦发送,所有注册了接收该数据消息的地方都会接收到该数据消息。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript Eval 函数使用
Mar 23 Javascript
jquery ajax 同步异步的执行 return值不能取得的解决方案
Jan 08 Javascript
jquery简单插件制作(fn.extend)完整实例
May 24 Javascript
原生Javascript插件开发实践
Jan 09 Javascript
ES6新特性六:promise对象实例详解
Apr 21 Javascript
js禁止浏览器页面后退功能的实例(推荐)
Sep 01 Javascript
使用use注册Vue全局组件和全局指令的方法
Mar 08 Javascript
Vue中保存数据到磁盘文件的方法
Sep 06 Javascript
ES6 迭代器与可迭代对象的实现
Feb 11 Javascript
JavaScript中的连续赋值问题实例分析
Jul 12 Javascript
基于axios 的responseType类型的设置方法
Oct 29 Javascript
uniapp实现可滑动选项卡
Oct 21 Javascript
一个Vue页面的内存泄露分析详解
Jun 25 #Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
Jun 25 #Javascript
angularjs结合html5实现拖拽功能
Jun 25 #Javascript
vue中vee validate表单校验的几种基本使用
Jun 25 #Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
Jun 24 #Javascript
JS的函数调用栈stack size的计算方法
Jun 24 #Javascript
JavaScript中var、let、const区别浅析
Jun 24 #Javascript
You might like
header跳转和include包含问题详解
2012/09/08 PHP
php模拟js函数unescape的函数代码
2012/10/20 PHP
php中opendir函数用法实例
2014/11/15 PHP
PHP explode()函数用法讲解
2019/02/15 PHP
YII框架行为behaviors用法示例
2019/04/26 PHP
JS解密入门之凭直觉解
2008/06/25 Javascript
JavaScript实现GriwView单列全选(自写代码)
2013/05/13 Javascript
js为什么不能正确处理小数运算?
2015/12/29 Javascript
jQuery ajax请求返回list数据动态生成input标签,并把list数据赋值到input标签
2016/03/29 Javascript
Bootstrap打造一个左侧折叠菜单的系统模板(一)
2016/05/17 Javascript
jQuery通过ajax方法获取json数据不执行success的原因及解决方法
2016/10/15 Javascript
在js中实现邮箱格式的验证方法(推荐)
2016/10/24 Javascript
通过原生JS实现为元素添加事件的方法
2016/11/23 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
深入理解Commonjs规范及Node模块实现
2017/05/17 Javascript
基于vue实现分页效果
2017/11/06 Javascript
详解基于mpvue微信小程序下载远程图片到本地解决思路
2019/05/16 Javascript
微信小程序修改数组长度的问题的解决
2019/12/17 Javascript
[02:44]重置世界,颠覆未来——DOTA2 7.23版本震撼上线
2019/12/01 DOTA
Python获取邮件地址的方法
2015/07/10 Python
python中日志logging模块的性能及多进程详解
2017/07/18 Python
python线程池threadpool实现篇
2018/04/27 Python
Windows 8.1 64bit下搭建 Scrapy 0.22 环境
2018/11/18 Python
判断python对象是否可调用的三种方式及其区别详解
2019/01/31 Python
python读取txt文件并取其某一列数据的示例
2019/02/19 Python
Win10环境python3.7安装dlib模块趟过的坑
2019/08/01 Python
vscode 配置 python3开发环境的方法
2019/09/19 Python
HTML5 3D书本翻页动画的实现示例
2019/08/28 HTML / CSS
main 函数执行以前,还会执行什么代码
2013/04/17 面试题
考博专家推荐信模板
2013/12/02 职场文书
安全生产月活动总结
2014/05/04 职场文书
诚实守信道德模范事迹材料
2014/08/15 职场文书
大学生自荐材料范文
2014/12/30 职场文书
大学生村官个人总结
2015/02/15 职场文书
反邪教观后感
2015/06/11 职场文书
java代码实现空间切割
2022/01/18 Java/Android