有没有办法让 vue 组件的模板只包含属性的文本?

Posted

技术标签:

【中文标题】有没有办法让 vue 组件的模板只包含属性的文本?【英文标题】:Is there a way to have a vue component whose template only contains the text of a property? 【发布时间】:2020-06-23 18:10:54 【问题描述】:

有没有办法让 vue 组件的模板区域只包含纯文本?我在当前解决方案中面临的问题(使用 div 将其包裹在文本周围)是我将这些组件与其他文本片段递归连接在一行中,这通常会导致跳转到父容器的下一行,因为没有在当前片段之前的文本片段的右侧留有足够的空间。因此,文本段落应如下所示:

Lorem ipsum dolor sit amet,consectetur adipiscing elit。整数 molestie 坐amet mauris sed sollicitudin。 nibh的Curabitur non quam venenatis facilisis。 Integer vitae augue vel quam condimentum 奥特莱斯。 Mauris consequat elit vitae sollicitudin auctor。多内克 volutpat velit nulla, vitae burningerat aliquet non。毛里斯·康格 nibh eget justo sodales luctus。

结果如下:

Lorem ipsum dolor sit amet,consectetur adipiscing elit。整数 molestie sit amet mauris sed sollicitudin。

nibh venenatis facilisis 的 Curabitur non quam。 Integer vitae augue vel quam condimentum 奥特莱斯。

Mauris consequat elit vitae sollicitudin auctor。多内克 volutpat velit nulla, vitae infantum erat aliquet non.

毛里斯·康格 nibh eget justo sodales luctus。

考虑到上例中分别有5个文本片段。

这就是在模板标签中使用 cmets 实现上述组件的方式,以具体化我的问题:

<template>
  <div>element.text</div> <!--  This is how I can do it to this point-->
  element.text            <!--  This is what I would like to do-->
</template>

<script lang="ts">
import  Component, Prop, Vue  from 'vue-property-decorator'
import TextElement from '@/models/elements/Text'

@Component
export default class TextWrapper extends Vue 
  @Prop() element!: TextElement

</script>

<style scoped>
</style>

【问题讨论】:

【参考方案1】:

简单的答案是否定的,渲染函数/模板需要一个根元素。除了使用&lt;div&gt;,您还可以使用&lt;span&gt; 等内联元素或使用css 属性display: inline 设置div 的样式来解决此问题。

【讨论】:

虽然这不适用于我的用例,但它启发了我在另一个层面上使用类似的方法来解决我的问题。谢谢!【参考方案2】:

Vue 组件模板应该具有存在于 DOM 中的根元素。通常使用divspan 包装元素。这很少会成为问题,因为可以设置根元素的样式以适应布局。

vue-fragment 插件提供了 Vue 中 React.Fragment 的功能。它基本上在安装时解开根元素。由于它是一种 hack,它可能无法在所有情况下都按预期工作。

使用_v 内部方法渲染函数can be used to render text nodes。它使用未记录的 API 表明它也是一种 hack。

【讨论】:

【参考方案3】:

我通过将 css 样式属性传递给父 vue 组件的模板,使用解决方法解决了这个问题:

<template>
  <div>
    <span v-for="(line, index) in paragraph.lines" :key="index">
      <p v-if="line.length">
        <span v-for="(lineFragment, index) in line" :key="index">
          <component class="inline-component" :element="lineFragment" :is="lineFragment.type"/>
        </span>
      </p>
    </span>
  </div>
</template>

<script lang="ts">
import  Component, Prop  from 'vue-property-decorator'
import ElementHook from '@/views/ElementHook.vue'

@Component
export default class ParagraphWrapper extends ElementHook 
  @Prop() element!: ParagraphElement


</script>

<style scoped>
  .inline-component 
    display: inline;
  
</style>

ElementHook 组件作为一个基本的抽象类,它导入所有可以通过 `:is="lineFragment.type" 显示的子组件(例如 TextWrapper 组件的 'text')。

如果想要确保段落仍然环绕在父容器对象的边界周围,您可以考虑将white-space: pre-wrap; 添加到 SFC 底部定义的 css 类中。

【讨论】:

以上是关于有没有办法让 vue 组件的模板只包含属性的文本?的主要内容,如果未能解决你的问题,请参考以下文章

Vue - 用标签动态包围组件

vue: 关于多路由公用模板,导致组件内数组缓存问题

Vue_(组件)计算属性

在 Angular 中有没有办法将包含组件指令的 html 注入到父组件的模板中?

Vue3基础-模板语法

Vue常用模板语法