0

I have a vuejs functional component that mimics a div behavior. To do so, I set it's class based on the props that it receives.

Something like this:

<MyDiv textAlign="left">Div with left aligned text</MyDiv>

Becomes:

<div class="text-left">Div with left aligned text</div>

However, if MyDiv component is the root element for some other component, like:

Card.vue

<template>
  <MyDiv display="inline-block" textAlign="center">
    <slot />
  </MyDiv>
</template>

And if Card receive any class attribute when used, I can't set the class attribute value based on MyDiv props, instead, class (on MyDiv) is overridden by the class received by Card.

So this:

<Card class="cool-style">Card content</Card>

Becomes:

<div class="cool-style">Card content</div>

Ant not this (what I need):

<div class="cool-style inline-block text-center">Card content</div>

Here's MyDiv component:

MyDiv.vue

export default {
  name: 'my-div',
  functional: true,
  props: {
    textAlign: {
      type: String,
      allowed: ['left', 'right', 'center'],
      default: null
    },
    display: {
      type: String,
      allowed: ['hidden', 'block', 'inline-block', 'flex'],
      default: null
    }
  },
  render: function(createElement, context) {
    let classes = [];

    // Adds parent class to itself
    if (typeof context.data.staticClass == 'string') {
      classes.push(context.data.staticClass);
    }

    let classes = classes.concat([
      'my-div',
      context.props.textAlign && `text-${context.props.textAlign}`,
      context.props.display && context.props.display
    ]);

    classes = classes.filter(elm => elm != null);
    classes = classes.join(' ').trim();

    return createElement(
      props.type,
      {
        attrs: {
          class: classes
        }
      },
      context.children
    );
  }
};

TL;DR

How can I force my custom class to a vue functional component, when it's parent have already a class being set?

As a side note, it can be done using statefull (non-functional and regular) components.

1 Answer 1

1

Replace

attrs: {
  class: classes
}

by

class: classes

Side note: Not really needed to join the array into a string, you can pass the array.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.