vue.js 2.4.0已经发布了,提供了丰富的新功能,进行了大量的优化和问题修复。
在这篇文章中,我将给大家带来我认为最有趣的四个新特性:
- 服务器端异步组件的渲染
- 继承包装组件中的属性
- Webpack 3 异步组件的支持
- 在组件中保存HTML注释
1. 服务器端的异步组件的渲染
在Vue 2.4.0发布之前,异步组件是无法被服务器渲染的;他们在SSR(服务端渲染)输出中被忽略了,留给客户端去生成。这使得异步组件存在一个重大的缺陷,更好的修正问题正是渐进式框架Vue的优势。
异步组件
异步组件使用起来十分方便。如果你一直在关注作者的博客,最近写了很多相关内容。简而言之,就是允许你把你的应用程序代码中非必要的内容(modals,tabs,可以折叠的内容,其他页面等)在加载初始页面后再加载,从而让用户更快的看到主要页面的内容。
假设你决定异步加载以下内容,那么你的主要组件可能这样写:
<template>
<div id="app">
<!--Above-the-fold-->
<sync-component></sync-component>
<!--Below-the-fold-->
<async-component></async-component>
</div>
</template>
<script>
import SyncComponent from './SyncComponent.vue';
const AsyncComponent = import('./AsyncComponent.vue');
export default {
components: {
SyncComponent,
AsyncComponent
}
}
</script>
通过使用Webpack的动态import功能,AsyncComponent 从服务器页面载入后通过Ajax来加载完成。这样做的缺点是,当它加载时后,用户可能只看到一个下拉框或一片空白。
这可以提高服务器端的渲染友好程度,因为异步组件标记会在初始页面加载渲染出来,这比下拉框或空白给用户的体验会更好。
但直到Vue 2.4.0发布之前,这是不可能的。这个主要组件在服务端渲染的输出看起来如下所示:
<div id="app" server-rendered="true">
<!--Above-the-fold-->
<div>
Whatever sync-component renders as...
</div>
<!--Below-the-fold-->
<!---->
</div>
Vue 2.4.0以后,异步组件将被包括在服务端渲染的输出中,你可以把专注于你的应用程序代码分拆和组织,直到满意为止,而不必担心用户体验的问题。
2. 继承包装组件中的属性
Props 有一个令人讨厌的问题就是,它们只能从父组件传递给子组件。这意味着,如果您希望将数据传递到深层嵌套组件,则必须将数据绑定到每个中间组件:
<parent-component :passdown="passdown">
<child-component :passdown="passdown">
<grand-child-component :passdown="passdown">
Finally, here's where we use {{ passdown }}!
这对一个或两个Props来说并不坏,但在一个真正的项目中,你可能有很多很多的东西要传递。
当然你也可以绕过这个问题使用中央事件总线或vuex,但Vue 2.4.0提供了另一种解决方案。事实上,这是两个不同但相关的新功能:首先,使用一个定义为inheritAttrs的标识;然后通过$attrs属性就能实现这样的功能。让我们通过一个例子来看看它们是如何工作的。
示例:
我们在组件上绑定两个属性。这个组件需要属性propa为自己的传递参数,但它不需要propb;它只是传递到另外一个嵌套的组件中。
<my-component :propa="propa" :propb="propb"></my-component>
在Vue 2.4.0 之前的版本中,任何绑定属性都没有注册为props,只是作为一个普通的HTML属性。你的组件定义看起来像这样:
<template>
<div>{{ propa }}</div>
</template>
<script>
export default {
props: [ 'propa' ]
}
</script>
它会像这样渲染:
<div propb="propb">propa</div>
注意propb只是作为一个普通的HTML属性。如果你想要这个组件通过propb传递内容,你必须注册prop,即使没有直接需要它的组件:
export default {
props: [
'propa',
'propb' // Only registering this to pass it down :(
]
}
这掩盖了组件的预期功能,使组件很难再重用。在Vue 2.4.0,我们现在可以将添加一个标记:inheritattrs:false 。这时组件就不会讲b作为一个普通的HTML属性来看待,然后去做渲染:
<div>propa</div>
传递propb
propb并未消失,但它仍然可以用在组件的实例属性$attrs中(也已经在Vue 2.4.0添加)。该实例属性包含未注册为props的任何绑定属性:
<template>
<div>
{{ propa }}
<grand-child v-bind:propb="$attrs.propb"></grand-child>
</div>
</template>
<script>
export default {
props: [ 'propa' ],
inheritAttrs: false
}
</script>
想象你需要将数百个props从一个父组件的props中传递给n层嵌套组件。这样就等于允许在父组件的作用域内更简洁地声明每个中间组件模板:
<input v-bind="$attrs">
这样通过v-on绑定监听器也是完全相同的:
<div>
<input v-bind="$attrs" v-on="$listeners">
</div>
3. Webpack 3异步组件的支持
Scope hoisting是最近发布的Webpack 3 的主要功能。没有太多的细节,在Webpack1和Webpack2捆绑,模块会被打包到独立的功能闭包中。相比这个新功能Scope hoisting,之前的方法在浏览器中执行的很缓慢,而且它也会使通过最新的ES2015模块语法来开发成为可能。
两周前,Vue的vue-loader v13.0.0发布,它引入了一个变化的地方。VUE文件将作为ES模块输出,允许他们利用Scope hoisting 来提升性能优势。
不幸的是,ES模块输出语法有所不同,所以使用异步组件时必须通过一些语法,在Vue项目中进行代码调整,例如:
const Foo = () => import('./Foo.vue');
必须改成这个:
const Foo = () => import('./Foo.vue').then(m => m.default);
Vue 2.4.0在处理异步组件时可以自动解析ES模块的默认输出,而且允许使用以前的更简洁的语法。
4. 在组件中保存HTML注释
我的说,这个功能可能不太重要,但我还是觉得很酷。在Vue 2.4.0之前,注释会在组件渲染时删除:
<template>
<div>Hello <!--I'm a comment.--></div>
</template>
渲染的时候是:
<div>Hello</div>
不过有些情况下,在渲染的页面中需要注释。有些库也可能需要这样做,例如,使用注释作为占位符。
所以Vue 2.4.0开始,你可以使用注释标记指示渲染时是否保留它:
<template>
<div>Hello <!--I'm a comment.--></div>
</template>
<script>
export default {
comments: true
}
</script>
文章来自vuejsdevelopers的Anthony Gore ,它一名web开发工程师。
由汇智网的小智翻译。