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的loading效果实现代码
Nov 05 Javascript
一个JavaScript去除字符串末尾的空白实例代码
Sep 22 Javascript
学习JavaScript设计模式之代理模式
Jan 12 Javascript
web 前端常用组件之Layer弹出层组件
Sep 22 Javascript
基于Three.js插件制作360度全景图
Nov 29 Javascript
JavaScript实现计数器基础方法
Oct 10 Javascript
JS实现table表格内针对某列内容进行即时搜索筛选功能
May 11 Javascript
js中Object.defineProperty()方法的不详解
Jul 09 Javascript
JS中async/await实现异步调用的方法
Aug 28 Javascript
js如何验证密码强度
Mar 18 Javascript
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 Vue.js
JavaScript使用canvas绘制坐标和线
Apr 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变量内存分配问题记录整理
2013/11/27 PHP
php查找任何页面上的所有链接的方法
2013/12/03 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
php将服务端的文件读出来显示在web页面实例
2016/10/31 PHP
PHP实现的最大正向匹配算法示例
2017/12/19 PHP
node.js中的fs.futimes方法使用说明
2014/12/17 Javascript
js强制把网址设为默认首页
2015/09/29 Javascript
编写高性能Javascript代码的N条建议
2015/10/12 Javascript
Jquery效果大全之制作电脑健康体检得分特效附源码下载
2015/11/02 Javascript
浅析AngularJS Filter用法
2015/12/28 Javascript
JavaScript编写页面半透明遮罩效果的简单示例
2016/05/09 Javascript
原生JS版和jquery版实现checkbox的全选/全不选/点选/行内点选(Mr.Think)
2016/10/29 Javascript
Javascript刷新页面的实例
2017/09/23 Javascript
JavaScript html5 canvas实现图片上画超链接
2017/10/20 Javascript
浅谈Angular单元测试总结
2019/03/22 Javascript
优雅地使用loading(推荐)
2019/04/20 Javascript
详解element-ui中el-select的默认选择项问题
2019/08/02 Javascript
Vue中通过Vue.extend动态创建实例的方法
2019/08/13 Javascript
jQuery操作元素的内容和样式完整实例分析
2020/01/10 jQuery
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
2020/09/01 Javascript
python使用any判断一个对象是否为空的方法
2014/11/19 Python
在RedHat系Linux上部署Python的Celery框架的教程
2015/04/07 Python
python实现RSA加密(解密)算法
2016/02/17 Python
Python利用ORM控制MongoDB(MongoEngine)的步骤全纪录
2018/09/13 Python
Python3 单行多行万能正则匹配方法
2019/01/07 Python
python 自动批量打开网页的示例
2019/02/21 Python
详解numpy.meshgrid()方法使用
2019/08/01 Python
Python转换字典成为对象,可以用&quot;.&quot;方式访问对象属性实例
2020/05/11 Python
CSS3中Animation动画属性用法详解
2016/07/04 HTML / CSS
理肤泉俄罗斯官网:La Roche-Posay俄罗斯
2018/07/24 全球购物
Java的类可以定义为Protected或者Private得吗
2015/09/25 面试题
药学专业毕业生求职信
2013/10/20 职场文书
保险内勤岗位职责
2015/04/13 职场文书
环保建议书作文300字
2015/09/14 职场文书
2019幼儿教师求职信(3篇)
2019/09/20 职场文书
python 解决微分方程的操作(数值解法)
2021/05/26 Python