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 相关文章推荐
js 对象是否存在判断
Jul 15 Javascript
js 实现菜单左右滚动显示示例介绍
Nov 21 Javascript
屏蔽相应键盘按钮操作
Mar 10 Javascript
jQuery的deferred对象详解
Nov 12 Javascript
Three.js学习之Lamber材质和Phong材质
Aug 04 Javascript
详解用vue.js和laravel实现微信支付
Jun 23 Javascript
ES6学习教程之对象字面量详解
Oct 09 Javascript
详解promise.then,process.nextTick, setTimeout 以及 setImmediate的执行顺序
Nov 21 Javascript
vue实现日历备忘录功能
Sep 24 Javascript
js实现无限瀑布流实例方法
Sep 16 Javascript
过滤器vue.filters的使用方法实现
Sep 18 Javascript
JavaScript实现栈结构Stack过程详解
Mar 07 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 开发环境配置(Zend Studio)
2010/04/28 PHP
php数组函数序列之array_sum() - 计算数组元素值之和
2011/10/29 PHP
thinkPHP5框架导出Excel文件简单操作示例
2018/08/03 PHP
PHP设计模式之工厂模式(Factory Pattern)的讲解
2019/03/21 PHP
srcElement表格样式
2006/09/03 Javascript
点击广告后才能获得下载地址
2006/10/26 Javascript
可以将word转成html的js代码
2010/04/11 Javascript
formStorage 基于jquery的一个插件(存储表单中元素的状态到本地)
2012/01/20 Javascript
JavaScript自动设置IFrame高度的小例子
2013/06/08 Javascript
jQuery操作JSON的CRUD用法实例
2015/02/25 Javascript
JavaScript中的ajax功能的概念和示例详解
2016/10/17 Javascript
jquery组件WebUploader文件上传用法详解
2020/10/23 Javascript
Bootstrap源码解读标签、徽章、缩略图和警示框(8)
2016/12/26 Javascript
详解nodeJs文件系统(fs)与流(stream)
2018/01/24 NodeJs
nodejs aes 加解密实例
2018/10/10 NodeJs
nodejs实现用户登录路由功能
2019/05/22 NodeJs
JS实现分页导航效果
2020/02/19 Javascript
解决vue下载后台传过来的乱码流的问题
2020/12/05 Vue.js
python实现数通设备端口监控示例
2014/04/02 Python
在Python中操作日期和时间之gmtime()方法的使用
2015/05/22 Python
python使用Tkinter实现在线音乐播放器
2018/01/30 Python
python将.ppm格式图片转换成.jpg格式文件的方法
2018/10/27 Python
Python http接口自动化测试框架实现方法示例
2018/12/06 Python
解决python 未发现数据源名称并且未指定默认驱动程序的问题
2018/12/07 Python
Python日志无延迟实时写入的示例
2019/07/11 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
自定义html标记替换html5新增元素
2008/10/17 HTML / CSS
来自美国主售篮球鞋的零售商店:KICKSUSA
2017/11/28 全球购物
初一科学教学反思
2014/01/27 职场文书
计算机专业自荐信
2014/05/24 职场文书
优秀少先队辅导员事迹材料
2014/12/24 职场文书
2016学校先进党组织事迹材料
2016/02/29 职场文书
python spilt()分隔字符串的实现示例
2021/05/21 Python
pytorch中F.avg_pool1d()和F.avg_pool2d()的使用操作
2021/05/22 Python
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android
以MySQL5.7为例了解一下执行计划
2022/04/13 MySQL