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 each()方法的使用方法
Mar 18 Javascript
jQuery源码分析-05异步队列 Deferred 使用介绍
Nov 14 Javascript
Backbone.js中的集合详解
Jan 14 Javascript
javascript中eval解析JSON字符串
Feb 27 Javascript
Boostrap模态窗口的学习小结
Mar 28 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
Oct 28 Javascript
Javascript 普通函数和构造函数的区别
Nov 05 Javascript
修改ligerui 默认确认按钮的方法
Dec 27 Javascript
详解webpack中的hash、chunkhash、contenthash区别
Jan 05 Javascript
Angularjs中date过滤器失效的问题及解决方法
Jul 06 Javascript
JavaScript异步操作的几种常见处理方法实例总结
May 11 Javascript
图解JS原型和原型链实现原理
Sep 15 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
全国FM电台频率大全 - 26 西藏自治区
2020/03/11 无线电
基于python发送邮件的乱码问题的解决办法
2013/04/25 PHP
PHP类的特性实例分析
2016/09/28 PHP
用cookies实现的可记忆的样式切换效果代码下载
2007/12/24 Javascript
很可爱的输入框
2008/08/03 Javascript
javascript随机将第一个dom中的图片添加到第二个div中示例
2013/10/08 Javascript
node.js 使用ejs模板引擎时后缀换成.html
2015/04/22 Javascript
仅30行代码实现Javascript中的MVC
2016/02/15 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
2017/06/03 Javascript
vue webuploader 文件上传组件开发
2017/09/23 Javascript
js处理包含中文的字符串实例
2017/10/11 Javascript
JS工厂模式开发实践案例分析
2019/10/17 Javascript
vue elementui 实现搜索栏公共组件封装的实例代码
2020/01/20 Javascript
javascript中导出与导入实现模块化管理教程
2020/12/03 Javascript
[02:51]2018年度DOTA2最佳中单位选手-完美盛典
2018/12/17 DOTA
Windows和Linux下使用Python访问SqlServer的方法介绍
2015/03/10 Python
windows下python之mysqldb模块安装方法
2017/09/07 Python
Django admin实现图书管理系统菜鸟级教程完整实例
2017/12/12 Python
Python使用selenium实现网页用户名 密码 验证码自动登录功能
2018/05/16 Python
python 自动去除空行的实例
2018/07/24 Python
Face++ API实现手势识别系统设计
2018/11/21 Python
Python 运行 shell 获取输出结果的实例
2019/01/07 Python
学习Django知识点分享
2019/09/11 Python
Python脚本导出为exe程序的方法
2020/03/25 Python
python 数据库查询返回list或tuple实例
2020/05/15 Python
Python延迟绑定问题原理及解决方案
2020/08/04 Python
python实现excel公式格式化的示例代码
2020/12/23 Python
实例教程 一款纯css3实现的数字统计游戏
2014/11/10 HTML / CSS
一款基于css3和jquery实现的动画显示弹出层按钮教程
2015/01/04 HTML / CSS
韩国休闲女装品牌网站:ANAIS
2016/08/24 全球购物
Mytheresa美国官网:德国知名的女性奢侈品电商
2017/05/27 全球购物
英国健康和美容技术产品购物网站:CurrentBody
2019/07/17 全球购物
毕业生就业协议书
2014/04/11 职场文书
安阳殷墟导游词
2015/02/10 职场文书
CSS巧用渐变实现高级感背景光动画
2021/12/06 HTML / CSS