关于vue3默认把全部`onSomething`看成`v-on`事件绑定的思考

最近在从新看vue3的rfcs,发现一个细节,原话以下:vue

  • 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的声明,那么会被看成事件绑定到组件的根节点上。node

究其缘由,我大体归纳了两点:react

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

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

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

先讲第一点

vue3中能够直接经过function() {}来声明函数组件了,这是一个便利性的很是大的提高。在之前,你要声明组件,你必需要:github

{
    functinal: true,
    props: {},
    render() {}
}
复制代码

这最大的提高来自不须要声明props,为何说这是提高,由于这让咱们开发HOC变得更方便了。如今咱们能够经过...rest的方式把HOC不关心的props直接向下传递了。数组

可是如今由于这个默认限制,咱们不得不在HOC中声明全部可能的他要扩展的组件以on开头的props。举个例子,咱们有以下组件:bash

{
    props: {
        name: String,
        onChange: Function
    }
}
复制代码

而咱们的HOC的功能是在name前面加上prefix,对于这个HOC咱们须要关心的只是name和他本身的props: prefix。因此他的声明应该以下:app

{
    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,若是组件开发者真的要在根节点上绑定事件,他能够实现的时候绑定,咱们不该该在使用组件的场景下须要考虑在组件内部的节点上作一些事情,这样作的反作用实在太大了。

虽然目前看来尤老师会听取个人意见的可能性是很是小的,但我仍是抱有一点简单的指望吧。

相关文章
相关标签/搜索