Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use prop inside another prop as default value in vuejs

I am using this package from git hub for minus plus input for vuejs and in v2 folder example there is a sample file named plusminusfield.vue and this is what I used for using it :

 export default {
    props: {



        value: {
            default: 0,
            type: Number
        },
       base_capacity: {
            type: Number,
            required: true
        },
        min: {
             default: here I want to use the sent variable which is defined above and that is base_capacity 
 if I send a hard code like 5 it works well but I want to make it dynamic
             type:Number
        },
        max: {
            default: 22,
            type: Number
        },
    },
    data(){
        return {

            newValue: this.base_capacity,
        }
    },

and here is the methods for minus plus the numbers of input and controlling the max and min values :

methods:{
        getNotificationClass (notification) {
            return `alert alert-${notification.type}`
        },
        mpminus: function () {
            if ((this.newValue) > this.min) {
                this.newValue = this.newValue - 1
                this.$emit('input', this.newValue)
            }

        },
        mpplus: function () {
            if (this.max === undefined || (this.newValue < this.max)) {
                this.newValue = this.newValue + 1
                this.$emit('input', this.newValue)
            }
        },

    },
 watch: {
        value: {
            handler: function (newVal, oldVal) {
                this.newValue = newVal
            }
        }
    },

so if I define it any where else and I use it in props I get the mutant error which the parent component change it and my app wont run and if I use the computed like below I comment the error in front of them :

computed: {
           min() {
             return this.min ? this.min : this.base_capacity //Maximum call stack size exceeded
         }
        min : this.base_capacity // the error is base_capacity not defined
    },

so is there any way that I pass the min for that input from the

like image 756
Farshad Avatar asked Mar 28 '19 13:03

Farshad


2 Answers

While the accepted answer will work for Vue 2.x, in Vue 3.x prop default factory functions no longer have access to this. Instead you can pass the component's props as an argument to the factory function:

props: {
  ...
  baseCapacity: {
    default: 0,
    type: Number
  },
  min: {
    default: (props) => props.baseCapacity,
    type: Number
  },
  ...
},

See the migration guide: https://v3.vuejs.org/guide/migration/props-default-this.html

like image 61
Joshua Clark Avatar answered Nov 15 '22 03:11

Joshua Clark


Instead of using it directly, use a factory function and return the value.

moreover, HTML attributes are case-sensitive.

Example: If you set the attribute as: base-capacity, Vue will automatically convert it into the camel-case as baseCapacity to access it from the script.

Here is the official docs

Vue.component('plus-minus', {
  template: '#vplusminus',
  props: {
    value: {
      default: 0,
      type: Number
    },
    baseCapacity: {
      default: 0,
      type: Number
    },
    min: {
      default: function () {
        return this.baseCapacity 
      },
      type: Number
    },
    max: {
      default: undefined,
      type: Number
    }
  },
  data() {
    return {
      newValue: 0
    }
  },
  methods: {
    getNotificationClass(notification) {
      return `alert alert-${notification.type}`
    },
    mpplus: function() {
      if (this.max === undefined || (this.newValue < this.max)) {
        this.newValue = this.newValue + 1
        this.$emit('input', this.newValue)
      }
    },
    mpminus: function() {
      console.log(this.min); // Here it is coming as 12
      if ((this.newValue) > this.min) {
        this.newValue = this.newValue - 1
        this.$emit('input', this.newValue)
      }
    }
  },
  watch: {
    value: {
      handler: function(newVal, oldVal) {
        this.newValue = newVal
      }
    }
  },
  created: function() {
    this.newValue = this.value
  }
});

new Vue({
  el: '#app'
});
.minusplusnumber {
  border: 1px solid silver;
  border-radius: 5px;
  background-color: #FFF;
  margin: 0 5px 0 5px;
  display: inline-block;
  user-select: none;
}

.minusplusnumber div {
  display: inline-block;
}

.minusplusnumber #field_container input {
  width: 50px;
  text-align: center;
  font-size: 15px;
  padding: 3px;
  border: none;
}

.minusplusnumber .mpbtn {
  padding: 3px 10px 3px 10px;
  cursor: pointer;
  border-radius: 5px;
}

.minusplusnumber .mpbtn:hover {
  background-color: #DDD;
}

.minusplusnumber .mpbtn:active {
  background-color: #c5c5c5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <plus-minus :base-capacity="12" :value="16"></plus-minus>
  <plus-minus></plus-minus>
</div>

<script type="template/text" id="vplusminus">
  <div class="minusplusnumber">
    <div class="mpbtn minus" v-on:click="mpminus()">
      -
    </div>
    <div id="field_container">
      <input type="number" v-model="newValue" disabled />
    </div>
    <div class="mpbtn plus" v-on:click="mpplus()">
      +
    </div>
  </div>
</script>
like image 28
Varit J Patel Avatar answered Nov 15 '22 04:11

Varit J Patel