Goo*_*ose 2 javascript vue.js vue-component vuejs2
我在下面简化了Vue组件。
这是模板
<template>
<slot></slot>
</template>
Run Code Online (Sandbox Code Playgroud)
插槽可能包含HTML,这就是为什么我决定使用插槽而不是我会简单绑定到的道具的原因。我想保持这种方式。
我有一种从服务器获取新HTML的方法。我想使用这个新的HTML来更新广告位。我不确定插槽是否具有反应性以及如何实现此目的。
我可以使用来查看默认广告位this.$slots.default[0],但是我不知道如何使用一串HTML内容更新它。简单地将字符串分配给元素显然是不正确的,to .innerHtml无效,因为它不是可用的函数,并且to.text无效。我假定即使插槽对象上存在文本元素,但元素属性仍然优先。
根据评论中的建议,我已经尝试过将其与计算机属性一起使用。
<span v-html="messageContent"><slot></slot></span>
Run Code Online (Sandbox Code Playgroud)
但是现在的问题是,它覆盖了传递给我的广告位。
如何在Vue.JS中使用新的HTML反应式更新广告位?
下面是我的解决方案,尽管我不喜欢这种意见(将 html 直接加载到当前组件级别的插槽中),因为它违反了插槽的规则。我认为你应该这样做(<component><template v-html="yourHtml"></template></component>),这样会更好,因为 Slot 会像 Vue 设计的那样专注于它的工作。
关键是this.$slots.default必须有一个VNode,所以我用extend()和$mount()来获取_vnode。
Vue.config.productionTip = false
Vue.component('child', {
template: '<div><slot></slot><a style="color:green">Child</a></div>',
mounted: function(){
setTimeout(()=>{
let slotBuilder = Vue.extend({
// use your html instead
template: '<div><a style="color:red">slot in child</a></div>',
})
let slotInstance = new slotBuilder()
this.$slots.default = slotInstance.$mount()._vnode
this.$forceUpdate()
}, 2000)
}
})
new Vue({
el: '#app',
data() {
return {
test: ''
}
}
})Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<child><h1>Test</h1></child>
</div>Run Code Online (Sandbox Code Playgroud)
我认为您的问题来自<slot>对VueJS固有工作方式的误解。插槽用于将内容从使用中的父组件交织到子组件中。将其视为的HTML等效项v-bind:prop。在v-bind:prop组件上使用时,实际上是在将数据传递到子组件中。这与插槽相同。
如果没有最终的具体示例或代码,此答案充其量只是猜测。我假设您的父组件本身就是VueJS应用程序,而子组件就是包含该<slot>元素的组件。
<!-- Parent template -->
<div id="app">
<custom-component>
<!-- content here -->
</custom-component>
</div>
<!-- Custom component template -->
<template>
<slot></slot>
</template>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,应用程序具有默认的基本状态,在该状态下,它将静态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>
Run Code Online (Sandbox Code Playgroud)
然后,在触发事件时,您想用新的传入标记替换该基态标记。这可以通过将传入的HTML存储在data属性中,然后简单地使用v-html有条件地呈现它来完成。假设我们要将传入的标记存储在应用程序的中vm.$data.customHTML:
data: {
customHTML: null
}
Run Code Online (Sandbox Code Playgroud)
然后您的模板将如下所示:
<!-- 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>
Run Code Online (Sandbox Code Playgroud)
请注意,与您尝试的代码相比,不同之处在于:
<slot>元素中请参阅下面的概念验证:
<!-- Parent template -->
<div id="app">
<custom-component>
<!-- content here -->
</custom-component>
</div>
<!-- Custom component template -->
<template>
<slot></slot>
</template>
Run Code Online (Sandbox Code Playgroud)
<!-- 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>
Run Code Online (Sandbox Code Playgroud)
data: {
customHTML: null
}
Run Code Online (Sandbox Code Playgroud)