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 相关文章推荐
Javascript 作用域使用说明
Aug 13 Javascript
基于JQuery的多标签实现代码
Sep 19 Javascript
jquery乱码与contentType属性设置问题解决方案
Jan 07 Javascript
js浮动图片的动态效果
Jul 10 Javascript
jquery实现树形二级菜单实例代码
Nov 20 Javascript
js获取通过ajax返回的map型的JSONArray的方法
Jan 09 Javascript
Bootstrap3制作图片轮播效果
May 12 Javascript
AngularJs IE Compatibility 兼容老版本IE
Sep 01 Javascript
js日期相关函数dateAdd,dateDiff,dateFormat等介绍
Sep 24 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
解决vue中修改export default中脚本报一大堆错的问题
Aug 27 Javascript
vue 导航菜单刷新状态不消失,显示对应的路由界面操作
Aug 06 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 输出缓存详解
2009/06/20 PHP
PHP开发的一些注意点总结
2010/10/12 PHP
基于php设计模式中单例模式的应用分析
2013/05/15 PHP
遍历echsop的region表形成缓存的程序实例代码
2016/11/01 PHP
CentOS7编译安装php7.1的教程详解
2019/04/18 PHP
文本框水印提示效果的简单实现代码
2014/02/22 Javascript
ANGULARJS中用NG-BIND指令实现单向绑定的例子
2014/12/08 Javascript
jQuery内容过滤选择器用法分析
2015/02/10 Javascript
JavaScript使用DeviceOne开发实战(三)仿微信应用
2015/12/02 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
Bootstrap学习笔记之js组件(4)
2016/06/12 Javascript
高效Web开发的10个jQuery代码片段
2016/07/22 Javascript
JS Select下拉框(支持输入模糊查询)
2017/02/04 Javascript
socket.io学习教程之基本应用(二)
2017/04/29 Javascript
jQuery插件artDialog.js使用与关闭方法示例
2017/10/09 jQuery
什么是Vue.js框架 为什么选择它?
2017/10/17 Javascript
react-native fetch的具体使用方法
2017/11/01 Javascript
laydate时间日历插件使用方法详解
2018/11/14 Javascript
Angular 多模块项目构建过程
2020/02/13 Javascript
jquery实现垂直手风琴菜单
2020/03/04 jQuery
json_decode 索引为数字时自动排序问题解决方法
2020/03/28 Javascript
Vue组件通信$attrs、$listeners实现原理解析
2020/09/03 Javascript
ant design vue 表格table 默认勾选几项的操作
2020/10/31 Javascript
[00:20]TI9观赛名额抽取Ⅱ
2019/07/24 DOTA
python批量生成本地ip地址的方法
2015/03/23 Python
pycharm安装和首次使用教程
2018/08/27 Python
Python3.5字符串常用操作实例详解
2019/05/01 Python
Idea安装python显示无SDK问题解决方案
2020/08/12 Python
HTML里显示pdf、word、xls、ppt的方法示例
2020/04/14 HTML / CSS
电气个人求职信范文
2014/02/04 职场文书
保护环境的建议书
2014/03/12 职场文书
2014年大学生四年规划书范文
2014/04/03 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
帝企鹅日记观后感
2015/06/10 职场文书
关于做家务的心得体会
2016/01/23 职场文书
Redis IP地址的绑定的实现
2021/05/08 Redis