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 10 Javascript
js类型转换与引用类型详解(Boolean_Number_String)
Mar 07 Javascript
JavaScript利用append添加元素报错的解决方法
Jul 01 Javascript
JavaScript改变CSS样式的方法汇总
May 07 Javascript
JavaScript中的splice()方法使用详解
Jun 09 Javascript
微信小程序 loading 详解及实例代码
Nov 09 Javascript
JS中Select下拉列表类(支持输入模糊查询)功能
Jan 17 Javascript
浅谈Vuejs Prop基本用法
Aug 17 Javascript
js获取文件里面的所有文件名(实例)
Oct 17 Javascript
node.js通过axios实现网络请求的方法
Mar 05 Javascript
微信小程序实现漂亮的弹窗效果
May 26 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
May 08 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
Yii2 输出xml格式数据的方法
2016/05/03 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
2017/03/31 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
PHP中localeconv()函数的用法
2019/03/26 PHP
javascript new fun的执行过程
2010/08/05 Javascript
jQuery学习笔记之jQuery选择器的使用
2010/12/22 Javascript
firebug的一个有趣现象介绍
2011/11/30 Javascript
一个简单的JS鼠标悬停特效具体方法
2013/06/17 Javascript
js中Image对象以及对其预加载处理示例
2013/11/20 Javascript
JavaScript运行机制之事件循环(Event Loop)详解
2014/10/10 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
JSON 数据详解及实例代码分析
2017/01/20 Javascript
AngularJS select设置默认值的实现方法
2017/08/25 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
2017/11/27 Javascript
通过 JS 判断页面是否有滚动条的实现方法
2018/04/05 Javascript
JS使用正则表达式获取小括号、中括号及花括号内容的方法示例
2018/06/01 Javascript
jquery 插件重新绑定的处理方法分析
2019/11/23 jQuery
vue element table中自定义一些input的验证操作
2020/07/18 Javascript
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
2016/12/15 Python
用python做一个搜索引擎(Pylucene)的实例代码
2017/07/05 Python
python数据分析数据标准化及离散化详解
2018/02/26 Python
在Python中增加和插入元素的示例
2018/11/01 Python
python threading和multiprocessing模块基本用法实例分析
2019/07/25 Python
Python range与enumerate函数区别解析
2020/02/28 Python
CSS3图片旋转特效(360/60/-360度)
2013/10/10 HTML / CSS
使用HTML5进行SVG矢量图形绘制的入门教程
2016/02/19 HTML / CSS
土耳其时尚购物网站:Morhipo
2017/09/04 全球购物
意大利婴儿产品网上商店:Mukako
2018/10/14 全球购物
Yahoo-PHP面试题2
2014/12/06 面试题
电气工程师岗位职责
2014/01/01 职场文书
美术社团活动总结
2014/06/27 职场文书
2015年设计师个人工作总结
2015/04/25 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书
创业计划书之面包店
2019/09/12 职场文书
redis通过6379端口无法连接服务器(redis-server.exe闪退)
2021/05/08 Redis
Java 在线考试云平台的实现
2021/11/23 Java/Android