【问题标题】:How to Access Component HTML output in Vue outside the template tag?如何在模板标签之外访问 Vue 中的组件 HTML 输出?
【发布时间】: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]

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component


    【解决方案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 个选项来完成你想要的:

    1. 搜索可让您以其他方式轻松使用素材图标的其他存储库;
    2. 您有权访问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: '',
    }
    
    1. 您可以在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 组件,
    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 2018-04-30
    • 2017-09-19
    • 1970-01-01
    • 2020-11-28
    • 2019-06-06
    • 2011-10-18
    • 1970-01-01
    相关资源
    最近更新 更多