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遍历Json的两种数据结构的实现代码
Jan 19 Javascript
multiSteps 基于Jquery的多步骤滑动切换插件
Jul 22 Javascript
javascript利用apply和arguments复用方法
Nov 25 Javascript
js实现完美兼容各大浏览器的人民币大小写相互转换
Oct 29 Javascript
深入理解setTimeout函数和setInterval函数
May 20 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
Dec 05 Javascript
react 组件传值的三种方法
Jun 03 Javascript
vue+elementUi图片上传组件使用详解
Aug 20 Javascript
vue中npm包全局安装和局部安装过程
Sep 03 Javascript
vue中的双向数据绑定原理与常见操作技巧详解
Mar 16 Javascript
在vue中使用Base64转码的案例
Aug 07 Javascript
Vue路由权限控制解析
Nov 09 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
怎样在UNIX系统下安装MySQL
2006/10/09 PHP
整理的9个实用的PHP库简介和下载
2010/11/09 PHP
神盾加密解密教程(三)PHP 神盾解密工具
2014/06/08 PHP
PHP多线程之内部多线程实例分析
2015/03/09 PHP
Laravel5.5 数据库迁移:创建表与修改表示例
2019/10/23 PHP
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
汉化英文版的Dreamweaver CS5并自动提示jquery
2010/11/25 Javascript
怎么判断js脚本加载完成
2014/02/28 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
使用jQuery实现星级评分代码分享
2014/12/09 Javascript
把Node.js程序加入服务实现随机启动
2015/06/25 Javascript
JS截取与分割字符串常用技巧总结
2015/11/10 Javascript
ashx文件获取$.ajax()方法发送的数据
2016/05/26 Javascript
Bootstrap3.0建站教程(一)之bootstrap表单元素排版
2016/06/01 Javascript
JS控制FileUpload的上传文件类型实例代码
2016/10/07 Javascript
全面解析vue中的数据双向绑定
2017/05/10 Javascript
JS中的JSON对象的定义和取值实现代码
2018/05/09 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
2018/09/05 Javascript
Vuex 单状态库与多模块状态库详解
2018/12/11 Javascript
vue3修改link标签默认icon无效问题详解
2019/10/09 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
2020/09/11 Javascript
python3使用tkinter实现ui界面简单实例
2014/01/10 Python
python模块之StringIO使用示例
2015/04/08 Python
python下os模块强大的重命名方法renames详解
2017/03/07 Python
Python装饰器原理与简单用法实例分析
2018/04/29 Python
Python数据持久化shelve模块用法分析
2018/06/29 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
python 使用while写猜年龄小游戏过程解析
2019/10/07 Python
瑞贝卡·明可弗包包官网:Rebecca Minkoff
2016/07/21 全球购物
大学生毕业求职简历的自我评价
2013/10/24 职场文书
六个一活动实施方案
2014/03/21 职场文书
审计局2014法制宣传日活动总结
2014/11/01 职场文书
2015年小学实验室工作总结
2015/07/28 职场文书
血轮眼轮回眼特效 html+css
2021/03/31 HTML / CSS
SpringBoot整合Redis入门之缓存数据的方法
2021/11/17 Redis
Golang 切片(Slice)实现增删改查
2022/04/22 Golang