Dariusz Legizynski
Dariusz Legizynski

Reputation: 386

How to pass a style property to a child component as a computed property in Vue.js?

I have the following problem:

I have too much logic in my inline style and would to place it inside a computed property. I know, that this is the way, that I should go, but do not know, how to achieve it.

Below I a simple example that I made for better understanding. In it, on button press, the child's component background-color is changing.

My code can be found here: Codesandbox

My parent component:

<template>   <div id="app">
    <MyChild :colorChange="active ? 'blue' : 'grey'" />
    <p>Parent:</p>
    <button @click="active = !active">Click Me!</button>   </div> </template>

<script> import MyChild from "./components/MyChild";

export default {   name: "App",   components: {
    MyChild,   },   data() {
    return {
      active: false,
    };   }, }; </script>

and my child component:

<template>   <div class="hello">
    <p>Hello from the child component</p>
    <div class="myDiv" :style="{ background: colorChange }">
      here is my color, that I change
    </div>   </div> </template>

<script> export default {   name: "HelloWorld",   props: {
    colorChange: {
      type: String,
      default: "green",
    },   }, }; </script>

<!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .myDiv {   color: white;   padding: 1rem 0; } </style>

I also have a second question. Let's say, that I have more than one child component and also would like to change to colors on button click, but those colors differ. How can I achieve it without repeating myself (within the computed properties?)

Code example for my parent component:

<MyChild :colorChange="active ? 'blue' : 'grey'" />
<MyChild :colorChange="active ? 'grey' : 'blue'" />
<MyChild :colorChange="active ? 'blue' : 'red'" />
<MyChild :colorChange="active ? 'yellow' : 'blue'" />

Thanks in advance!

Upvotes: 2

Views: 518

Answers (1)

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23490

Maybe You can bind class and use different css classes:

Vue.component('MyChild',{
  template: `
    <div class="hello">
      <p>Hello from the child component</p>
      <div class="myDiv" :class="collorCurrent">
        here is my color, that I change
      </div>   
    </div>
  `,
  props: {
    colorChange: {
      type: String,
      default: "green",
    },
    colorDef: {
      type: String,
      default: "green",
    },
    isActive: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    collorCurrent() {
      return this.isActive ? this.colorChange : this.colorDef
    }
  }
})

new Vue({
  el: "#demo",
  data() {
    return {
      active: false,
    }
  },
})
.myDiv {   color: white;   padding: 1rem; }

.blue {
  background: blue;
  font-size: 22px;
}

.red {
  background: red;
  font-variant: small-caps;
}

.yellow {
  background: yellow;
  color: black;
}

.grey {
  background: grey;
  text-decoration: underline;
}

.green {
  background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <p>Parent:</p>
  <button @click="active = !active">Click Me!</button>
  <my-child :is-active="active" :color-def="'grey'" :color-change="'blue'"></my-child>
  <my-child :is-active="active" :color-def="'blue'" :color-change="'grey'"></my-child>
  <my-child :is-active="active" :color-def="'red'" :color-change="'blue'"></my-child>
  <my-child :is-active="active" :color-def="'blue'" :color-change="'yellow'"></my-child>
</div>

Upvotes: 1

Related Questions