Vue.js 2.4.0上周发布了大量新功能,修复和优化。
在这篇文章中,我将给出我认为最有趣的四个新功能的细节:
- 服务器端呈现异步组件
- 在包装器组件中继承属性
- 异步组件支持Webpack 3
- 在组件中保留HTML注释
服务器端呈现异步组件
在Vue 2.4.0之前,异步组件无法进行服务器渲染; 它们在SSR输出中被忽略,并留给客户端生成。 这给异步组件带来了显着的缺点,并且修复这个问题可以使Vue更好地实现PWAs。
异步组件
异步组件非常方便。 简单的说,它们允许您对应用程序进行代码分割,因此在初始页面加载后,非必要组件(模态,选项卡,折叠内容,其他页面等)可以加载,从而用户能更快的查看页面面内容。
假设您决定以异步方式加载折叠下面的内容。 您的主要组件可能如下所示:
<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的动态导入功能,AsyncComponent将在页面加载后由服务器加载。 不利的是,当它加载时,用户可能只会看到一个旋转或空格。
这可以通过服务器端渲染进行改进,因为异步组件标记将在初始页面加载时呈现,对于UX而言,异步组件标记将比微调框或空白区域更好。
在Vue 2.4.0之前,这是不可能的。 这个主要组件的SSR输出将如下所示:
<div id="app" server-rendered="true"> <!--Above-the-fold--> <div> Whatever sync-component renders as... </div> <!--Below-the-fold--> <!----> </div>
从Vue 2.4.0开始,异步组件将被包含在SSR输出中,因此您可以专注于Vue代码,而不用去关心用户体验。
2.在包装器组件中继承属性
关于Props
的一个令人讨厌的事情是,他们只能从父母传给孩子。 这意味着如果您有深入的嵌套组件,您需要传递数据,则必须将数据作为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
。 我们来看一个例子来看看它们是如何工作的。
Example
假如我们在一个组件上要绑定2个属性。 这个组件自身需要一个propa
属性,但它不需要propb
; 它只是将它传递给另一个嵌套组件。
<my-component :propa="propa" :propb="propb"></my-component>
在低于Vue 2.4.0的版本中,任何绑定属性没有注册为
prop
,只是作为一个普通的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
从父母传递到几层嵌套组件。 该功能将允许在父作用域内更简洁地声明每个中间组件模板:
<input v-bind="$attrs">
这样在使用
v-on
绑定监听器传递数据时也是一样的:
<div> <input v-bind="$attrs" v-on="$listeners"> </div>
3.异步组件支持Webpack 3
作用域提升是最近发布的Webpack 3的主要功能之一。没有太多的细节,在Webpack 1和2中,捆绑的模块将被包装在单独的功能闭包中。 与新的作用域提升方法相比,这些包装器功能在浏览器中执行速度很慢,这可以通过新的ES2015模块语法实现。
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中,您可以使用comments
标记来表示您要保留注释:
<template> <div>Hello <!--I'm a comment.--></div> </template> <script> export default { comments: true } </script>