- 开始时间:2019-01-28
- 目标主要版本:3.x
- 引用 issue:https://github.com/vuejs/vue-next/issues/8
- 实现的 PR:N/A
摘要
删除 v-bind 的 .sync 修饰符,用 v-model 上的参数来替代它。
基本范例
替代:
<MyComponent v-bind:title.sync="title" />
语法为:
<MyComponent v-model:title="title" />
动机
我们看到 v-bind.sync 在 Vue2 中引发了相当多的混乱,因为用户希望能像 v-bind 那样使用表达式(不管我们在文档中写了什么)。我最成功的解释是:
把 v-bind:title.sync=”title” 想象成一个有额外行为的普通绑定,其实是错误的。因为双向绑定在本质上是不同的。.sync 修饰符工作原理与 v-model 类似,v-model 是 Vue 创建双向绑定的另一种语法糖。主要区别在于,它扩展到一个稍微不同的模式,允许你在一个组件上有多个双向绑定,而不只限于一种。
这让我想到一个问题:如果告诉用户不要把 v-bind.sync 当成 v-bind,而把它当成 v-model,这样做有帮助的话,它是否应该成为 v-model API 的一部分。
具体设计
注意:虽然不是提案的一部分,但 v-model 的实现细节可能会在 Vue 3 中改变,以使透明包装组件等常见模式更容易实现。当你看到 modelValue 属性和 update:modelValue 事件时,你要知道他们是特殊的占位符,用于说明我们如何通过表单元素实现 v-model 的特殊行为,而不是本提案中的一项建议。
在元素上
<input v-model="xxx"><!-- would be shorthand for: --><input:model-value="xxx"@update:model-value="newValue => { xxx = newValue }">
<input v-model:aaa="xxx"><!-- INVALID: should throw a compile time error -->
注意:v-bind.sync="xxx" 目前没有抛出编译时错误,尽管它可能应该抛出。
在组件上
<MyComponent v-model="xxx" /><!-- would be shorthand for: --><MyComponent:model-value="xxx"@update:model-value="newValue => { xxx = newValue }"/>
<MyComponent v-model:aaa="xxx"/><!-- would be shorthand for: --><MyComponent:aaa="xxx"@update:aaa="newValue => { xxx = newValue }"/>
赋值 v-bind=”xxx” 的对象的传递行为
其他带参数的指令是 v-bind 和 v-on。这两个指令都使用他们无参数版本来展开一个对象,但是没有参数的 v-model 已经是简写 v-model=”xxx”,我们可以看到有几个不同的选项:
- 改变 v-model=”xxx” 来传递一个对象,强制用户写 v-model:model-value=”xxx” 的旧行为。这将使得 v-model 和 v-bind 和 v-on 更加一致,但是也会产生一个别的破坏性的变化,使最常见的用例更加冗余和负责。
- 为 v-model 添加一个新的修饰符(如 .spread)。这将减少破坏性的修改,但是与其他带参数的指令的对象传递行为不一致,有可能会造成混乱,并使框架整体感觉更复杂。
- 检测并改变原始数据的行为(如,v-model=”{…xxx}”)。这将再次减少破坏性的变化,但与其他带参数的指令行为更加一致,因为 v-bind=”{…xxx}” 会有同样的效果。我也预计这将会产生分歧,因为有些人会觉得这非常直观,而其他人会觉得使用 xxx 和使用 {…xxx} 会产生不同的行为,这是可以理解的。
- 简单地不允许 v-model 传递对象。这就避免了上述两个上述两个建议的问题,但缺点是让一些人更难迁移到 Vue3(尽管可能是少数)。Template / JSX 可能在该功能中受益,在最好的情况下,编写和维护也会变得更加繁琐,在最坏情况下,则无法使用(被迫重构到使用 createElement / h 渲染函数)。
这些都不是很好的选择,但是我可能最赞成选项 2。我也希望听到关于我可能遗漏的其他解决方案的建议。
缺点
除了任何破坏性的改变所带来的不可避免的痛苦外,我认为这种语法的痛苦相对来说是最小的 —— 部分原因是 .sync 修饰符并不是一个广泛使用的功能,同时也是用户迁移潜在的便利(见下面的采纳策略)。
备选方案
N/A
采纳策略
作为一个破坏性的修改,这只能在一个主要版本(v3)变化中引入。然而,我认为可以做一些事情来让迁移更加容易:
- 当在 v-bind 上检测到 .sync 修饰符时发出一个警告,并链接到迁移指南中的这一变化条目。
- 使用新的迁移助手,我们应该能检测并自动修复 100% 的 v-bind 与 .sync 一起使用的情况。
结合起来,即使是大量使用 .sync 的大型代码库的学习和迁移也应该只需要几分钟。
没有解决的问题
N/A
