简体   繁体   中英

How to apply classes to Vue.js Functional Component from parent component?

Suppose I have a functional component:

<template functional>
    <div>Some functional component</div>
</template>

Now I render this component in some parent with classes:

<parent>
    <some-child class="new-class"></some-child>
</parent>

Resultant DOM doesn't have new-class applied to the Functional child component. Now as I understand, Vue-loader compiles Functional component against render function context as explained here . That means classes won't be directly applied and merge intelligently.

Question is - how can I make Functional component play nicely with the externally applied class when using a template?

Note: I know it is easily possible to do so via render function:

Vue.component("functional-comp", {
    functional: true,
    render(h, context) {
        return h("div", context.data, "Some functional component");
    }
});

TL;DR;

Use data.staticClass to get the class, and bind the other attributes using data.attrs

<template functional>
  <div class="my-class" :class="data.staticClass || ''" v-bind="data.attrs">
    //...
  </div>
</template>

Explanation:

v-bind binds all the other stuff, and you may not need it, but it will bind attributes like id or style . The problem is that you can't use it for class because that's a reserved js object so vue uses staticClass , so binding has to be done manually using :class="data.staticClass" .

This will fail if the staticClass property is not defined, by the parent, so you should use :class="data.staticClass || ''"

Example:

I can't show this as a fiddle, since only "Functional components defined as a Single-File Component in a *.vue file also receives proper template compilation"

I've got a working codesandbox though: https://codesandbox.io/s/z64lm33vol

Render function inside a functional component example, to supplement @Daniel's answer:

render(createElement, { data } {
  return createElement(
    'div',
    {
      class: {
        ...(data.staticClass && {
          [data.staticClass]: true,
        })
      },
      attrs: {
        ...data.attrs,
      }
    }
  )
}

We can use ES6 computed property name in order to set a static class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM