如何更新Vue.JS中的插槽 [英] How to update a slot in Vue.JS

查看:368
本文介绍了如何更新Vue.JS中的插槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面简化了Vue组件。

I have a Vue component simplified below.

这是模板

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

这个插槽可能包含HTML,这就是我决定使用插槽而不是支柱的原因只会绑定到。我想保持这种方式。

The slot may contain HTML, which is why I decided to use a slot rather than a prop which I would simply bind to. I'd like to keep it that way.

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

I have a method that gets new HTML from the server. I'd like to use this new HTML to update the slot. I'm not sure if slots are reactive and how I can accomplish this.

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

I can view the default slot using this.$slots.default[0], but I don't know how to update it with a string of HTML content. Simply assigning the string to the element is obviously incorrect, to .innerHtml does not work because it isn't an available function, and to .text doesn't work. I assume that even though the text element exists on the slot object, the element properties take precedence.

根据评论中的建议,我尝试过这个以及计算机属性。

Per suggestion in comments, I've tried this along with a computer property.

<span v-html="messageContent"><slot></slot></span>

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

But now the problem is that it overwrites the slot passed to me.

如何在Vue.JS中使用新HTML反应性更新广告位?

推荐答案

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

I think your issue comes from a misunderstanding of how <slot> inherently works in VueJS. Slots are used to interweave content from a consuming parent component into a child component. See it as a HTML equivalent of v-bind:prop. When you use v-bind:prop on a component, you are effectively passing data into a child component. This is the same as slots.

如果没有任何具体的示例或代码,那么这个答案充其量只是猜测工作。我假设您的父组件本身是VueJS应用程序,子组件是保存< slot> 元素的组件。

Without any concrete example or code from your end, this answer is at best just guess-work. I assume that your parent component is a VueJS app itself, and the child component is the one that holds the <slot> element.

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

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

在这种情况下,应用程序有一个默认的基础状态,它将静态HTML传递给子组件:

In this case, the app has a default ground state where it passes static HTML to the child component:

<!-- 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 中:

Then, when an event is fired, you want to replace that ground-state markup with new incoming markup. This can be done by storing the incoming HTML in the data attribute, and simply using v-html to conditionally render it. Let's say we want to store the incoming markup in app's vm.$data.customHTML:

data: {
    customHTML: null
}

然后您的模板将如下所示:

Then your template will look like this:

<!-- 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>

请注意,与您尝试过的代码相比,不同之处在于:

Note that in contrast to the code you have tried, the differences are that:


  • 父组件(即消费组件)负责指示哪种类型的要传递给孩子的标记

  • 子组件与 dumb 一样:它只是接收标记并在<中呈现它; slot> 元素

  • It is the parent component (i.e. the consuming component) that is responsible for dictating what kind of markup to pass to the child
  • The child component is as dumb as it gets: it simply receives markup and renders it in the <slot> element

查看证明 - 概念如下:

See proof-of-concept below:

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>

这篇关于如何更新Vue.JS中的插槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆