本篇内容介绍了“Vue如何实现插槽下渲染dom字符串使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
先来简单介绍下需求:这是在开发一个低代码平台的时候所遇到的需求,用户可以自己写一些组件上传到平台,在使用的时候可以对组件的 props
slots
events
进行配置,这就涉及到了动态插槽内容的实现了。对于代码编辑器的实现使用了 code-mirror,感兴趣的可以去看下,这里就不多说了。这里主要讲如何实现动态插槽内容渲染。
先来大致看下代码的上下文:
<template>
<Component
v-bind="componentProps"
>
<template
v-for="item of componentSlots"
#[item[0]]
>
</template>
</Component>
</template>
<script setup lang="ts">
const Component = defineAsyncComponent({
// ...
})
const componentProps = ref({})
const componentSlots = ref<[string, string][]>([])
onMounted(async () => {
componentProps.value = await loadProps()
componentSlots.value = await loadSlots()
})
</script>
说到渲染 dom
字符串,那 v-html
肯定是首要想到的。但是 template
标签上是无法使用 v-html
的,那么只能在 template
下写一个普通元素来塞 dom
字符串,代码如下:
<template
v-for="item of componentSlots"
#[item[0]]
>
<span v-html="item[1]">
</span>
</template>
这样的确实现了动态渲染插槽内容的需求,但是多出一个标签总是感觉不太妥当;而且也很难保证这个多出的 span
不会对组件的布局产生影响。这让我又陷入的沉思...
既然 innerHTML
不完全满足需求,那么使用 outerHTML
不就完美解决这个问题了吗?于是我去查关于 vue
如何使用 outerHTML
相关资料,发现并没有很好的案例,那就自己实现一个吧。
export const vOuterHTML = {
bind(el, binding) {
el.outerHTML = binding.value
},
update(el, binding) {
el.outerHTML = binding.value
},
}
<template
v-for="item of componentSlots"
#[item[0]]
>
<span v-outerHTML="item[1]">
</span>
</template>
代码保存,页面一刷新,这不完美实现了吗?但是等我去编辑 dom
字符串并保存后发现问题了,组件渲染内容并没有改变,控制台也报错了。
什么原因呢?原来是因为在 update
阶段时,span
已不在页面中,因此无法对他执行 outerHTML
赋值。
那怎么办呢?只需要在 bind
阶段记住 span
的父节点,然后在更新阶段手动再创建一个 span
并 append
到父节点下,再进行 outerHTML赋值即可,代码如下:
export const vOuterHTML = (() => {
let parentNode = null
return {
bind(el, binding) {
parentNode = el.parentNode
el.outerHTML = binding.value
},
update(el, binding) {
if (parentNode) {
const span = document.createElement('span')
parentNode.appendChild(span)
span.outerHTML = binding.value
}
},
unbind() {
if (parentNode) {
parentNode = null
}
}
}
})()
“Vue如何实现插槽下渲染dom字符串使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://juejin.cn/post/7222096611634348091