Created
June 30, 2021 09:13
-
-
Save nash403/9e7746f9eda859155c8b111db5f8ed3b to your computer and use it in GitHub Desktop.
Vue component that render raw SVG content like with `v-html` but without the need of an extra root element.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { VNodeData } from 'vue' | |
import { defineComponent } from '@vue/composition-api' | |
/** | |
* Use this component to render raw SVG content | |
* without the need to use the `v-html` directive | |
* which requires a parent node in Vue 2.x (ex: `<div v-html="..."></div>`). | |
* `<NSvgFragment :src="..." />` will directly render the svg tag with its content. | |
* */ | |
export default defineComponent({ | |
functional: true, | |
props: { | |
src: { type: String, default: '' }, | |
}, | |
render(h, context) { | |
try { | |
const UniversalDOMParser = typeof window === 'undefined' ? require('universal-dom-parser') : DOMParser | |
const svgRoot = new UniversalDOMParser().parseFromString(context.props.src, 'image/svg+xml').firstChild as Element | |
const svgAttributes = {} as { [key: string]: unknown } | |
for (const attribute of Array.from(svgRoot?.attributes ?? [])) { | |
svgAttributes[attribute.name] = attribute.value | |
} | |
const combinedAttributes: VNodeData['attrs'] & { class?: VNodeData['class']; style?: VNodeData['style'] } = { | |
...(context.data.attrs ?? {}), | |
...svgAttributes, | |
...{ | |
class: [context.data.class, (svgAttributes.class as string) || ''], | |
style: [context.data.style, (svgAttributes.style as string) || ''], | |
}, | |
} | |
const { class: classNames, style: styles, ...attributes } = combinedAttributes | |
return h('svg', { | |
...context.data, | |
attrs: attributes, | |
style: styles, | |
class: classNames, | |
domProps: { | |
innerHTML: `${svgRoot?.innerHTML}`, | |
}, | |
}) | |
} catch (error) { | |
console.error(error) | |
return h('svg', context.data, []) | |
} | |
}, | |
}) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment