1

I want to add padding to the :style directive of my shared button component but for some reasons, the changes aren't showing up on the button.

I tried doing it with 3 ways below to apply the changes but none of them worked. I'm new to Vuejs and not able to find the problem. Any inputs/suggestions would be appreciated.

<Button
          @on-click="currentStep = 2"
          :text= "Next"
          :style="'padding: 12px 15px 12px 15px'"
       />
<Button
          @on-click="currentStep = 2"
          :text= "Next"
          :style="{ padding: '12px 15px 12px 15px' }"
        />
<Button
          @on-click="currentStep = 2"
          :text= "Next"
          :style="myStyle"
        />

and then returning myStyle: { padding: '12px 15px 12px 15px' } in the script for third one.

My Button.vue component looks like this:

<template>
  {{ this.color }}
  <button 
    @click="onClick"
    :disabled="disabled" 
    class="begin-btn"
    :style="backgroundColor + textColor"
  >{{ text }}
  </button>
</template>

<script>
export default {
  name: 'ButtonComponent',
  props: {
    text: String,
    disabled: Boolean,
    width: String,
    bgColor: String,
    txtColor: String,
  },
  data() {
    return {}
  },
  computed: {

    backgroundColor(){
      let bgColor = this.bgColor ? this.bgColor : '#d64ba1'
      return "background: " + bgColor + ';';
    },

    textColor(){
      let textColor = this.txtColor ? this.txtColor : '#ffffff'
      return "color: " + textColor  + ';';
    }
  },
  methods: {
    onClick() {
      this.$emit("onClick");
    },
  },
}
</script>

<style scoped>
.begin-btn {
  justify-content: center;
  align-items: center;
  border: 0px;
  width: 100%;
  height: 44px;
  background: #d64ba1;
  border-radius: 24px;
  font-style: normal;
  font-weight: 700;
  font-size: 16px;
  color: #ffffff;
}
</style>
Appu
  • 35
  • 5

4 Answers4

1

Please take a look at following snippet:

const app = Vue.createApp({
  data() {
    return {
      myStyle: { padding: '12px 15px 12px 15px' },
      Next: 'aaaaaa'
    };
  },
})
app.component('myButton', {
  template: `
  <button 
    @click="onClick"
    :disabled="disabled" 
    class="begin-btn"
    :style="backgroundColor + textColor + getPadding "
  >{{ text }}
  </button>
  `,props: {
    text: String,
    disabled: Boolean,
    width: String,
    bgColor: String,
    txtColor: String,
    padding: String
  },
  data() {
    return {}
  },
  computed: {
    getPadding() {
      return 'padding:' + this.padding.padding
    },
    backgroundColor(){
      let bgColor = this.bgColor ? this.bgColor : '#d64ba1'
      return "background: " + bgColor + ';';
    },
    textColor(){
      let textColor = this.txtColor ? this.txtColor : '#ffffff'
      return "color: " + textColor  + ';';
    }
  },
  methods: {
    onClick() {
      this.$emit("onClick");
    },
  },
})
app.mount('#demo')
.begin-btn {
  justify-content: center;
  align-items: center;
  border: 0px;
  width: 100%;
  height: 44px;
  background: #d64ba1;
  border-radius: 24px;
  font-style: normal;
  font-weight: 700;
  font-size: 16px;
  color: #ffffff;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <my-button
    @on-click="currentStep = 2"
    :text="Next"
    :padding="myStyle"
  ></my-button>
</div>
Nikola Pavicevic
  • 21,952
  • 9
  • 25
  • 46
  • I don't want to declare padding values inside the button component as they will be custom based on the usage of this shared button component. Could you suggest something that I can do for resolving this issue with padding? – Appu Feb 26 '23 at 23:46
1

You can use same approach as with another properties: define a property for padding and set a default value for in in your component's computed.

<template>
    <button
        @click="onClick"
        :disabled="disabled"
        class="begin-btn"
        :style="backgroundColor + textColor + calculatedPadding"
    >{{ text }}
    </button>
</template>

<script>
export default {
    name: 'ButtonComponent',
    props: {
        text: String,
        disabled: Boolean,
        width: String,
        bgColor: String,
        txtColor: String,
        padding: String
    },
    data() {
        return {}
    },
    computed: {
        calculatedPadding(){
            const paddingString = this.padding || '10px'; // default padding
            return 'padding:' + paddingString + ';';
        },

        backgroundColor(){
            let bgColor = this.bgColor ? this.bgColor : '#d64ba1'
            return "background: " + bgColor + ';';
        },

        textColor(){
            let textColor = this.txtColor ? this.txtColor : '#ffffff'
            return "color: " + textColor  + ';';
        }
    },
    methods: {
        onClick() {
            this.$emit("onClick");
        },
    },
}
</script>

Then, override the padding value with the one you need in another template where you use your component: SomeView.vue

<template>
    <div>
    <ButtonComponent 
        padding="50px 20px" <!-- overriding default padding for our button -->
    ></ButtonComponent>
    </div>
</template>

<script>
import ButtonComponent from '../components/ButtonComponent'

export default {
    // ....
    components:{
        ButtonComponent
    }
    // ....
}
</script>

UPDATE: You don't even need computed for this. Following code also works fine:

<template>
<button
    @click="onClick"
    :disabled="disabled"
    class="begin-btn"
    :style="backgroundColor + textColor + 'padding:'+this.padding"
>{{ text }}</button>
</template>

And then pass the required value to component:

<ButtonComponent bg-color="red" padding="10px 20px 100px 20px"></ButtonComponent>
Denis O.
  • 1,841
  • 19
  • 37
  • 1
    Thanks Denis. I tried all the solutions in this question post but the one you mentioned above UPDATE actually worked and overridden the internal style! It helped me to implement other custom based styles to the button as well. – Appu Mar 01 '23 at 12:22
1

The way you bind style property is correct, and it should work: see the example here

What is not working in your example is that your Button component has specified another :style binding internally. You cannot have the same property provided both internally and externally. Vue has to pick one and Vue picks the one defined by your component.

Xinchao
  • 2,929
  • 1
  • 24
  • 39
1

1、 use className

<Button
          @on-click="currentStep = 2"
          :text= "Next"
          class="btnClass"
       />
::v-deep{
// or other scoped lint
    .btnClass{
    padding: 12px 15px 12px 15px
    }
}

2、 props styleStr

button use

<Button
          @on-click="currentStep = 2"
          :text= "Next"
          styleStr="padding: '12px 15px 12px 15px'; " // or other your style
        />

button

<template>
  {{ this.color }}
  <button 
    @click="onClick"
    :disabled="disabled" 
    class="begin-btn"
    :style="backgroundColor + textColor + styleStr"
  >{{ text }}
  </button>
</template>

<script>
export default {
  name: 'ButtonComponent',
  props: {
    text: String,
    disabled: Boolean,
    width: String,
    bgColor: String,
    txtColor: String,
    styleStr:String,
  },
  data() {
    return {}
  },
  computed: {

    backgroundColor(){
      let bgColor = this.bgColor ? this.bgColor : '#d64ba1'
      return "background: " + bgColor + ';';
    },

    textColor(){
      let textColor = this.txtColor ? this.txtColor : '#ffffff'
      return "color: " + textColor  + ';';
    }
  },
  methods: {
    onClick() {
      this.$emit("onClick");
    },
  },
}
</script>

<style scoped>
.begin-btn {
  justify-content: center;
  align-items: center;
  border: 0px;
  width: 100%;
  height: 44px;
  background: #d64ba1;
  border-radius: 24px;
  font-style: normal;
  font-weight: 700;
  font-size: 16px;
  color: #ffffff;
}
</style>

3、 props style object

<Button
          @on-click="currentStep = 2"
          :text= "Next"
          :styleObj="{padding: '12px 15px 12px 15px'}" 
        />

button

<template>
  {{ this.color }}
  <button 
    @click="onClick"
    :disabled="disabled" 
    class="begin-btn"
    :style="backgroundColor + textColor +styleObj"
  >{{ text }}
  </button>
</template>

<script>
export default {
  name: 'ButtonComponent',
  props: {
    text: String,
    disabled: Boolean,
    width: String,
    bgColor: String,
    txtColor: String,
    styleObj:String,
  },
  data() {
    return {}
  },
  computed: {

    backgroundColor(){
      let bgColor = this.bgColor ? this.bgColor : '#d64ba1'
      return "background: " + bgColor + ';';
    },

    textColor(){
      let textColor = this.txtColor ? this.txtColor : '#ffffff'
      return "color: " + textColor  + ';';
    }
  },
  methods: {
    onClick() {
      this.$emit("onClick");
    },
  },
}
</script>

<style scoped>
.begin-btn {
  justify-content: center;
  align-items: center;
  border: 0px;
  width: 100%;
  height: 44px;
  background: #d64ba1;
  border-radius: 24px;
  font-style: normal;
  font-weight: 700;
  font-size: 16px;
  color: #ffffff;
}
</style>
```
张文玉
  • 29
  • 5