专栏首页胡哥有话说Vue.js中异常高效可用的.sync修饰符

Vue.js中异常高效可用的.sync修饰符

前言

在Vue.js中,父子组件进行数据通信是一个老生常谈的话题,父级组件通过Prop向子组件传递数据,而子组件如何向父级组件进行数据交流沟通呢?

一、父子组件数据交互 - 第一种方式

业务需求:

子组件展示父组件传递的数值num,点击子组件中的+号按钮,改变父组件num的值

页面效果展示

定义子组件

// Num.vue
<template>
  <div class="num">
    <h3>子组件</h3>
    <button @click="plus">+</button>
    <h3>子组件:{{ num }}</h3>
  </div>
</template>
<script>
export default {
  name: 'Num',
  props: {
    num: {
      type: Number,
      required: true
    }
  },
  methods: {
    /**
     * 子组件是无法直接修改this.num,也无法直接修改父级组件的num
     * 子组件$emit触发特定事件,父级组件监听对应事件,处理num
    */
    plus () {
      let num = this.$props.num
      this.$emit('updateNum', ++num)
    }
  }
}
</script>

定义父组件

// Index.vue
<template>
    <div class="index">
      <h3>父组件:{{ num }}</h3>
      <hr>
      <num :num="num" @updateNum="updateNum"></num>
    </div>
</template>
<script>
import Num from './Num'
export default {
  name: 'Index',
  data () {
    return {
      num: 1
    }
  },
  components: {
    Num
  },
  methods: {
    // 更新num,传递到子组件的数据发生更新
    updateNum (num) {
      this.num = num
    }
  }
}
</script>

小结

使用以上方式进行父子组件通信是Vue.js的标配:父组件通过prop向子组件传递数据,子组件使用$emit触发特定的事件updateNum,父组件监听特定的事件updateNum,进而更新父组件数据。功能确实实现了,但是在部分情况下不是那么完美

缺点: 考虑到Num.vue以后可能被多个组件复用,那么每个父组件中都需要监听处理updateNum事件,这样的话,对于父组件提升了其复杂性,对于子组件降低了其功能的独立性。

二、父子组件数据交互 - 第二种方式

完美解决方案:.sync修饰符

Vue.js本身就考虑到这种情况,提供了使用.sync修饰符,以实现更加便捷的从子组件更新父组件数据。

父子组件都要进行特定的配置

子组件

在原有的Num.vue中,需要修改以下位置代码:

// Num.vue
methods: {
    plus () {
        let num = this.$props.num
        // 注意:此处触发的update:xxx事件,是特定的事件名称,xxx对应的是父组件中对应的变量num
        this.$emit('update:num', ++num)
    }
}

父组件

在原有的父组件Index.vue中,需要修改以下位置的代码:

// Index.vue
<template>
    <!-- 其他代码 -->
    <!--
        调用Num组件,并传递num,此处一定要添加.sync修饰符
        同时不用再监听任何其他事件
        同时methods中添加的updateNum方法删除即可
    -->
    <num :num.sync="num"></num>
</template>

现在就实现了第一种方式中的相同功能!手动 微笑.gif

小结

其实.sync修饰符是相同于Vue.js自动帮你在Index.vue中的num组件调用上监听了update:num事件,并将传递的新值赋值到了变量num上,实现了子组件更新父组件的变量,进行了数据通信。

思维拓展

在很多的第三方框架中,如element-ui,都使用了.sync修饰符的功能。比如Dialog对话框组件,调用时也是使用.sync方式传递变量visible的值,子组件Dialog在执行关闭对话框时,就执行了this.$emit('update:visible', false)(详情可自行查看elemnt-ui源码)

后记

以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得收藏、转发、点击在看呦,欢迎多多留言交流...

胡哥有话说,一个有技术,有情怀的胡哥!京东开放平台首席前端攻城狮。与你一起聊聊大前端,分享前端系统架构,框架实现原理,最新最高效的技术实践!

本文分享自微信公众号 - 胡哥有话说(hugeyouhuashuo)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 浅入深出Vue:前言

    之前大部分是在做后端,后来出于某些原因开始接触Vue。深感前端变化之大,各种工具、框架令人眼花缭乱。不过正是这些变化,让前端开发更灵活。

    若羽
  • 浅入深出Vue:工具准备之PostMan安装配置及Mock服务配置

    由于家中有事,文章没顾得上。在此说声抱歉,这是工具准备的最后一章。 接下来就是开始环境搭建了~尽情期待

    若羽
  • 浅入深出Vue:数据渲染

    今天来正式开始 vue的学习,首当其冲的当然是数据的渲染。毕竟数据就是拿来看的,看看如果使用 vue来展示数据。

    若羽
  • 浅入深出Vue:事件处理

    在前端开发中,经常要面对各种表单、按钮。而这里面就住着一个事件:点击 (click)。

    若羽
  • mpvue搭建小程序框架

    由于mpvue框架是完全基于Vue框架的(重写了其runtime和compiler) 运行时框架 runtime 和代码编译器 compiler 实现

    达达前端
  • 浅入深出Vue:路由

    路由的概念在计算机界中的历史大概可以追溯到OSI模型中的数据链路层与网络层中的定义。这里的定义大意是:在转发数据包时,根据数据包的目的地址进行寻址,从而将数据包...

    若羽
  • 浅入深出Vue:数据绑定

    上一篇我们使用了简单的数据渲染,那么如果说我们想要动态渲染标签的 class 可以这么操作么?

    若羽
  • Vue简介

    vue.js 中 data, prop, computed, method,watch 介绍

    达达前端
  • 浅入深出Vue:组件

    这三部分会在接下来的章节中一一实践,在本篇中并不会给出具体的实例代码。 本篇更侧重于讲清楚在写组件之前应该要注意的地方。

    若羽
  • 浅入深出Vue:环境搭建

    这里同样的,有固态硬盘的童鞋可以安装到固态硬盘,不过这里有个小问题就是 在选择目录的时候会卡死一小会儿。可能是若羽的机器性能不太好。

    若羽

扫码关注云+社区

领取腾讯云代金券