Is this even a thing in Vue?
import Vue from 'vue'
import { css } from './index'
export default function (tag, cls, vars = [], content) {
return Vue.component('styled', {
props: ['class'],
template: `<${tag} v-bind:class="[{{class}}, ${css(
cls,
vars.map(v => (v && typeof v === 'function' ? v(props) : v)),
content
)}]"><slot></slot></p>`
})
}
Suggested solution:
Learn Vue
I think Vue converts templates into jsx render functions.
Haven't tried locally, but how about something like this:
import { css } from './index'
Vue.component('styled', {
props: ['class'],
render(h) {
const ourCss = css(
cls,
vars.map(v => (v && typeof v === 'function' ? v(props) : v)),
content
);
return h(tag, { class:`${this.class} ${ourCss}` }, this.$slots.default);
}
});
Mostly from docs example
I've tested this locally and it works except for the name so you can only have one component. I'm trying to extract the name from the class name but it's being strange.
import Vue from 'vue'
import { css as magic } from 'emotion'
const styled = (tag, cls, vars = [], content) => {
Vue.component('styled', {
functional: true,
render (h, context) {
const className = magic(
cls,
vars.map(v => (v && typeof v === 'function' ? v(context.props) : v)),
content
)
return h(tag, { class: context.props.class
? className + ' ' + context.props.class
: className }, context.children)
}
})
}
export default styled
@mitchellhamilton I think class can be an array so you can lose the concat. Not 100% sure if it works with h though.
You don't need to register the component globally I guess? I mean no need of Vue.component('styled', component), just return the component object.
Thanks @egoist, it's working perfectly now, about to submit a PR.
Most helpful comment
I've tested this locally and it works except for the name so you can only have one component. I'm trying to extract the name from the class name but it's being strange.