Vue.js组件通信之自定义事件详解


Posted in Javascript onOctober 19, 2019

组件通信

从父组件向子组件通信,通过props传递数据就可以了,但Vue组件通信的场景不止有这一种,归纳起来,组件之间的通信可以用下图来表示:

Vue.js组件通信之自定义事件详解

自定义事件

当子组件需要向父组件传递数据时,就要用到自定义事件。子组件用**$ emit()来触发事件**,父组件用**$ on()**来监听子组件的事件。

父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的事件。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <title>自定义事件</title>
</head>
<body>
  <div id="app">
    <p>总数:{{total}}</p>
    <my-component
      @increase="handleGetTotal"
      @reduce="handleGetTotal"></my-component>
  </div>
  <script>
    Vue.component('my-component',{
      template: '\
        <div>\
          <button @click="handleIncrease">+1</button>\
          <button @click="handleReduce">-1</button>\
        </div>',
      data: function () {
        return {
          counter: 0
        }
      },
      methods: {
        handleIncrease: function () {
          this.counter++;
          this.$emit('increase', this.counter);
        },
        handleReduce: function () {
          this.counter--;
          this.$emit('reduce', this.counter);
        }
      }
    });

    var app = new Vue({
      el: '#app',
      data: {
        total: 0
      },
      methods: {
        handleGetTotal: function (total) {
          this.total = total;
        }
      }
    });
  </script>
</body>
</html>

Vue.js组件通信之自定义事件详解

子组件有两个按钮,分别实现+1和-1的效果,在改变组件的data “counter”后,通过$emit()在把它传递给父组件,父组件使用v-on:increase和v-on:reduce监听事件。

$emit()方法的第一个参数是自定义事件的名称,后面的参数是要传递的数据,可以不填或者填写多个。

注意:除了用v-on在组件上监听自定义事件外,也可以监听DOM事件,这时候可以用 .native修饰符表示监听的是一个原生事件,监听的是该组件的根元素:

<my-component v-on:click.native="handleClick"></my-component>

使用v-model

Vue 2.x 可以在自定义组件上使用v-model指令。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <title>使用v-model</title>
</head>
<body>
  <div id="app">
    <p>总数:{{total}}</p>
    <my-component v-model="total"></my-component>
  </div>
  <script>
    Vue.component('my-component',{
      template: '<button @click="handleClick">+1</button>',
      data: function () {
        return {
          counter: 0
        }
      },
      methods: {
        handleClick: function () {
          this.counter++;
          this.$emit('input',this.counter);
        }
      }
    });

    var app = new Vue({
      el: '#app',
      data: {
        total: 0
      }
    });
  </script>
</body>
</html>

仍然是点击按钮+1的效果,不过这次组件$emit()的事件是特殊的input,在使用组件的父级,并没有在<my-component>上使用@input=“handler”,而是使用了v-model板顶的一个数据total。这也可以称作是一个语法糖,因为上面的示例可以间接地用自定义事件来实现:

<div id="myApp">
  <p>总数:{{total}}</p>
  <my-component1 @input="handlegetTotal"></my-component1>
</div>
<script>
  Vue.component('my-component1',{
    template: '<button @click="handleClick">+1</button>',
    data: function () {
      return {
        counter: 0
      }
    },
    methods: {
      handleClick: function () {
        this.counter++;
        this.$emit('input',this.counter);
      }
    }
  });

  var myApp = new Vue({
    el: '#myApp',
    data: {
      total: 0
    },
    methods: {
      handlegetTotal: function (value) {
        this.total = value;
      }
    }
  });
</script>

v-model还可以用来创建自定义的表单输入组件,进行数据双向绑定:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <title>自定义表单输入组件</title>
</head>
<body>
  <div id="app">
    <p>总数:{{total}}</p>
    <my-component v-model="total"></my-component>
    <button @click="handleReduce">-1</button>
  </div>
  <script>
    Vue.component('my-component',{
      props: ['value'],
      template: '<input :value="value" @input="updateValue">',
      methods: {
        updateValue: function (event) {
          this.$emit('input', event.target.value);
        }
      }
    });

    var app = new Vue({
      el: '#app',
      data: {
        total: 0
      },
      methods: {
        handleReduce: function () {
          this.total--;
        }
      }
    });
  </script>
</body>
</html>

Vue.js组件通信之自定义事件详解

注意:实现这样一个具有双向绑定的v-model组件要满足下面的两个要求:

  • 接受一个value属性
  • 在有新的value时触发input事件

更多教程点击《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

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

Javascript 相关文章推荐
jquery 弹出层注册页面等(asp.net后台)
Jun 17 Javascript
jquery checkbox实现单选小例
Nov 27 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
Jul 29 Javascript
Node.js实用代码段之正确拼接Buffer
Mar 17 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
May 30 Javascript
jquery判断iPhone、Android设备类型
Sep 14 Javascript
JavaScript数据结构学习之数组、栈与队列
May 02 Javascript
详解用webpack把我们的业务模块分开打包的方法
Jul 20 Javascript
layui 给数据表格加序号的方法
Aug 20 Javascript
详解webpack模块加载器兼打包工具
Sep 11 Javascript
Vue表情输入组件 微信face表情组件
Feb 11 Javascript
用js实现放大镜效果
Oct 28 Javascript
Vue.js自定义指令学习使用详解
Oct 19 #Javascript
Vue.js标签页组件使用方法详解
Oct 19 #Javascript
基于JavaScript获取base64图片大小
Oct 18 #Javascript
react MPA 多页配置详解
Oct 18 #Javascript
vue滚动插件better-scroll使用详解
Oct 18 #Javascript
VUE实现密码验证与提示功能
Oct 18 #Javascript
VUE实现图片验证码功能
Nov 18 #Javascript
You might like
php 判断服务器操作系统的类型
2014/02/17 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
2014/08/21 PHP
php使用curl实现ftp文件下载功能
2017/05/16 PHP
PHP优化之批量操作MySQL实例分析
2020/04/23 PHP
理解JavaScript中的对象 推荐
2011/01/09 Javascript
gridpanel动态加载数据的实例代码
2013/07/18 Javascript
引入autocomplete组件时JS报未结束字符串常量错误
2014/03/19 Javascript
javascript几个易错点记录
2014/11/26 Javascript
javascript实现图片上传前台页面
2015/08/18 Javascript
jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构
2015/11/19 Javascript
javascript闭包(Closure)用法实例简析
2015/11/30 Javascript
简要了解jQuery移动web开发的响应式布局设计
2015/12/04 Javascript
js实现内容显示并使用json传输数据
2016/03/16 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
2016/08/12 Javascript
微信小程序开发之录音机 音频播放 动画实例 (真机可用)
2016/12/08 Javascript
Angular2使用Guard和Resolve进行验证和权限控制
2017/04/24 Javascript
Node.js使用gm拼装sprite图片
2017/07/04 Javascript
jquery版轮播图效果和extend扩展
2017/07/18 jQuery
jquery tmpl模板(实例讲解)
2017/09/02 jQuery
基于js中的原型(全面讲解)
2017/09/19 Javascript
vue  directive定义全局和局部指令及指令简写
2018/11/20 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
2019/04/29 Javascript
JavaScript遍历查找数组中最大值与最小值的方法示例
2019/05/24 Javascript
Python显示进度条的方法
2014/09/20 Python
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
在django中自定义字段Field详解
2019/12/03 Python
利用python画出AUC曲线的实例
2020/02/28 Python
利用纯html5绘制出来的一款非常漂亮的时钟
2015/01/04 HTML / CSS
体育教育专业自荐信范文
2013/12/20 职场文书
干部个人对照检查材料
2014/08/25 职场文书
师范生见习报告范文
2014/11/03 职场文书
公司停电通知
2015/04/15 职场文书
毕业典礼主持词
2015/06/29 职场文书
为什么node.js不适合大型项目
2021/04/28 Javascript
Python MNIST手写体识别详解与试练
2021/11/07 Python
基于Redission的分布式锁实战
2022/08/14 Redis