【问题标题】:Vue.js slots - how to retrieve slot content in computed propertiesVue.js 插槽 - 如何在计算属性中检索插槽内容
【发布时间】: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 中使用这个组件。

【问题讨论】:

    标签: javascript vue.js slots


    【解决方案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有帮助

    【讨论】:

    • 你太棒了!!!现在我看到了逻辑。感谢您花时间编写答案和长代码。
    猜你喜欢
    • 2021-05-17
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2019-01-24
    相关资源
    最近更新 更多