关于vue3默认把所有onSomething当作v-on事件绑定的思考


Posted in Javascript onMay 15, 2020

最近在重新看vue3的rfcs,发现一个细节,原话如下:

props that start with on are handled as v-on bindings, with everything after on being converted to all-lowercase as the event name (more on this below)

也就是说,以后如果你在传递props的时候,以 on 开头的props,如果在组件上没有做props的声明,那么会被当作事件绑定到组件的根节点上。

究其原因,我大致概括了两点:

  • 兼容vue2中的v-on.native
  • vue3的vnode声明把props拍平了,为了区分事件和其他props,就统一把所有的on开通的props默认作为事件绑定

为此,我开了一个issue来讨论这个问题,issue地址 。我关心的主要有两点:

  • 这是对functional component的严重限制
  • 是否会导致一些令人括困惑的误解

先讲第一点

vue3中可以直接通过 function() {} 来声明函数组件了,这是一个便利性的非常大的提升。在以前,你要声明组件,你必须要:

{
  functinal: true,
  props: {},
  render() {}
}

这最大的提升来自不需要声明props,为什么说这是提升,因为这让我们开发HOC变得更方便了。现在我们可以通过 ...rest 的方式把HOC不关心的props直接向下传递了。

但是现在因为这个默认限制,我们不得不在HOC中声明所有可能的他要扩展的组件以 on 开头的props。举个例子,我们有如下组件:

{
  props: {
    name: String,
    onChange: Function
  }
}

而我们的HOC的功能是在 name 前面加上 prefix ,对于这个HOC我们需要关心的只是 name 和他自己的props: prefix 。所以他的声明应该如下:

{
  props: {
    name: String,
    prefix: String
  }
}

然后在render中他可以这么做:

{
  render() {
    const {name, prefix, ...rest} = props
    return <WrapperedComponent name={`${prefix}-${name}`} {...rest} />
  }
}

也就是对于HOC来说,他是不需要关心他扩展的组件其他的props的,但是在这种情况下,如果我们不在HOC中声明,那么在使用的时候传入的 onChange 会自动绑定到root节点,而不是作为props传递下去。

第二点:令人困惑的使用

举个例子,如果我有一个组件:

{
  props: {
    onChange: Function
  },
  methods: {
    handleInput() {
      // do someting
      // 并且根据情况触发`onChange`
    } 
  },
  render() {
    return <input onInput={this.handleInput} />
  }
}

很显然我是想要封装 input 的变化,在满足某些条件的时候才对外抛出新的value。但是如果这个时候有人就是不看文档,直接传递了 onInput ,那么这时候 input 事件会直接绑定到节点上,那么这也是可以触发的。

如果我们的测试用例太少或者不仔细,很可能反应不过来他们的区别。这显然是作为组件开发者的我们不希望出现的,但我们又无法限制这种行为。

总结

不得不说,我在考虑这两个问题的时候是有一定的 React思维 在里面的。因为个人来说我是比较喜欢React的API设计的,非常的简洁,其对于组件的使用也更趋于极致,就是一切皆组件(连 redirect 这样的行为都定义成了组件)。

而vue是一直在跟随react的,相信这点大家也不会否认。vue3更新的hooks(Composition)API,Suspense等明显是借鉴的React的概念。

但同时我又是很看好vue3的,我一直觉得vue2这样的API设计以及 .vue 文件的开发模式都是为了吸引中低级用户而准备的,甚至舍弃了一些高级API特性(比如HOC在vue中就很难实现,并且普及率相当低)。

而vue3的hooks API以及其对JSX的更好支持,还有更纯粹的 functional component ,让我一度看到了vue在工程方面更激进的变化。

但是 v-on 的默认行为,却又是一次那么明显的 替用户做决定 的行为。其实要解决这个问题很简单,可以完全不考虑 v-on ,把所有传递的参数作为props,如果组件开发者真的要在根节点上绑定事件,他可以实现的时候绑定,我们不应该在使用组件的场景下需要考虑在组件内部的节点上做一些事情,这样做的副作用实在太大了。

虽然目前看来尤老师会听取我的意见的可能性是非常小的,但我还是抱有一点简单的期望吧。

到此这篇关于关于vue3默认把所有onSomething当作v-on事件绑定的思考的文章就介绍到这了,更多相关vue3 onSomething当作v-on事件绑定内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
asp批量修改记录的代码
Jun 25 Javascript
jquery监控数据是否变化(修正版)
Apr 12 Javascript
非主流的textarea自增长实现js代码
Dec 20 Javascript
Bootstrap表格和栅格分页实例详解
May 20 Javascript
React实现双向绑定示例代码
Sep 19 Javascript
jQuery实现CheckBox全选、全不选功能
Jan 11 Javascript
JavaScript之underscore_动力节点Java学院整理
Jul 03 Javascript
详解node+express+ejs+bootstrap构建项目
Sep 27 Javascript
React注册倒计时功能的实现
Sep 06 Javascript
深入理解JavaScript 箭头函数
May 30 Javascript
layui按条件隐藏表格列的实例
Sep 19 Javascript
vue+element搭建后台小总结 el-dropdown下拉功能
Apr 10 Javascript
js实现简单贪吃蛇游戏
May 15 #Javascript
Javascript执行流程细节原理解析
May 14 #Javascript
使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法
May 14 #Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
May 14 #Javascript
vue组件系列之TagsInput详解
May 14 #Javascript
ant-design-vue按需加载的坑的解决
May 14 #Javascript
JavaScript数组排序功能简单实现
May 14 #Javascript
You might like
ip签名探针
2006/10/09 PHP
php基于双向循环队列实现历史记录的前进后退等功能
2015/08/08 PHP
php使用CURL模拟GET与POST向微信接口提交及获取数据的方法
2016/09/23 PHP
浅谈php数组array_change_key_case() 函数和array_chunk()函数
2016/10/22 PHP
在Laravel中实现使用AJAX动态刷新部分页面
2019/10/15 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
零基础学JavaScript最新动画教程+iso光盘下载
2008/01/22 Javascript
Js nodeType 属性全面解析
2013/11/14 Javascript
javascript模拟地球旋转效果代码实例
2013/12/02 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
jquery实现根据浏览器窗口大小自动缩放图片的方法
2015/07/17 Javascript
easyui中combotree循环获取父节点至根节点并输出路径实现方法
2016/11/10 Javascript
基于vue开发的在线付费课程应用过程
2018/01/25 Javascript
vue自定义全局组件(自定义插件)的用法
2018/01/30 Javascript
JavaScript调用模式与this关键字绑定的关系
2018/04/21 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
Node.js npm命令运行node.js脚本的方法
2018/10/10 Javascript
Python爬虫抓取手机APP的传输数据
2016/01/22 Python
简单掌握Python的Collections模块中counter结构的用法
2016/07/07 Python
Python读取word文本操作详解
2018/01/22 Python
简单了解python中对象的取反运算符
2019/07/01 Python
解决Djang2.0.1中的reverse导入失败的问题
2019/08/16 Python
Python序列化与反序列化pickle用法实例
2019/11/11 Python
Django form表单与请求的生命周期步骤详解
2020/06/07 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
python爬虫---requests库的用法详解
2020/09/28 Python
css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况
2016/12/06 HTML / CSS
Brasty罗马尼亚:购买手表、香水、化妆品、珠宝
2020/04/21 全球购物
会计自我鉴定
2013/11/02 职场文书
房屋转让协议书
2014/10/18 职场文书
2014幼儿园中班工作总结
2014/11/10 职场文书
雷锋之歌观后感
2015/06/10 职场文书
2016年机关单位节能宣传周活动总结
2016/04/05 职场文书
人生一定要学会的三样东西:放下、忘记、珍惜
2019/08/21 职场文书
新手必备Python开发环境搭建教程
2021/05/28 Python
vue如何清除浏览器历史栈
2022/05/25 Vue.js