Vue2.4+新增属性.sync、$attrs、$listeners的具体使用


Posted in Javascript onMarch 08, 2020

sync

在vue2.4以前,父组件向子组件传值用props;子组件不能直接更改父组件传入的值,需要通过$emit触发自定义事件,通知父组件改变后的值。比较繁琐,写法如下:

//父组件
<template>
 <div class="parent">
  <p>父组件传入子组件的值:{{name}}</p>
  <fieldset>
   <legend>子组件</legend>
   <child :val="name" @update="modify">
   </child>
  </fieldset>
 </div>
</template>

<script>
import Child from './Child'
export default {
 components:{Child},
 data () {
  return {
   name:'linda'
  }
 },
 methods:{
  modify(newVal){
   this.name=newVal
  }
 }
}
</script>

//子组件
<template>
  <label class="child">
    输入框:
    <input :value=val @input="$emit('update',$event.target.value)"/>
  </label>
</template>
<script>
export default {
  props:['val']
}
</script>

vue2.4以后的写法明显舒服许多,上面同样的功能,直接上代码

//父组件
<template>
 <div class="parent">
  <p>父组件传入子组件的值:{{name}}</p>
  <fieldset>
   <legend>子组件</legend>
   <child :val.sync="name">
   </child>
  </fieldset>
 </div>
</template>

<script>
import Child from './Child'
export default {
 components:{Child},
 data () {
  return {
   name:'linda'
  }
 }
}
</script>

//子组件
<template>
  <label class="child">
    输入框:
    <input :value=val @input="$emit('update:val',$event.target.value)"/>
  </label>
</template>
<script>
export default {
  props:['val']
}
</script>

写法上简化了一部分,很明显父组件不用再定义方法检测值变化了。其实只是对以前的$emit方式的一种缩写,.sync其实就是在父组件定义了一update:val方法,来监听子组件修改值的事件。

$attrs

想象一下,你打算封装一个自定义input组件——MyInput,需要从父组件传入type,placeholder,title等多个html元素的原生属性。此时你的MyInput组件props如下:

props:['type','placeholder','title',...]

很丑陋不是吗?$attrs专门为了解决这种问题而诞生,这个属性允许你在使用自定义组件时更像是使用原生html元素。比如:

//父组件
<my-input placeholder="请输入你的姓名" type="text" title="姓名" v-model="name"/>

my-input的使用方式就像原生的input一样。而MyInput并没有设置props,如下

<template>
  <div>
    <label>输入框:</label><input v-bind="$attrsAll" @input="$emit('input',$event.target.value)"/>
  </div>
</template>
<script>
export default {
  inheritAttrs:false,
  computed: {
    $attrsAll() {
      return {
        value: this.$vnode.data.model.value,
        ...this.$attrs
      }
    }
  }
}
</script>

基础扫盲

v-model是v-bind:value和v-on:input的简写,所以在父组件你完全可以直接写 :value="name",@input="val => name = val"。查看文档

疑难

引用下vue的官方api中对$attrs的说明

$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)

比较迷惑的一点是给子组件设置:value="name"相当于给子组件设置props:['value'],所以在MyInput中直接从$attrs获取不到value,需要重新包装$attrsAll,添加value属性。所以子组件还有下面写法,我倾向于这种写法,因为它更优雅

<template>
  <div>
    <label>输入框:</label><input v-bind="$attrs" :value="value" @input="$emit('input',$event.target.value)"/>
  </div>
</template>
<script>
export default {
  inheritAttrs:false,
  props:['value']
}
</script>

$listener

同上面$attrs属性一样,这个属性也是为了在自定义组件中使用原生事件而产生的。比如要让前面的MyInput组件实现focus事件,直接这么写是没用的

<my-input @focus="focus" placeholder="请输入你的姓名" type="text" title="姓名" v-model="name"/>

必须要让focus事件作用于MyInput组件的input元素上,最终的MyInput源码如下:

<template>
  <div>
    <label>输入框:</label><input v-bind="$attrsAll" v-on="$listenserAll"/>
  </div>
</template>
<script>
export default {
  inheritAttrs:false,
  props:['value'],
  computed:{
     $attrsAll() {
      return {
        value: this.value,
        ...this.$attrs
      }
    },
    $listenserAll(){
      return Object.assign(
        {},
        this.$listeners,
        {input:(event) => this.$emit('input',event.target.value)})
    }
  }
}
</script>

到此这篇关于Vue2.4+新增属性.sync、$attrs、$listeners的具体使用的文章就介绍到这了,更多相关Vue2.4 .sync、$attrs、$listeners内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript中onmouse事件在div中失效问题的解决方法
Jan 09 Javascript
javascript对select标签的控制(option选项/select)
Jan 31 Javascript
javascript实现的弹出层背景置灰-模拟(easyui dialog)
Dec 27 Javascript
jquery实现未经美化的简洁TAB菜单效果
Aug 28 Javascript
JS实现环形进度条(从0到100%)效果
Jul 05 Javascript
jQuery Masonry瀑布流插件使用方法详解
Jan 18 Javascript
jQuery DOM节点的遍历方法小结
Aug 15 jQuery
JS判断用户用的哪个浏览器实例详解
Oct 09 Javascript
require.js 加载过程与使用方法介绍
Oct 30 Javascript
Vue.js轮播图走马灯代码实例(全)
May 08 Javascript
vue实现条件叠加搜索的解决方法
May 28 Javascript
three.js利用gpu选取物体并计算交点位置的方法示例
Nov 25 Javascript
Vue vm.$attrs使用场景详解
Mar 08 #Javascript
浅谈Vue2.4.0 $attrs与inheritAttrs的具体使用
Mar 08 #Javascript
vue-cli点击实现全屏功能
Mar 07 #Javascript
vue全屏事件开发详解
Jun 17 #Javascript
vue实现全屏滚动效果(非fullpage.js)
Mar 07 #Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
Mar 07 #Javascript
详解钉钉小程序组件之自定义模态框(弹窗封装实现)
Mar 07 #Javascript
You might like
用PHP程序实现支持页面后退的两种方法
2008/06/30 PHP
php 缩略图实现函数代码
2011/06/23 PHP
用JS剩余字数计算的代码
2008/07/03 Javascript
javascript自定义startWith()和endWith()的两种方法
2013/11/11 Javascript
jQuery实现tab标签自动切换的方法
2015/02/28 Javascript
javascript制作sql转换为stringBuffer的小工具
2015/04/03 Javascript
javascript设置和获取cookie的方法实例详解
2016/01/05 Javascript
jQuery基本选择器之标签名选择器
2016/09/03 Javascript
单行 JS 实现移动端金钱格式的输入规则
2017/05/22 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
微信小程序实现登录遮罩效果
2018/11/01 Javascript
Vue.js递归组件实现组织架构树和选人功能
2019/07/04 Javascript
vue cli安装使用less的教程详解
2019/07/12 Javascript
JavaScript Date对象功能与用法学习记录
2020/04/28 Javascript
Javascript实现鼠标移入方向感知
2020/06/24 Javascript
vue 弹出遮罩层样式实例
2020/07/22 Javascript
[03:08]Ti4观战指南上
2014/07/07 DOTA
在Python的Flask框架下收发电子邮件的教程
2015/04/21 Python
Python实现的手机号归属地相关信息查询功能示例
2017/06/08 Python
python 巧用正则寻找字符串中的特定字符的位置方法
2018/05/02 Python
python 保存float类型的小数的位数方法
2018/10/17 Python
Python中字符串List按照长度排序
2019/07/01 Python
python使用tomorrow实现多线程的例子
2019/07/20 Python
提升python处理速度原理及方法实例
2019/12/25 Python
Pandas实现一列数据分隔为两列
2020/05/18 Python
浅谈python量化 双均线策略(金叉死叉)
2020/06/03 Python
应届毕业生求职自荐书
2014/01/03 职场文书
自荐信写法介绍
2014/01/25 职场文书
《雷雨》教学反思
2014/02/20 职场文书
《钱学森》听课反思
2014/03/01 职场文书
2014离婚协议书范文(3篇)
2014/11/29 职场文书
2014年妇女工作总结
2014/12/06 职场文书
2014个人年终工作总结范文
2014/12/15 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
python如何在word中存储本地图片
2021/04/07 Python
Python中的 enumerate和zip详情
2022/05/30 Python