6

I have a component v-popup.vue

<template>
  <div class="overlay">
    <div class="popup">
      <slot></slot>
    </div>
  </div>
</template>

and I want to style it from the parent, for example:

<template>
  <v-popup class="custom-popup">
    Popup content
  </v-popup>
</template>

<style>
  .custom-popup {
    padding: 20px;
  }
</style>

How can I configure v-popup.vue component to make custom-popup class to be automatically added to div.popup, not div.overlay ?

0

2 Answers 2

6

Scoped Styles

  • Using scoped styles (in both parent and child) is a good idea and will make this solution easier.

  • Instead of creating a new custom-popup class, use a deep selector in the parent. This allows the parent to define extra styles for child components that use the same selector.

  • The deep selector looks like this: >>> unless you're using a SCSS/SASS pre-processor. Then you use ::v-deep instead.

<template>
  <v-popup>
    Popup content
  </v-popup>
</template>

<style scoped>
  >>> .popup {
    padding: 20px;
  }

  /* If using SCSS/SASS, do this instead */
  /*
  ::v-deep .popup {
    padding: 20px;
  }
  */
</style>

The child will use both its own .popup class and the one from the parent.

If you didn't use scoped styles, it would quickly become a problem if you wanted to import the child in multiple parents and use different styles each time.

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

Comments

3

In your v-popup.vue, you can do the following:

<template>
  <div class="overlay">
    <div :class="['popup', popupClass]">
      <slot></slot>
    </div>
  </div>
</template>

<script>
 
export default {

// Do the usual implementations here...
props: {
 popupClass: ''
}

}

</script>

Then in your parent component, you can do the following:

<template>
  <v-popup popup-class="custom-popup">
    Popup content
  </v-popup>
</template>

However, I am curious. Why not encapsulate this class inside v-popup.vue. I seldom use this design unless there will be another component sharing this class from the parent.

EDIT (per your last comment): You can use this link as a reference on how to use the $attr attribute: https://jsfiddle.net/changjoo_park/pzx08wp9/

So, in a sense, you can do the following, in your parent component

<template>
  <v-popup popup-class="custom-popup" v-bind="$attrs">
    Popup content
  </v-popup>
</template>

In your v-popup component:

<template>
  <div class="overlay">
    <div :class="['popup', $attrs.popupClass]">
      <slot></slot>
    </div>
  </div>
</template>

<script>
 
export default {

// Do the usual implementations here...

}

</script>

So, no props implementations and the class is taken directly from the $attrs object. Hope this helps! You can read more about this usage here: https://v2.vuejs.org/v2/api/#vm-attrs

1 Comment

I'd like to prevent custom popupClass property. I'm wondering about using $attrs. I agree with encapsulation, but project I'm working on has some legacy code around that, and I don't have time to refactoring it :(

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.