为什么 Vue.js 不支持 templateURL

2015 年 10 月 28 日

一个非常常见的新 Vue 用户的问题,尤其是那些之前使用过 Angular 的用户,是“我可以使用 templateURL 吗?”。我已经回答过这个问题很多次了,我想最好写点东西来解释一下。

在 Angular 中,templateURLng-include 允许用户在运行时动态加载远程模板文件。这似乎是一个非常方便的内置功能,但是让我们重新思考一下它解决了什么问题。

首先,它允许我们将模板写入一个单独的 HTML 文件。这让我们在编辑器中获得了正确的语法高亮,这可能是许多人喜欢这样做的原因。但是,将 JavaScript 代码和模板分开真的是最好的方法吗?对于 Vue.js 组件来说,它的模板和 JavaScript 本质上是紧密耦合的 - 事实上,如果它们在同一个文件中,会更简单。在两个文件之间来回切换的上下文切换实际上会使开发体验变得更糟。从概念上讲,组件是 Vue.js 应用程序的基本构建块,而不是模板。每个 Vue.js 模板都与一个伴随的 JavaScript 上下文相耦合 - 将它们进一步分开是没有意义的。

其次,由于 templateURL 通过 Ajax 在运行时加载模板,因此您不需要构建步骤来将文件拆分。这在开发期间很方便,但在您想要将其部署到生产环境时会带来严重的成本。在 HTTP/2 普遍支持之前,HTTP 请求的数量仍然可能是应用程序初始加载性能中最关键的因素。现在想象一下,您在应用程序中的每个组件都使用 templateURL - 浏览器需要执行数十个 HTTP 请求才能显示任何内容!如果您不知道,大多数浏览器限制了它可以执行到单个服务器的并行请求数量。当您超过该限制时,应用程序的初始渲染将因浏览器必须等待的每次额外往返而受到影响。当然,有一些构建工具可以帮助您在 $templateCache 中预先注册所有这些模板 - 但这表明,对于任何严肃的前端开发来说,构建步骤实际上是不可避免的。

那么,没有 templateURL,我们如何解决开发体验问题?将模板作为内联 JavaScript 字符串编写很糟糕,使用 <script type="x/template"> 来模拟模板也感觉像是一种 hack。好吧,也许是时候升级一下,使用一个合适的模块打包器,比如 WebpackBrowserify。如果您以前从未使用过它们,这可能看起来很吓人,但相信我,跨越这一步是值得的。如果您想构建任何大型且可维护的东西,适当的模块化是必需的。更重要的是,您可以 在单个文件中编写 Vue 组件,并获得正确的语法高亮以及自定义预处理器、热重载、默认情况下使用 ES2015、自动前缀和作用域 CSS 等额外好处,这使得开发体验提高了 10 倍。

最后,Vue 允许您 延迟加载您的组件,并且使用 Webpack 非常容易。虽然这只有在您的初始包非常大,以至于您最好将其拆分时才是一个问题。

用组件思考,而不是模板。