• 开始时间:2019-11-14
  • 目标主要版本:3.x
  • 引用 issue:N/A
  • 实现的 PR:N/A

摘要

删除对 inline template 功能的支持。

基本范例

N/A

动机

inline-template 最初包含在 Vue 中,以解决 Vue 被用来逐步增强传统的服务器渲染应用程序的情况(例如,与 Rails、Django 或者 Laravel)。它允许用户直接在父模版中定义子组件的模版。

inline-template 的最大问题是它使模版的范围变得非常不一致。如果没有 inline-template,一个简单的经验法则是,每个出现在模版中的变量要么由所有者组件提供,要么由明确引入的作用域变量的指令提供(例如 v-for 和 v-slot)。inline-template 通过在同一模版中混合多个作用域上下文来打破这一假设。

  1. <div>
  2. {{ parentMsg }}
  3. <child-comp inline-template>
  4. {{ parentMsg }}
  5. </child-comp>
  6. </div>

在一个期望有 slot 的标准组件中,{{ parentMag }} 会在槽的内容中直观的发挥作用。但如果使用 inline-template,情况就不一样了。同样,使用 v-for + inline-template 的组件也会像预期那样工作。

  1. <child-comp inline-template v-for="item in list">
  2. {{ item.msg }}
  3. </child-comp>

在这里,内部模版实际上无法访问循环的 item。它指向了子组件上的 this.item

具体设计

N/A

缺点

N/A

备选方案

N/A

采纳策略

替换 1:<script> 标签

inline-template 的大多数情况都是假设没有编译工具设置,所有的模块都直接写在 HTML 页面里。在这种情况下,最直接的解决方法是使用有替代类型的 <script>

  1. <script type="text/html" id="my-comp-template">
  2. <div>
  3. {{ hello }}
  4. </div>
  5. </script>

在组件中,使用选择器定位模版:

  1. const MyComp = {
  2. template: '#my-comp-template',
  3. // ...
  4. }

这不需要任何编译设置,可以在所有浏览器中使用,不受 DOM 内 HTML 解析注意事项的限制(例如,你可以使用驼峰的 props 名称),并在大多数 IDE 中提供适当的语法高亮。在传统的服务器端框架中,这些模版可以被分割成服务器模版部分(包含在主要的 HTML 模版中),以便更好的维护。

替换 2:默认插槽

以前使用 inline-template 的组件可以被重构为使用默认插槽 —— 这使得数据的作用域更加明确,同时保留了编写内联子内容的便利性:

  1. <!-- before -->
  2. <my-comp inline-template :msg="parentMsg">
  3. {{ msg }} {{ childState }}
  4. </my-comp>
  5. <!-- after -->
  6. <my-comp v-slot="{ childState }">
  7. {{ parentMsg }} {{ childState }}
  8. </my-comp>

在子组件中,现在应该渲染默认插槽(注意在 v3 中由于 fragment 的支持,你现在可以渲染一个 slot 作为根),而不是不提供模版:

  1. <!--
  2. in child template, render default slot while passing
  3. in necessary private state of child.
  4. -->
  5. <slot :childState="childState" />

没有解决的问题

N/A