How to update a slot in Vue.JS(如何更新 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.
我可以使用 this.$slots.default[0]
查看默认插槽,但我不知道如何使用 HTML 内容字符串对其进行更新.简单地将字符串分配给元素显然是不正确的,对于 .innerHtml
不起作用,因为它不是可用的函数,对于 .text
不起作用.我假设即使文本元素存在于 slot 对象上,元素属性也优先.
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 中的插槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何更新 Vue.JS 中的插槽
基础教程推荐
- 我什么时候应该在导入时使用方括号 2022-01-01
- 在for循环中使用setTimeout 2022-01-01
- 角度Apollo设置WatchQuery结果为可用变量 2022-01-01
- 有没有办法使用OpenLayers更改OpenStreetMap中某些要素 2022-09-06
- Karma-Jasmine:如何正确监视 Modal? 2022-01-01
- 动态更新多个选择框 2022-01-01
- 响应更改 div 大小保持纵横比 2022-01-01
- 在 JS 中获取客户端时区(不是 GMT 偏移量) 2022-01-01
- 当用户滚动离开时如何暂停 youtube 嵌入 2022-01-01
- 悬停时滑动输入并停留几秒钟 2022-01-01