如何在模板标签之外访问 Vue 中的组件 HTML 输出?

Posted

技术标签:

【中文标题】如何在模板标签之外访问 Vue 中的组件 HTML 输出?【英文标题】:How to Access Component HTML output in Vue outside the template tag? 【发布时间】:2020-07-29 18:29:49 【问题描述】:

我知道我们可以简单地在模板中显示带有<ComponentName/>的组件输出,

但是我们如何在datamethodsmounted 期间访问模板外部的ComponentName html 输出

例如components/Test.vue

<template>
    <div>I'm a test</div>
</template>

在另一个 vue 文件中pages/ViewTest.vue

import Test from '~/components/Test.vue'
export default 
    components: Test,
    data() 
        return 
            test: Test
        
    ,
    mounted: function()  
      console.log( Test ) // Output is Test Component Object
      console.log( this.test ) // Output is Test Component Object
    

控制台日志输出的对象似乎包含很多信息,我什至可以从该对象中看到 render 属性,尽管当我尝试 console.log( Test.render() ) 时它给了我错误

所以我的问题是如何从模板外部获取&lt;div&gt;I'm a test&lt;/div&gt;

感谢任何帮助或指导

编辑

我正在使用vue-material-design-icons 包来生成不同的 svg 图标,

我可以像下面这样使用它

<template>
  <MapMarkerRadius/>
</template>
<script>
  import MapMarkerRadius from 'vue-material-design-icons/MapMarkerRadius'
  export default 
    components: MapMarkerRadius
  
</script>

现在这是我的主要问题, 我有这个生成 html 的组件

<template>
  <div :class="'card'">
    <div v-if="title" :class="'card-title'">
       title 
    </div> 
    <div :class="'card-content'">
      <slot />
    </div>
  </div>
</template>
<script>
export default 
  name: 'card',
  props: 
    title: ,
  
;
</script>

然后我在另一个 vue 文件上使用像这样的 card 组件

<template>
  <card :title="'Title ' + MapMarkerRadius">
    Test Content
  </card>
</template>

<script>
import card from '~/components/Card'
import MapMarkerRadius from 'vue-material-design-icons/MapMarkerRadius'
export default 
  components: card, MapMarkerRadius
;
</script>

我的问题是card title 的输出是Title [object]

【问题讨论】:

【参考方案1】:

尝试在Test 组件的根目录中使用ref,例如:

<template>
  <div ref="test">I'm a test</div>
</template>

在其他组件中做:

   mounted: function()  
      console.log( this.$refs.test )
    

无需导入组件

【讨论】:

感谢您的回答,但是不使用ref就没有别的办法了吗?我试图访问的组件来自外部包。所以我不能真正修改组件并添加ref标签 我认为没有办法,但你可以在模板中引用它,如&lt;Test ref="test"&gt;&lt;/Test&gt;,但你的具体用例是什么? 我已经更新了我的问题,你能再看看它是否有意义吗?非常感谢您的帮助:) 好的,让我分析一下你的用例 你对` `有什么期望?组件名称还是 html 内容?【参考方案2】:

您使用的 repo 是通过单个标签生成 html 的单文件组件,因此使用

import MapMarkerRadius from 'vue-material-design-icons/MapMarkerRadius'

将使您能够在模板中使用它作为&lt;map-marker-radius/&gt;

这就是为什么附加字符串标题和像"My Icon"+MapMarkerRadius 这样的对象将返回文字[object],正如您所见:"My Icon [object]"

你有 3 个选项来完成你想要的:

    搜索可让您以其他方式轻松使用素材图标的其他存储库; 您有权访问card 组件?您可以使用此 repo 的类名而不是 svg 版本或组件本身:https://github.com/robcresswell/vue-material-design-icons/issues/12,将类名添加到 props 并将其添加到您的组件中:
<card :title="'Title'" :icon_class="map-marker-radius">
    Test Content
</card>
<div v-if="title" :class="'card-title'">
       title  <div :class="icon_class"></div>
</div>
props: 
    title: ,
    icon_class: '',

    您可以在card 组件中直接使用MapMarkerRadius 组件,但仅在您通过card 组件的特定条件时才会出现,例如:

ma​​in.vue

<template>
  <card :title="'Title'" :icon="true" :icon_typename="'map-marker-radius'">
    Test Content
  </card>
</template>

<script>
import card from '~/components/Card'
export default 
  components: card
;
</script>

使用icon_typename 作为您想使用的任何名称/关键字。

card.vue

<template>
  <div :class="'card'">
    <div v-if="title" :class="'card-title'">
       title  <span v-if="icon_mmr"><map-marker-radius/></span>
    </div> 
    <div :class="'card-content'">
      <slot />
    </div>
  </div>
</template>
<script>
import MapMarkerRadius from 'vue-material-design-icons/MapMarkerRadius'
export default 
  name: 'card',
  props: 
    title: ,
    icon:  default: false ,
    icon_typename: '',
    icon_mmr: false,
  ,
  mounted()
    if (this.icon && this.icon_typename === 'map-marker-radius') this.icon_mmr = true
,
  components:  MapMarkerRadius ,
;
</script>

代码远非完美,但您可以从那里进一步优化。

【讨论】:

我选择使用基于组件的图标的主要原因是为了优化,您知道如果您将所有图标加载到您的应用程序中,图标库会如此繁重,甚至只是 js 文件fontawesome 版本 5 的大小约为 1MB,如果您只需要 5 到 10 个图标,则加载 1MB 文件是不公平的 如果标题上需要一个图标,我最终不会使用card 组件,

以上是关于如何在模板标签之外访问 Vue 中的组件 HTML 输出?的主要内容,如果未能解决你的问题,请参考以下文章

Vue2.0的字符串模板、html模板、组件、slot

vue单个组件命名标签无法引用

HTML 5一篇就够

vue中,组件怎么做到按需加载呢

如何将 HTML 模板导入 Vue.js 项目?

如何使用VUE给模板标签中的属性赋值