我在下面简化了一个 Vue 组件。

这是模板

<template>
    <slot></slot>
</template>

slot 可能包含 HTML,这就是为什么我决定使用 slot 而不是我将简单绑定(bind)到的 prop。我想保持这种状态。

我有一种从服务器获取新 HTML 的方法。我想使用这个新的 HTML 来更新插槽。我不确定插槽是否具有反应性以及如何实现这一点。

我可以使用 this.$slots.default[0] 查看默认插槽,但我不知道如何用一串 HTML 内容更新它。简单地将字符串分配给元素显然是不正确的,.innerHtml 不起作用,因为它不是一个可用的函数,而 .text 不起作用。我假设即使文本元素存在于插槽对象上,元素属性也优先。

根据评论中的建议,我已将其与计算机属性一起尝试过。
<span v-html="messageContent"><slot></slot></span>

但现在的问题是它覆盖了传递给我的插槽。

如何在 Vue.JS 中使用新 HTML 被动更新插槽?

最佳答案

我认为您的问题来自对 <slot> 在 VueJS 中固有的工作方式的误解。插槽用于将内容从消费父组件交织到子组件中。将其视为 v-bind:prop 的 HTML 等价物。当您在组件上使用 v-bind:prop 时,您实际上是在将数据传递到子组件中。这与插槽相同。

没有任何具体的示例或代码,这个答案充其量只是猜测。我假设您的父组件是一个 VueJS 应用程序本身,而子组件是包含 <slot> 元素的组件。

<!-- Parent template -->
<div id="app">
    <custom-component>
        <!-- content here -->
    </custom-component>
</div>

<!-- Custom component template -->
<template>
    <slot></slot>
</template>

在这种情况下,应用程序有一个默认的基本状态,它将静态 HTML 传递给子组件:
<!-- Parent template -->
<div id="app">
    <custom-component>
        <!-- Markup to be interweaved into custom component -->
        <p>Lorem ipsum dolor sit amet.</p>
    </custom-component>
</div>

<!-- Custom component template -->
<template>
    <slot></slot>
</template>

然后,当一个事件被触发时,您想用新的传入标记替换该基态标记。这可以通过将传入的 HTML 存储在 data 属性中并简单地使用 v-html 有条件地呈现它来完成。假设我们要将传入的标记存储在应用程序的 vm.$data.customHTML 中:
data: {
    customHTML: null
}

然后您的模板将如下所示:
<!-- Parent template -->
<div id="app">
    <custom-component>
        <div v-if="customHTML" v-html="customHTML"></div>
        <div v-else>
            <p>Lorem ipsum dolor sit amet.</p>
        </div>
    </custom-component>
</div>

<!-- Custom component template -->
<template>
    <slot></slot>
</template>

请注意,与您尝试过的代码相比,不同之处在于:
  • 父组件 (即消费组件)负责指示传递给子组件
  • 的标记类型
  • 子组件非常愚蠢:它只是接收标记并将其呈现在 <slot> 元素中


  • 请参阅下面的概念验证:

    var customComponent = Vue.component('custom-component', {
      template: '#custom-component-template'
    });
    
    new Vue({
      el: '#app',
      data: {
        customHTML: null
      },
      components: {
        customComponent: customComponent
      },
      methods: {
        updateSlot: function() {
          this.customHTML = '<p>Foo bar baz</p>';
        }
      }
    });
    .custom-component {
      background-color: yellow;
      border: 1px solid #000;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
    
    <div id="app">
      <h1>I am the app</h1>
      <button type="button" @click="updateSlot">Click me to update slot content</button>
      <custom-component>
        <div v-if="customHTML" v-html="customHTML">
        </div>
        <div v-else>
          <p>Lorem ipsum dolor sit amet.</p>
        </div>
      </custom-component>
    </div>
    
    <!-- custom-component template -->
    <script type="text/template" id="custom-component-template">
      <div class="custom-component">
        <h2>I am a custom component</h2>
        <!-- slot receives markup set in <custom-component> -->
        <slot></slot>
      </div>
    </script>

    关于javascript - 如何更新 Vue.JS 中的插槽,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50241423/

    10-09 20:30
    查看更多