Search code examples
node.jsvue.jsvuex

doubly linking 2 inputs in vuejs with a computation in the middle


Explaining what I am trying to achieve with words is difficult for me because I am very new to vue.js.

I know I can use v-model to link an input to a variable, however, I want to link an input to a variable, do a computation, and display it in the another input. I also need the other input to do an inverse computation and display that result in the first input.

Okay so after that word salad, here is an example of the exact behavior I need.

enter image description here

You can type a value in either input and the other input will display the conversion. How could I achieve this in the best way? Is there a way avoiding hacky solutions like an if statement that's condition relies on which box is active?

Aside: I will be moving all of this into Vuex after I get the logic right? does something in vuex handle exactly this situation?


Solution

  • For this you can bind your <input> elements to computed properties, each with a setter.

    When you update one input, you can set the values of both accordingly.

    For example...

    const mul = 1.5
    
    new Vue({
      el: '#app',
      data: {
        val1: null,
        val2: null
      },
      computed: {
        input1: {
          get () {
            return this.val1
          },
          set (val) {
            this.val1 = val
            this.val2 = (val * mul).toFixed(2) // multiply to set val2
          }
        },
        input2: {
          get () {
            return this.val2
          },
          set (val) {
            this.val2 = val
            this.val1 = (val / mul).toFixed(2) // divide to set val1
          }
        }
      }
    })
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script>
    <div id="app">
    <p>
    <label for="input1">Input #1:</label>
    <input id="input1" v-model="input1" type="number">
    </p>
    <p>
    <label for="input2">Input #2:</label>
    <input id="input2" v-model="input2" type="number">
    </p>
    </div>