gpt4 book ai didi

css - 如何将 Vue VNode 渲染为字符串

转载 作者:行者123 更新时间:2023-12-03 06:47:15 26 4
gpt4 key购买 nike

我正在尝试在我的 Vue 组件中使用 CSS 掩码。我需要完成下面的toSvg函数的实现。这会将来自 this.$slots.default 的 Vue VNode 呈现为 SVG 字符串。

<script>
export default {
computed: {
maskImage() {
const svg = this.toSvg(this.$slots.default);
const encodedSvg = btoa(svg);
return `url('data:image/svg+xml;base64,${encodedSvg}')`;
},
},
methods: {
toSvg(vnode) {
// TODO: How can I convert the VNode to a string like the one below?
// In React, I could use const svg = ReactDOMServer.renderToStaticMarkup(vnode);
return `<svg viewBox="0 0 260 68" xmlns="http://www.w3.org/2000/svg">
<rect x="80" y="32" width="160" height="12" rx="2" />
<rect width="180" height="20" rx="2" />
<rect x="80" y="52" width="95" height="12" rx="2" />
<rect y="26" width="68" height="42" rx="2" />
</svg>`;
},
},
render(createElement) {
return createElement("div", {
attrs: {
class: "skeleton",
style: `-webkit-mask-image: ${this.maskImage}; mask-image: ${this.maskImage};`,
},
});
},
};
</script>

<style lang="scss">
.skeleton {
animation: skeleton-animation 2s infinite linear;
background: linear-gradient(to right, hsl(30, 1, 99) 0%, hsl(30, 2, 95) 30%, hsl(30, 2, 95) 70%, hsl(30, 1, 99) 100%) 0 0 / 200% 100% hsl(30, 2, 95);
overflow: hidden;
position: relative;

width: 200px;
height: 100px;

@keyframes skeleton-animation {
100% {
background-position: -200% 0;
}
}
}
</style>

使用示例:

<u-skeleton>
<svg viewBox="0 0 260 68" xmlns="http://www.w3.org/2000/svg">
<rect x="80" y="32" width="160" height="12" rx="2" />
<rect width="180" height="20" rx="2" />
<rect x="80" y="52" width="95" height="12" rx="2" />
<rect y="26" width="68" height="42" rx="2" />
</svg>
</u-skeleton>

显示为:

enter image description here

最佳答案

使用Vue.extend构造一个SVG组件constructor,在构造函数的render function中,渲染slots.default

下一步是创建它的实例,然后 mount() 并获取编译后的 html。

Vue.component('v-test', {
computed: {
maskImage() {
let vnodes = this.$slots.default
let SVGConstructor = Vue.extend({
render: function (h, context) {
return h('svg', {
attrs: {
xmlns: 'http://www.w3.org/2000/svg'
}
}, vnodes)
}
})
let instance = new SVGConstructor()
instance.$mount()
const encodedSvg = btoa(instance.$el.outerHTML);
return `url('data:image/svg+xml;base64,${encodedSvg}')`;
}
},
render(createElement) {
return createElement("div", {
attrs: {
class: "skeleton",
style: `-webkit-mask-image: ${this.maskImage}; mask-image: ${this.maskImage};`,
},
})
},
})

new Vue({
el: '#app'
})
.skeleton {
animation: skeleton-animation 2s infinite linear;
background: linear-gradient(to right, #fcfcfc 0%, #f3f2f2 30%, #f3f2f2 70%, #fcfcfc 100%) 0 0 / 200% 100% #f3f2f2;
overflow: hidden;
position: relative;
width: 200px;
height: 100px;
}
@keyframes skeleton-animation {
100% {
background-position: -200% 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<v-test>
<svg viewBox="0 0 260 68" xmlns="http://www.w3.org/2000/svg">
<rect x="80" y="32" width="160" height="12" rx="2" />
<rect width="180" height="20" rx="2" />
<rect x="80" y="52" width="95" height="12" rx="2" />
<rect y="26" width="68" height="42" rx="2" />
</svg>
</v-test>
<hr>
<v-test>
<svg viewBox="0 0 260 68" x="0" y="0" xmlns="http://www.w3.org/2000/svg">
<rect x="80" y="32" width="160" height="12" rx="2" />
<rect width="180" height="20" rx="2" />
<rect x="80" y="52" width="95" height="12" rx="2" />
<rect y="26" width="68" height="42" rx="2" />
</svg>
<svg viewBox="0 0 260 68" x="20" y="-20" xmlns="http://www.w3.org/2000/svg">
<rect x="80" y="32" width="160" height="12" rx="2" />
<rect width="180" height="20" rx="2" />
<rect x="80" y="52" width="95" height="12" rx="2" />
<rect y="26" width="68" height="42" rx="2" />
</svg>
</v-test>
</div>

关于css - 如何将 Vue VNode 渲染为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64206148/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com