I would like to create a vue element from a string from my database.
In this case, it should be a message with a smiley emoji.
I actually save it like: Some text with Emoji: :santa::skin-tone-3:
, and replace all valid string between '::' with the <Emoji emoji=':santa::skin-tone-3:' :size='16' />
<template>
<span class=message v-html=convertedMessage></div>
</template>
<script>
import { Emoji } from 'emoji-mart-vue'
export default {
components: {
Emoji
},
computed:{
convertedMessage(){
return "Some text with Emoji: "+"<Emoji emoji=':santa::skin-tone-3:' :size='16' />"
}
}
}
</script>
But instead of the rendered element which should be something like:
<span data-v-7f853594="" style="display: inline-block; width: 32px; height: 32px; background-image: url("https://unpkg.com/[email protected]/img/apple/sheets/64.png"); background-size: 5200%; background-position: 15.6863% 41.1765%;"></span>
I only get:
<emoji emoji=":santa::skin-tone-3:" :size="16"></emoji>
What is the best possibility to render this Element like intended?
Here are some much easier ways to do what you generally want. If you give more specifics, your right direction may be a strategy pattern before one of these solutions, but one of these solutions is probably what you want:
1) Vue lets you dynamically define components right out of the box, so this single line:
<component v-for="(component, index) in components" :key="'component'+index" :is="component.name" v-bind="component.props" />
...would draw a bunch of components in an array of objects like this (for example): {name: 'myComponentName', props: {foo: 1, bar: 'baz'}}.
2) Vue lets you inject HTML into components by simply adding v-html="variable"
For example, here is a component that creates dynamic SVG icons, where the contents of the SVG is dynamically injected from JavaScript variables...
<template>
<svg xmlns="http://www.w3.org/2000/svg"
:width="width"
:height="height"
viewBox="0 0 18 18"
:aria-labelledby="name"
role="presentation"
>
<title :id="name" lang="en">{{name}} icon</title>
<g :fill="color" v-html="path">
</g>
</svg>
</template>
<script>
import icons from '../common/icons'
export default {
props: {
name: {
type: String,
default: 'box'
},
width: {
type: [Number, String],
default: 18
},
height: {
type: [Number, String],
default: 18
},
color: {
type: String,
default: 'currentColor'
}
},
data () {
return {
path: icons[this.name]
}
},
created () {
console.log(icons)
}
}
</script>
<style scoped>
svg {
display: inline-block;
vertical-align: baseline;
margin-bottom: -2px;
}
</style>
3) Vue lets you dynamically define your component template through this.$options.template:
export default {
props: ['name', 'props'],
template: '',
created(){
this.$options.template = `<component :is="name" ${props.join(' ')} ></component>`
},
}
4) Vue lets you define a render function, so proxy components or other advanced shenanigans are trivial:
Vue.component('component-proxy', {
props: {
name: {
type: String,
required: true
},
props: {
type: Object,
default: () => {}
}
},
render(h) {
// Note the h function can render anything, like h('div') works too.
// the JS object that follows can contain anything like on, class, or more elements
return h(this.name, {
attrs: this.props
});
}
});
A smart genius wrote a jsbin for this here: http://jsbin.com/fifatod/5/edit?html,js,output
5) Vue allows you to create components with Vue.extend or even passing in raw JavaScript objects into a page or apps components section, like this, which creates a component named "foo" from a simple string for the template and an array for props, you could also extend the data, created, on, etc. the same way using the JS object alone:
new Vue({
el: '#app',
data: {
foo: 'bar',
props: {a: 'a', b: 'b'}
},
components: {
foo: {
template: '<p>{{ a }} {{ b }}</p>',
props: ['a', 'b']
}
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With