【整理】Vue 2.0 自 beta 1 到 beta 4 以来的主要更新

主要内容来自 https://github.com/vuejs/vue/releases

之前 Vue 2.0 发布技术预览版 到现在差不多三个月了,之前写过一篇简单的 code review,如今三个月过去了,Vue 2.0 在这个基础之上又带来了不少更新,这里汇总 beta 以来 (最新的版本是 beta 4) 的主要更新,大家随意学习感受一下

alpha 和 beta 版本的侧重点会有所不同

首先 Vue 2.0 对 alpha、beta 有自己的理解和设定:alpha 版本旨在完善 API、考虑所需的特性;而来到 beta 版则会对未来的正式发布进行充分的“消化”,比如提前进行一些必要的 breaking change,增强框架的稳定性、完善文档和周边工具 (如 vue-router 2.0 等)

最后的几个 alpha 版本主要更新

Vue 本身的语法基础这里就不多赘述了,网上有很多资料可以查阅,我们已经假定你比较熟悉 Vue 并对 2.0 的理念和技术预览版的状态有一定的了解。

alpha 5

  1. ref 的写法由 <comp v-ref:foo> 变成了 <comp ref="foo">,更加简单,同时动态数据的写法是 <comp :ref="x">
  2. 支持 functional components,这个特性蛮酷的,可以把一个组件的生成过程完全变成一个高度自定义的函数执行过程,比如:

    Vue.component('name', { functional: true, props: ['x'], render: (h, props, children) { return h(props.tag, null, children) } })

你可以在 render() 函数里写各种特殊的逻辑,这样标签的含义和能力都得到了非常大的扩展,在后续的几次更新中,你马上会感受到一些 functional components 的威力

另外剧透一下,h 方法里的第二个参数如果是 null 就可以省略,这个改动出现在了 beta 1

alpha 6

可以设置特殊的 keyCode,比如 Vue.config.keyCodes.a = 65,然后你就可以写 <input @keyup.a="aPressed">

alpha7

  1. 一个组件的生命周期名由 init 改成了 beforeCreated (大家可以在 Vuex 的源码里看到对应的改变哦)
  2. Vue.transition 的 hook 支持第二个参数,把 vm 传递进去

如:

Vue.transition('name', {
    onEnter (el, vm) {
        ...
    }
})

Beta 1 ~ Beta 4

beta 1

  1. 自定义 directive 里 update 的触发时机发生了变化,由于 functional component 等概念的引入,一个 directive 的变更的颗粒度也不完全是 directive 本身引起的,所以这里做了一个更具有通用性的调整;同时 hook 名 postupdate 也相应的更名为 componentUpdated——如果你想让 update 保持原有的触发时机,可以加入一句 binding.value !== binding.oldValue 即可。
  2. Vue.traisition 的 hook 名做了简化
    • onEnter -> enter
    • onLeave -> leave
  3. server-side rendering
    • server.getCacheKey 更名为 serverCacheKey,避免多一层结构嵌套
    • createRenderer/createBundleRenderer 方法不会强制应用 lru-cache,而是开发者手动选择

beta 2

<transition> 标签来了!

其实这个玩意儿我之前在 polymer 等其他框架里也见到过,不过看到 Vue 的语法设计,还是觉得巧妙而简洁:

<transition>
    <div v-if="...">...</div>
</traisition>

<transition-group tag="ul">
    <li v-for="...">...</li>
</traisition-group>

更牛掰的在这里,还记得 functional components 吧,你今天可以这样抽象一个动画效果的标签:

Vue.component('fade', {
    functional: true,
    render (h, children) {
        return h('transition', {
            props: {...},
            on: {
                beforeEnter,
                afterEnter
            }
        }, children)
    }
})

然后

<fade>...</fade>

就可以实现高度自定义的动画效果了,这个我个人觉得是非常赞的设计和实现!

beta 3

  1. 支持在自定义组件中使用原生事件。因为在 Vue 2.0 的设计中,自定义组件上是不能绑定原生事件的,自定义组件上的时间绑定被默认理解为组件的自定义事件,而不是原生事件。针对这个问题我很早就提了 issue 当时小右提出了一个新的语法设计,就是 <comp @click.native="..."></comp>,beta 3 的时候终于看到它被实现了,嘿嘿,有点小激动
  2. 支持两种语法 <div :xxx.prop="x"><div v-bind:prop="{ xxx: x }"> 来对 DOM 的 property 进行绑定,最近我自己也在思考一些在 virtual-DOM 上支持 properties 而不只是 attributes 的想法,这个设计让我也多了一些新的思路。

beta 4

2 天前发布的,其实这个版本以 bugfix 为主

总结

以上是近期 Vue 2.0 的一些更新,让我自己比较兴奋的主要是 functional component 以及基于这个设计的 <transition><transition-group> 标签和自定义 transition 标签的能力拓展,还有就是久违的 <comp @click.native="..."></comp>

最后希望大家可以多多试用,有更大兴趣的可以多多学习 Vue 的源码!

通过一张图走进 Vue 2.0

这可能是字最少的一篇了,都在图里 - -

文字介绍稍后抽空再补补

Code Review for Vue 2.0 Preview

是的!Vue 2.0 发布了! 源代码仓库在此

首先,当我第一次看到 Vue 2.0 的真面目的时候,我的内心是非常激动的

Demo

来个简单的 demo,首先把 dist/vue.js 导入到一个空白的网页里,然后写:

当然,在大家阅读下面所有的内容之前,先想象一下,这是一个运行时 min+gzip 后只有 12kb 大小的库

<script src="./dist/vue.js"></script>

<div id="app">
  Hello {{who}}
</div>
<script>
  new Vue({
    el: '#app',
    data: {who: 'Vue'}
  })
</script>

你将看到 "Hello Vue"

然后再看一个神奇的:

<script src="./dist/vue.js"></script>

<div id="app"></div>
<script>
  new Vue({
    el: '#app',
    render: function () {
      with (this) {
        __h__('div',
          {staticAttrs:{"id":"app"}},
          [("\n  Hello "+__toString__(who)+"\n")],
          ''
        )
      }
    }
    data: {who: 'Vue'}
  })
</script>

这个是 compile 过后的格式,大家会发现首先 #app 下不需要写模板了,然后 <script> 里多了一个 render 字段,Vue 在运行时其实是会把模板内容先转换成渲染方法存入 render 字段,然后再执行,如果发现 render 已经存在,就跳过模板解析过程直接渲染。所以在 Vue 2.0 中写一段模板和写一个 render option 是等价的。为什么要这样设计,稍后会我们会涉及到。

阅读剩余部分...

Vue 2.0 发布啦!

原文:https://medium.com/the-vue-point/announcing-vue-js-2-0-8af1bde7ab9#.cyoou0ivk

今天我们非常激动的首发 Vue 2.0 preview 版本,这个版本带来了很多激动人心的改进和新特性。我们来看看这里面都有些什么!

更轻,更快

Vue.js 始终聚焦在轻量和快速上面,而 2.0 把它做得更好。现在的渲染层基于一个轻量级的 virtual-DOM 实现,在大多数场景下初试化渲染速度和内存消耗都提升了 2~4 倍 (详见这里的 benchmarks)。从模板到 virtuel-DOM 的编译器和运行时是可以独立开来的,所以你可以将模板预编译并只通过 Vue 的运行时让你的应用工作起来,而这份运行时的代码 min+gzip 之后只有不到 12kb (提一下,React 15 在 min+gzip 之后的大小是 44kb)。编译器同样可以在浏览器中工作,也就是说你也可以写一段 script 标签然后开始你的工作,就像以前一样。而即便你把编译器加进去,build 出来的文件 min+gzip 之后也仅有 17kb,仍然小于目前的 1.0 版本。

不是普通的 Virtual-DOM

现在 virtual-DOM 有点让人听腻了,因为社区里有太多种实现,但是 Vue 2.0 的实现有与众不同的地方。和 Vue 的响应式系统结合在一起之后,它可以让你不必做任何事就获得完全优化的重渲染。由于每个组件都会在渲染时追踪其响应依赖,所以系统精确地知道应该何时重渲染、应该重渲染哪些组件。不需要 shouldComponentUpdate,也不需要 immutable 数据 - it just works.

除此之外,Vue 2.0 从模板到 virtuel-DOM 的编译阶段使用了一些高阶优化:

  1. 它会检测出静态的 class 名和 attributes 这样它们在初始化渲染之后就永远都不会再被比对。

  2. 它会检测出最大静态子树 (就是不需要动态性的子树) 并且从渲染函数中萃取出来。这样在每次重渲染的时候,它就会直接重用完全相同的 virtual nodes 同时跳过比对。

这些高阶优化通常只会在使用 JSX 时通过 Babel plugin 来做,但是 Vue 2.0 即使在使用浏览器内的编译器时也能做到。

新的渲染系统同时允许你通过简单的冻结数据来禁用响应式转换,配以手动的强制更新,这意味着你对于重渲染的流程实际上有着完全的控制权。

以上这些技术组合在一起,确保了 Vue 2.0 在每一个场景下都能够拥有高性能的表现,同时把开发者的负担和成本降到了最低。

Templates, JSX, or Hyperscript?

开发者对于用模板还是 JSX 有很多的争执。一方面,模板更接近 HTML - 它能更好地反映你的 app 的语义结构,并且易于思考视觉上的设计、布局和样式。另一方面,模板作为一个 DSL 也有它的局限性 - 相比之下 JSX/hyperscript 的程序本质使得它们具有图灵完备的表达能力。

作为一个兼顾设计和开发的人,我喜欢用模板来写大部分的界面,但在某些情况下我也希望能拥有 JSX/hyperscript 的灵活性。举例来说,当你想在一个组件中程序化的处理其子元素时,基于模板的 slot 机制会显得比较有局限性。

那么,为什么不能同时拥有它们呢?在 Vue 2.0 中,你可以继续使用熟悉的模板语法,但当你觉得受限制的时候,你也可以直接写底层的 virtual-DOM 代码,只需用一个 render 函数替换掉 template 选项。你甚至可以直接在你的模板里使用一个特殊的 <render> 标签来嵌入渲染函数!一个框架,两全其美。

流式服务端渲染

既然迁移到了 virtual-DOM,Vue 2.0 自然支持服务端渲染和客户端的 hydration(直接使用服务端渲染的 DOM 元素)。当前服务端渲染的实现有一个痛点,比如在 React 里,渲染是同步的,所以如果这个 app 比较复杂的话它会阻塞服务器的 event loop。同步的服务端渲染在优化不当的情况下甚至会对客户端获得内容的速度带来负面影响。Vue 2.0 提供了内建的流式服务端渲染 - 在渲染组件时返回一个可读的 stream,然后直接 pipe 到 HTTP response。流式渲染能够确保服务端的响应度,也能让用户更快地获得渲染内容。

解锁更多可能性

基于新的架构,我们还有更多的可能性有待开发 - 比如在手机端渲染到 native 界面。目前我们正在探索一个 Vue.js 2.0 的端,它会用 weex:一个由中国最大科技公司之一的阿里巴巴的工程师们维护的项目,作为一个 native 的渲染层。同时从技术角度 Vue 2.0 运行在 ReactNative 上也是可行的。让我们拭目以待!

兼容性以及接下来的计划

Vue.js 2.0 仍然处在 pre-alpha 阶段,但是你可以来这里 查看源代码。尽管 2.0 是一个完全重写的项目,但是除了一些有意废弃掉的功能,API 和 1.0 是大部分兼容的。看看 2.0 中一模一样的官方例子 - 你会发现几乎没有什么变化!

对于部分功能的废弃,本质上是为了提供更简洁的 API 从而提高开发者的效率。你可以移步这里 查看 1.0 和 2.0 的特性比对。如果你在现有的项目中大量地使用着一些被废弃的特性,这意味着会有一定的迁移成本,不过我们在未来会提供更详实的升级指导。

现在我们还有很多工作没有完成。一旦我们达到了令人满意的测试覆盖率,我们将会推出 alpha 版本,同时我们希望能在五月底六月初推出 beta 版。除了更多的测试之外,我们也需要更新相关库(如 vue-router, Vuex, vue-loader, vueify...)的支持。目前只有 Vuex 在 2.0 下可以直接使用,但是我们会确保在 2.0 正式发布时所有东西都会顺畅地工作。

我们不会因此而忘记 1.x 哦!1.1 将会和 2.0 beta 独立发布,提供六个月 critical bug fixes 和九个月安全升级的长效服务 (LTS)。同时 1.1 还会包含可选的废弃特性警告,让你为升级到 2.0 做好充足的准备。尽请期待!

务实的小而美

随意分享几则自己近期的感悟

人不够?

我自己发现周围的同学越来越把一句话挂在嘴边,那就是:我们就这么些人,想搞定这件事情是远远不够的

说白了,大家觉得“人多好办事”,“规模”这个词很多情况下几乎就是个褒义词。

但是今天有些变化正在悄然发生,比如人类的学习能力越来越强,同时信息技术越来越发达,学习新知识的门槛越来越低,比如各技术领域的成熟度越来越高,比如移动时代前所未有的技术挑战,在有限的硬件性能和网络带宽的情况下,越是“规模”的东西越难以维持;比如体力和知识都逐渐远离核心竞争优势等等

拥抱社区,“我们有更多人”

一件事搞得起来搞不起来,逐渐不取决于我们的团队有多少人,而取决于我们有没有让这件事情发生在最广阔的舞台上,因为一个技术团队再多人,哪怕一百多人,相比起任何一个知名技术社区都是九牛一毛,而一个集团、一个国家、一门语言的社区,相比起全球的互联网社区,也都是渺小的。所以今天,我们想在技术上成就一件事,未必需要很大的团队,未必需要很多人在身边

同时,我们也不能小看个体在科技发展中所起到的关键作用。技术的不断融合和碰撞也加速了这件事情。所以更重要的不是团队有多少人,而是团队有没有能够真正起到关键作用的个体,找到对的人,比组建一支上百人的团队要重要得多

从社区汲取最好的技术

我敢说,抛开具有真正技术驱动力的公司,绝大多数公司的技术工作都能够在社区找到现成并且适合的方案,也都不太需要最高精简的科研探索。一个务实的技术方案,一定是在大量的社区成熟技术基础上建立起来的,再加上一点点针对自身业务独特性的技术实践。不过看上去“没什么自己的东西”罢了,如果大家很介意这东西“得是我自己的”,那么你需要继续考虑这个问题:自己搞出来的东西能不能比今天社区的更好,能不能发展成更好的社区,是否可以在社区中的深度参与从而把“别人的”变成“自己的”

在社区中施展+检验自己的技术

然而社区不应该只有索取,还应该有奉献,如果你发现有件事情是别人也会再次遇到的那种事情,但社区没有合适现成的东西,那么恭喜你,赶紧开工吧

有的时候觉得社区化的技术发展也有它残酷的一面,同类的方案或工具库基本上也就全球数一数二的几个能生存下来,并且体现出可观的价值,稍微差一点的,也许绝对实力没有差很多,但只要不是第一,所产生的价值和影响力就少得可怜了。所以想掂量掂量自己,看看是不是这块料,不妨放到社区里跟大家一起来一场真正的PK吧!也别自己憋着,别觉得“等我弄得再完善一点再给你们看”,因为在社区化的技术发展中,这样做只会让自己越来越没有价值和勇气把它拿出来了。当然也不必贪多,哪怕是一个小小的功能,如果做到最好,能够被全球的开发者使用,那也是极好的

合理的把技术运用在工作中

我们在工作中逐渐对人的评价,会由评价其绝对的技术实力,转向评价其运用各方面技术解决实际问题的能力。这两者之间有一个比较形象的比喻,就好比我们学生时期背单词,拿出任何一个单词来,都能立刻说出它的含义、发音、常用短语、同义词、反义词、各种形态,但面对具体的对话场景不知道该用哪个词最合适最得体,这是比较典型的一种现象。其实前者就像是一个人的技术实力,后者就像是一个人的解决实际问题的能力。所以新知识新技术不光要学,还要学以致用,如何合理运用技术解决实际问题才是我们真正希望看到的。

把工作中的必经之路和常见任务萃取出来沉淀为最佳实践

现在回到“小而美的务实方案”这件事情上。我们认为看上去很重要、工作量很大、需要很多人来做的工作,是可以充分拥抱社区,汲取最好的技术,同时发挥关键角色的关键作用,并把技术合理运用在实际需求上。整件事情的成败有很多因素,但是“规模”这个因素显然不在考前的位置了

基于这样的思考,我觉得,自己喜欢的团队,是一个小而美的团队