Vue 最黑暗的一天
译者:李润泽
链接:https://juejin.im/post/5d0f64d4f265da1b67211893(点击尾部阅读原文前往)作者:Daniel Elkington
英文原文:https://dev.to/danielelkington/vue-s-darkest-day-3fgh
译者注:原文写于2019年6月21日
今天,我惊讶的发现,往常积极友好的 VueJS 社区陷入了一场激烈的战争。两周前,Vue 的创建者尤雨溪发布了一个请求意见稿(RFC),用于在即将发布的 Vue 3.0 中使用基于函数的方式编写 Vue 组件。今天,一个 Reddit 上批评性的帖子和 Hacker News 上一些类似的批评性的评论,引起大批开发者涌向原本的 RFC 来表达他们的愤怒,其中一些有点侮辱性。在很多地方都有人声称:
所有 Vue 代码都必须以全新的方式重写,因为现有的语法正在被移除,并且被其他东西取代;
人们花在学习 Vue 上的所有时间都被浪费了,因为一切都会改变;
新语法比旧的更糟糕,因为它没有强制的结构,并且会导致意大利面条式代码;
Vue 核心团队在没有任何咨询的情况下突然施行一个巨大的破坏性的变化;
Vue 要变成 React 了!
不,Vue 要变成 AngularJS/Angular 了!
所有 HTML 都要写在一个超长的字符串里!
看过 Reddit 上成堆的负面评论,你可能会在 RFC 页面上惊讶的发现尤雨溪的 RFC 收到的正面的表情回应的比例比负面的高得多,而且许多早期评论都是相当正面的。实际上,第一条评论就充满了溢美之词。
我就是第一个写评论的人。我碰巧收到新 RFC 的通知,马上读了一下,发现这正是我想从 Vue 3.0 得到的,而且它会给我极大的帮助,于是我在 RFC 发布 15 分钟后留下了第一条评论来表达我的谢意。我希望在这里进一步说明为什么我觉得新提案是一个如此好的主意,但首先,要回应一些批评。
我怀疑很多人在阅读了 Hacker News 或 Reddit 上有着很多误导性评论的帖子之后有点激动,他们在没有阅读原始提案的情况下就表达了自己的愤怒。尤雨溪已经更新了这个提案,通过问答的方式回应了人们的很多问题,总的来说:
如果你不想重写任何代码,那么你就不需要重写——新语法是附加的,而且只要旧语法仍然被广泛使用,它在 Vue 3.0 中依然有效。就算它最终被从核心代码中移除了,也可以很容易地通过插件来使旧语法 100% 有效。
学习 Vue 的时间并没有浪费——新组件语法使用的概念与你之前花时间学习的一样,其他概念,例如单文件组件、模板、scoped style 的功用完全一样。
没有经过咨询,就不会改变—— RFC 就是在 咨询。新语法离发布还有很长一段路要走。
不,HTML 代码不需要被写进一个超长字符串。
一个更主观的观点是:新语法不如旧语法,并且会导致结构化程度较低的代码。我希望通过一个简单的例子来说明为什么我在看到 RFC 时如此兴奋,以及为什么我觉得它更优秀,将会导致结构化 更好 的代码。
考虑一下下面的有趣组件,用户可以输入宠物的详细信息。请注意:
当他们输入完宠物的名字时会显示一条信息;
另一条信息会在他们选择宠物的大小后显示。
你可以在这里尝试组件的demo,也可以在这里查看使用 Vue 2.x 编写的代码(在 components/Vue2.vue)
考虑一下这个组件的 JavaScript:
export default { data() { return { petName: "", petNameTouched: false, petSize: "", petSizeTouched: false }; }, computed: { petNameComment: function() { if (this.petNameTouched) { return "Hello " + this.petName; } return null; }, petSizeComment: function() { if (this.petSizeTouched) { switch (this.petSize) { case "Small": return "I can barely see your pet!"; case "Medium": return "Your pet is pretty average."; case "Large": return "Wow, your pet is huge!"; default: return null; } } return null; } }, methods: { onPetNameBlur: function() { this.petNameTouched = true; }, onPetSizeChange: function() { this.petSizeTouched = true; } }};
实质上,我们有一些数据、从这些数据计算出的属性、以及 操作这些数据的方法。注意,在 Vue 2.x 中我们 没有办法把相关的东西放在一起。我们不能把 petName
数据声明放在 petNameComment
计算属性或者 onPetNameBlur
方法旁边,因为在 Vue 2.x 中,这些选项是按照类型组织的。
当然,对于像这样的小例子来说,这不太重要。但是想象一个更大的例子,它有很多功能,需要 data
、 computed
、 methods
、甚至是一两个 watcher
。目前还 没有好方法 来把相关的东西放一起!有人可能会使用诸如 Mixin 或高阶组件之类的办法,但是它们都有问题——很难辨别一个属性来自哪里,还有命名空间的冲突。(是的,在这种情况下,拆分为多个组件是可能的,但是这个类似的例子就不行)
新提案不是按照选项的类型来组织组件,而是允许我们按照实际功能来组织组件。这类似于你在电脑上整理个人文件的方式——你通常没有“表格”文件夹和“Word 文档”文件夹,相反,你可能有一个”工作“文件夹和一个”假期计划“文件夹。想象一下使用提案里的语法来编写组件(尽我所能,如果你看到了什么 bug 请告诉我):
import { state, computed } from "vue";export default { setup() { // Pet name const petNameState = state({ name: "", touched: false }); const petNameComment = computed(() => { if (petNameState.touched) { return "Hello " + petNameState.name; } return null; }); const onPetNameBlur = () => { petNameState.touched = true; }; // Pet size const petSizeState = state({ size: "", touched: false }); const petSizeComment = computed(() => { if (petSizeState.touched) { switch (this.petSize) { case "Small": return "I can barely see your pet!"; case "Medium": return "Your pet is pretty average."; case "Large": return "Wow, your pet is huge!"; default: return null; } } return null; }); const onPetSizeChange = () => { petSizeState.touched = true; }; // All properties we can bind to in our template return { petName: petNameState.name, petNameComment, onPetNameBlur, petSize: petSizeState.size, petSizeComment, onPetSizeChange }; }};
注意:
很容易把相关的东西放到一起;
通过查看 setup 函数的返回值,我们可以很容易地知道模板中可以获取什么变量;
我们甚至可以避免暴露模板不需要获取的内部状态(touched)。
除此之外,新语法可以有完整的 Typescript 支持,这在 Vue 2.x 基于对象的语法中很难实现。而且我们可以很轻易地把可重用的逻辑提取为可重用的函数。例如:
import { state, computed } from "vue";function usePetName() { const petNameState = state({ name: "", touched: false }); const petNameComment = computed(() => { if (petNameState.touched) { return "Hello " + petNameState.name; } return null; }); const onPetNameBlur = () => { petNameState.touched = true; }; return { petName: petNameState.name, petNameComment, onPetNameBlur };}function usePetSize() { const petSizeState = state({ size: "", touched: false }); const petSizeComment = computed(() => { if (petSizeState.touched) { switch (this.petSize) { case "Small": return "I can barely see your pet!"; case "Medium": return "Your pet is pretty average."; case "Large": return "Wow, your pet is huge!"; default: return null; } } return null; }); const onPetSizeChange = () => { petSizeState.touched = true; }; return { petSize: petSizeState.size, petSizeComment, onPetSizeChange };}export default { setup() { const { petName, petNameComment, onPetNameBlur } = usePetName(); const { petSize, petSizeComment, onPetSizeChange } = usePetSize(); return { petName, petNameComment, onPetNameBlur, petSize, petSizeComment, onPetSizeChange }; }};
在 Vue 2.x 中,我经常发现自己写了个“怪兽组件”,它很难分解成更小的部分——它不能分解成其他的组件,因为很多事务基于少量状态。然而,使用提案中的语法,很容易看出大型组件的逻辑可以被分解为更小的可重用部分,在必要时移动到独立的文件里,留给你小的、易于理解的函数和组件。
这是目前为止 Vue 最黑暗的一天吗?看起来是的。一直团结追随这个项目方向的社区已经分裂了。但我希望人们能够重新审视这个提案,它没有破坏任何东西,只要他们想,仍然可以按照选项的类型来组织它们,但是可以做到更多——更清晰的代码、更简洁的代码、更有意思的库、还有完善的 Typescript 支持。
最后,在使用开源软件时,最好记住,全靠维护者投入的大量精力,你才可以免费使用它。今天的一些过分批评是他们不应该承受的。好在这些无礼的批评只是少数(尽管数量相当多),大多数人能以更礼貌的方式表达自己。
2019年6月23日更新:
我很快就写好了原文,并没有期望它能得到这样的关注。然后我意识到这个代码示例对于我想要表达的观点来说过于复杂,所以我把它简化了很多。原本的代码示例在这里。
Vue 最黑暗的一天相关推荐
- Vue3.0 凉凉了?Vue 最黑暗的一天!
点击"开发者技术前线",选择"星标????" 在看|星标|留言, 真爱 原来链接:https://dev.to/danielelkington/vue-s-d ...
- Vue3.0 难产?Vue 最黑暗的一天
文/北妈 阅读本文需要 2.6分钟 一 这篇文原文是一个老外的vue爱好者写的,原文写于2019年6月21日,有同学把他翻译出来了,北妈觉得很不错,从原因到过程都有介绍,还有2.0和3.0的写法对比. ...
- Vue3.0 凉了?Vue 最黑暗的一天
点击"开发者技术前线",选择"星标?" 在看|星标|留言, 真爱 vue3.0从去年放出消息很长时间了,至今还没正式发布,也可能大大和社区正在调查取舍,前端日 ...
- 爱奇艺动态化框架 Qigsaw 正式开源!
点击"开发者技术前线",选择"星标?" 13:21 在看|星标|留言, 真爱 作者 | 陈家伟 编辑 | 可可 跨平台成了今年前端的热门话题,各大公司发布自己 ...
- if 我是前端团队 Leader,怎么制定前端协作规范?
点击上方 "程序员小乐"关注, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 Nothing in this world no wounds people ...
- React Native 与 Flutter ,一场跨平台世纪之战!
点击"开发者技术前线",选择"星标?" 13:21 在看|星标|留言, 真爱 作者 | Paresh Sagarg 译者 | 苏本如 谷歌和 Facebo ...
- 产品、测试…...我信你个鬼,你们坏得很!
文/北妈 阅读本文需要 1.3分钟 一通过漫画这种有趣的表现形式,来表达和讽刺一些喜闻乐见的现象,一直是北妈的一个小愿望,因为有趣.易传播,而很形象,但原创很复杂,也需要积累素材和灵感. 今天我先从好 ...
- Vue2要不要升级到Vue3?(尤雨溪回复解读)
作者:掘金干货君 https://juejin.cn/post/7117525259212816414 就在前两天,一篇反对Vue2升级到Vue3的文章在vue官方社区引起了热议.(原文链接:Vue ...
- 模仿CSDN黑暗帝国动态背景的vue项目(附源码)
开发工具:Webstorm 技术栈:vue.html.canvas 实现效果(其实这里面的是动态变换的,只是没有截成GIF动图): 实现步骤: (1)在这里的项目我是用VueCli3脚手架进行搭建的. ...
- Vue的自定义滚动,我用el-scrollbar
弄了一个持续更新的github笔记,可以去看看,诚意之作(本来就是写给自己看的--)链接地址:Front-End-Basics 此篇文章的地址:Vue的自定义滚动,我用el-scrollbar 基础笔 ...
最新文章
- 从汉诺塔讲递归的思考方式
- 算法题26 复杂链表的复制
- 【爬虫】Scrapy爬取腾讯社招信息
- postgresql兴建用户_PostgreSQL 12.2, 11.7, 10.12, 9.6.17, 9.5.21, 和 9.
- hbase集群 数据写入_HBase神器 | BDSHBase集群之间数据迁移同步的利器
- 百家姓 —— 特别的姓氏与姓氏的由来
- JS 字符串全部替换 ,replace (/ /g,'')
- 计算机考研复试问题回答,关于考研复试问题的官方解答及部分问题答题模板!...
- 海康SDK/Ehome协议/RTSP协议/GB28181安防视频云服务EasyCVR前端音频采集流程介绍
- 工程测量(平面高程控制网)
- 信捷用c语言编写梯形图,PLC一键启停编程梯形图实例
- 记录:关于Win10系统中Microsoft Edge上的网页如何滚动截屏?
- 经典的排错过程 expected unqualified-id before string constant
- CocosCreator之微信小游戏的聊天/提示气泡制作
- dedecms教程:织梦搬家错位,链接不上数据库
- keil中创建lib库,使用lib库
- java SNS网络系统_JEESNS-JAVA开源SNS社交管理系统
- 第三方软件测试(软件检测)收费标准
- 光立方原理讲解_基于杠杆平衡的防汛挡水板设计原理分析
- VR工厂:助力工厂数字化升级
热门文章
- 联想Y450 GT130M显卡 使用NVIDIA公版驱动(安装成功)
- 联想Y7000安装ubuntu1604 双系统
- linux 关闭后台程序
- 博饼游戏c语言,2015中秋博饼游戏规则
- 7.详解第三代移动通信系统——WCDMA、TD-SCDMA、CDMA2000
- openssl密码套件详解
- NSIS 简易教程(四)
- kindle看pdf不清楚_不要再纠结pdf在kindle上的显示问题了,简单教程,拿去!不要太谢我。...
- 【Android 学习记录】:针对Android 7.0 抓不到HTTPS包的情况
- 体检管理软件#一站式体检管理系统#体检管理软件#体检软件#体检系统#体检管理系统源码