【问题标题】:Multiple templates declared in one .vue file在一个 .vue 文件中声明多个模板
【发布时间】:2018-03-26 00:36:57
【问题描述】:

我在 .vue 文件中有一个组件,它可以从重用代码块中受益。我知道我可以将该代码移动到单独的 .vue 文件中并将其作为新组件导入。但是,此组件不会在其他任何地方使用,我想避免使目录混乱。是否可以在不使用代码内template:"<div>.....</div>" 的东西的情况下在父级中声明此组件的模板?

这就是想法:

<template>
  <div>
    ...some html here...
    <div v-for="item in items">
      {{item.name}}: 
      <div v-if="item.available">YES!</div>
      <div v-else>NO :(</div>     
    </div>    

    ...some other components and data here...

    <div v-for="item in items">
      {{item.name}}: 
      <div v-if="item.available">YES!</div>
      <div v-else>NO :(</div>
    </div>    
  </div>
</template>

我希望能够做这样的事情:

<template>
  <div>
    ...some html here...
    <div v-for="item in items">
      <itemizer inline-template v-model="item">
        {{value.name}}: 
        <div v-if="value.available">YES!</div>
        <div v-else>NO :(</div>
      </itemizer>
    </div>    

    ...some other components and data here...

    <div v-for="item in items">
      <itemizer v-model="item"/>
    </div>    
  </div>
</template>

但是,据我了解,这是不可能的。

【问题讨论】:

  • 顺便说一句,我认为您不能在 inline-template 元素上使用 v-model。
  • 我可以使用 :param="....."
  • 我认为您实际上需要将“item”作为道具传递。下面我举个例子。
  • 是的,我知道,我做这个例子只是为了速度,但这不是重点。我的问题是如何在其他地方重用内联模板的组件。

标签: vue.js vue-component


【解决方案1】:

实际上,这应该可以。只需在父 .vue 文件的部分中注册您的 Vue 内联模板:

<template>

    <div v-for="item in items">
        <test-template :item="item">
            <h1>{{item.text}}</h1>
        </test-template>
    </div>

</template>


<script>
    Vue.component('test-template', {
        template:'#hello-world-template',
        props: {
            item: Object
        }
    });

    export default {...}
</script>

在您的父 HTML 文件中,输入以下内容:

<script type="text/x-template" id="hello-world-template">
    <p>Hello hello hello</p>
</script>

【讨论】:

  • 是的,但是当我尝试在代码的其他地方使用&lt;test-template/&gt; 时,它说模板或渲染函数未定义。并且每次定义内联模板都是没有意义的,因为整个想法是重用相同的代码
  • 嗨@andrei - 实际上内联模板的优势之一是您可以使用相同的 JS 和不同的 HTML。如果你想重用 HTML,那么你就不需要内联模板。
  • 我想重用 HTML 和 JS。这可能在单个 .vue 文件中吗?
  • 是的,我认为您可以使用template 属性。我会更新我的答案。
  • 是的,但这意味着我必须在 JS 中用引号创建整个模板。而且它变得很麻烦,因为我的“子”组件几乎有 30 行,其中包含各种 v-if、v-on 和 v-bind
【解决方案2】:

不幸的是,Vue 的创建者似乎不支持这种模式:

我个人觉得语法比[Single File Components]更难维护

请注意,我们希望 SFC 语法尽可能保持一致,因为它涉及一个庞大的工具生态系统,需要支持添加的任何新功能(例如,Vetur 需要做一些非常不同的事情来处理具有多个脚本/模板的 SFC )。建议的语法 IMO 不能证明添加新语法是合理的。

https://github.com/vuejs/vue/pull/7264#issuecomment-352452213

这太糟糕了,因为即使超出了灵活性和开发人员的选择,为了降低复杂性,内联其他组件不使用的小函数也是一个很好的论据。这是 React 中的一种常见模式,并且在需要时不会禁止单个文件组件。事实上,它允许随着内联组件的增长而逐步迁移。


这是目前提供一些潜在解决方法的仅有的资源之一: https://codewithhugo.com/writing-multiple-vue-components-in-a-single-file/

我已经尝试了所有这些,但目前对其中任何一个都不满意。充其量你可以设置runtimerCompiler: true 并使用模板字符串,但它会为你的包增加10KB,你可能会错过&lt;template&gt; 元素中可用的完整语法突出显示。也许你可以破解Teleport,但我没有专门尝试。

【讨论】:

    【解决方案3】:

    vue3 有多种选择:

    1. 使用 vue-jsx,您可以在脚本设置部分声明一个组件并使用它
    const Named = defineComponent(() => {
      const count = ref(0)
      const inc = () => count.value++
    
      return () => (
        <button class="named" onClick={inc}>
          named {count.value}
        </button>
      )
    })
    
    
    1. Michael Thiessen 描述了另一个选项here

    2. 你也可以在一个文件中拥有多个渲染函数组件: https://staging.vuejs.org/guide/extras/render-function.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 2023-04-10
      • 1970-01-01
      • 2016-10-04
      • 2017-10-10
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      相关资源
      最近更新 更多