Skip to content

Instantly share code, notes, and snippets.

@nash403
Created June 30, 2021 09:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nash403/9e7746f9eda859155c8b111db5f8ed3b to your computer and use it in GitHub Desktop.
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.
<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