1

What is the simplest way to implement multiple changeable variables that depend on each other?

For example we have a price before discount which cannot change and we can:

  1. apply the discount and the price after discount should update,
  2. or change the price after discount and the discount should update accordingly.

I have came up with the following solution for this example: https://jsfiddle.net/2wh6cgq5/1/

Can it be done without having to create separate handlers for each @input event and applying the v-model directive?

1
  • 1
    You can try to use computed props with a getter and a setter and use them only for v-model and change underlying props only from code Commented Sep 26, 2020 at 11:59

1 Answer 1

5

One option is to use the v-model binding with computed properties so you can control the set logic.

new Vue({
  el: '#app',
  
  data: {
    priceBeforeDiscount: 100,
    discount: 50,
    priceAfterDiscount: 50,
  },
  
  computed: {
    priceAfterDiscountInput: {
      get() {
        return this.priceAfterDiscount;
      },
      set(val) {
        this.priceAfterDiscount = val;
        this.discount = this.priceBeforeDiscount - this.priceAfterDiscount;
      }
    },
    discountInput: {
      get() {
        return this.discount;
      },
      set(val) {
        this.discount = val;
        this.priceAfterDiscount = this.priceBeforeDiscount - this.discount;
      }
    }
  },
})

Another possibility is to use watchers on discount and priceAfterDiscount. It doesn't lead to an infinite loop in this case because the values reach an equilibrium and watchers only run if the value changes. I'd be cautious about using co-dependent watchers in general though.

new Vue({
  el: '#app',
  
  data: {
    priceBeforeDiscount: 100,
    discount: 50,
    priceAfterDiscount: 50,
  },
  
  watch: {
    discount() {
        this.priceAfterDiscount = this.priceBeforeDiscount - this.discount;
    },
    priceAfterDiscount() {
        this.discount = this.priceBeforeDiscount - this.priceAfterDiscount;
    }
  },
})

However, I don't really think there's an issue with your solution. If you aren't required to use the v-model directive (e.g. for vee-validate), I'd just convert it to v-bind and do the assignment in the input handler.

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

1 Comment

The computed property approach is the most elegant in my opinion. Watchers are risky because if I want to for example round the price and the discount to 2 decimal places it may go into an infinite loop.

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.