Vue.js 插槽 - 如何在计算属性中检索插槽内容

Posted

技术标签:

【中文标题】Vue.js 插槽 - 如何在计算属性中检索插槽内容【英文标题】:Vue.js slots - how to retrieve slot content in computed properties 【发布时间】:2021-02-27 03:21:43 【问题描述】:

vue.js slots 有问题。一方面,我需要显示插槽代码。另一方面,我需要在 textarea 中使用它来将其发送到外部源。

ma​​in.vue

<template>
  <div class="main">

    <my-code>
      <template v-slot:css-code>
        #custom-css 
          width: 300px
          height: 200px;
        
      </template>
      <template v-slot:html-code>
        <ul id="custom-css">
          <li> aaa </li>
          <li> bbb </li>
          <li> ccc </li>
        </ul>
      </template>
    </my-code>

  </div>
</template>

my-code.vue

<template>
    <div class="my-code">

        <!-- display the code -->
        <component :is="'style'" :name="codeId"><slot name="css-code"></slot></component>
        <slot name="html-code"></slot>

        <!-- send the code -->
        <form method="post" action="https://my-external-service.com/">
            <textarea name="html">theHTML</textarea>
            <textarea name="css">theCSS</textarea>
            <input type="submit">
        </form>

    </div>
</template>

<script>
export default 
    name: 'myCode',
    props: 
        codeId: String,
    ,
    computed: 
        theHTML() 
            return this.$slots['html-code']; /* The problem is here, it returns vNodes. */
        ,
        theCSS() 
            return this.$slots['css-code'][0].text;
        ,
    

</script>

问题在于 vue 不会转槽内容。它是&lt;VNode&gt; 元素的数组。有没有办法在textarea 中使用插槽。或者一种在 theHTML() 计算属性中检索槽内容的方法。

注意:我在 vuePress 中使用这个组件。

【问题讨论】:

【参考方案1】:

您需要创建一个自定义组件或自定义函数来将 VNode 直接渲染为 html。我认为这将是最简单的解决方案。

vnode 到 html.vue

<script>
export default 
  props: ["vnode"],
  render(createElement) 
    return createElement("template", [this.vnode]);
  ,
  mounted() 
    this.$emit(
      "html",
      [...this.$el.childNodes].map((n) => n.outerHTML).join("\n")
    );
  ,
;
</script>

然后你就可以在你的组件中使用它了

template>
  <div class="my-code">
    <!-- display the code -->
    <component :is="'style'" :name="codeId"
      ><slot name="css-code"></slot
    ></component>
    <slot name="html-code"></slot>

    <!-- send the code -->

    <Vnode :vnode="theHTML" @html="html = $event" />

    <form method="post" action="https://my-external-service.com/">
      <textarea name="html" v-model="html"></textarea>
      <textarea name="css" v-model="theCSS"></textarea>
      <input type="submit" />
    </form>
  </div>
</template>

<script>
import Vnode from "./vnode-to-html";
export default 
  name: "myCode",
  components: 
    Vnode,
  ,
  props: 
    codeId: String,
  ,
  data() 
    return 
      html: "", // add this property to get the plain HTML
    ;
  ,
  computed: 
    theHTML() 
      return this.$slots[
        "html-code"
      ]
    ,
    theCSS() 
      return this.$slots["css-code"][0].text;
    ,
  ,
;
</script>

这个帖子可能对How to pass html template as props to Vue component有帮助

【讨论】:

你太棒了!!!现在我看到了逻辑。感谢您花时间编写答案和长代码。

以上是关于Vue.js 插槽 - 如何在计算属性中检索插槽内容的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 如何在插槽上使用属性

Vue.js(17)之 插槽

将图像源传递到 Vue.js 中的作用域插槽

vue.js-使用插槽分发内容的三个示例

使用渲染功能时如何在 Vue.js 模板中定义插槽?

如何在 Vue.js 插槽中使用条件渲染?