Подсчет динамических полей во Vue js

227
05 апреля 2018, 13:53

Есть поля формы, которые создаются динамически. Нужно расчитать 5 поле()Стоимость по формуле: width * len * height. Только я не могу понять, как это все правильно сделать. Проблема заключается с получением данных. У watch я получаю только тот input который изменяю, а нужно получить и остальные.

 <template id="baggage-template">
        <div>
            <div class="row" v-for="(input, index) in inputs">
                <div class="col-md-2">
                    <label class="control-label">Ширина</label>
                    <input class="form-control" type="text" v-model="input.width"  placeholder="см">
                </div>
                <div class="col-md-2">
                    <div class="form-group">
                        <label class="control-label">Длина</label>
                        <input class="form-control"  type="text" v-model="input.len" placeholder="см">
                    </div>
                </div>
                <div class="col-md-2">
                    <div class="form-group">
                        <label class="control-label">Высота</label>
                        <input class="form-control"  type="text" v-model="input.height" placeholder="см">
                    </div>
                </div>
                <div class="col-md-2" >
                    <label class="control-label">Вес</label>
                    <input class="form-control"  type="text" v-model="input.weight" placeholder="кг">
                </div>
                <div class="col-md-2">
                    <label class="control-label">Стоимость</label>
                    <input class="form-control" type="text"  v-model="input.price" name="input.baggage_price">
                </div>
                <div class="col-md-1">
                    <label class="control-label"></label>
                    <button class="btn btn-sm btn-danger" type="button" title="Удалить"  @click="deleteRow(index)">
                        <i class="fa fa-remove"></i></button>
                </div>
            </div>
            <button class="btn btn-sm btn-primary" type="button" @click="addRow">Добавить место багажа</button>
        </div>
    </template>
  Vue.component('baggage', {
        template:'#baggage-template',
        data: function(){
          return {
              checked:false,
              inputs: []
          }
        },
        props:['id','title', 'price'],
        methods:{
            addRow:function() {
                this.inputs.push({
                    width: '',
                    len: '',
                    height: '',
                    weight: '',
                    price:4,
                })
            },
            deleteRow(index) {
                this.inputs.splice(index,1)
            },
        },
        watch: {
            'inputs.0.width': {
                handler: function (val, oldVal) {
                   //здесь делать расчет вида: width * len * height
                }
            },
            'inputs.0.len': {
                handler: function (val, oldVal) {
                }
            },
            'inputs.0.height': {
                handler: function (val, oldVal) {
                }
            },
            'inputs.0.weight': {
                handler: function (val, oldVal) {
                }
            }
        }

    });

Визуальный вид формы:

Answer 1

Я бы сделал как-то так:
<input class="form-control" type="text" v-model="input.width" placeholder="см" @input="setPrice(input)">
аналогично по полям длины и высоты.
и в секции methods:

setPrice(input) {
  const {width, length, height} = input;
  const price = (!width || !length || !height) ? null : width*length*height;
  this.$set(input, 'price', price);
}
Answer 2

Как вариант добавить обработчик на изменение поля и в нем делать расчет:

        <div class="row" v-for="(input, index) in inputs">
            <div class="col-md-2">
                <label class="control-label">Ширина</label>
                <input class="form-control" type="text" v-model="input.width" @input="handler(index)"  placeholder="см">
            </div>
            <div class="col-md-2">
                <div class="form-group">
                    <label class="control-label">Длина</label>
                    <input class="form-control"  type="text" v-model="input.len" @input="handler(index)" placeholder="см">
                </div>
            </div>
            <div class="col-md-2">
                <div class="form-group">
                    <label class="control-label">Высота</label>
                    <input class="form-control"  type="text" v-model="input.height" @input="handler(index)" placeholder="см">
                </div>
            </div>
            <div class="col-md-2" >
                <label class="control-label">Вес</label>
                <input class="form-control"  type="text" v-model="input.weight" @input="handler(index)" placeholder="кг">
            </div>
            <div class="col-md-2">
                <label class="control-label">Стоимость</label>
                <input class="form-control" type="text"  v-model="input.price" name="input.baggage_price">
            </div>
            <div class="col-md-1">
                <label class="control-label"></label>
                <button class="btn btn-sm btn-danger" type="button" title="Удалить"  @click="deleteRow(index)">
                    <i class="fa fa-remove"></i></button>
            </div>
        </div>
        <button class="btn btn-sm btn-primary" type="button" @click="addRow">Добавить место багажа</button>
    </div>
</template>
  Vue.component('baggage', {
        template:'#baggage-template',
        data: function(){
          return {
              checked:false,
              inputs: []
          }
        },
        props:['id','title', 'price'],
        methods:{
            addRow:function() {
                this.inputs.push({
                    width: '',
                    len: '',
                    height: '',
                    weight: '',
                    price:4,
                })
            },
            deleteRow(index) {
                this.inputs.splice(index,1)
            },
            handler(index) {
              let {height, width, len} = this.inputs[index]
              this.inputs[index].price = height * width * len
            }
        }
    });
Answer 3

Сделал не много по другому. Через computed, само значения скрываю на выводе:

 <span style="visibility: hidden">@{{calc}}</span>

    Vue.component('baggage', {
        template:'#baggage-template',
        data: function(){
          return {
              checked:false,
              hide:false,
              inputs: []
          }
        },
        props:['id','title', 'price'],
        methods:{
            addRow:function() {
                this.inputs.push({
                    width: '',
                    len: '',
                    height: '',
                    weight: '',
                    suma:'',
                })
            },
            deleteRow(index) {
                this.inputs.splice(index,1)
            },
            calc(width, len, height, weight){
                vol = (width * len * height) / 5000
                if(vol > 9.6 || weight > 20){
                    return this.price / 2;
                }else{
                    return 0;
                }
            }
        },
       computed:{
           totalPrice() {
               return this.inputs.reduce((total, item) => {
                   return item.suma = this.calc(item.width, item.len, item.height, item.weight);
               }, 0);
           }
       },

    });
READ ALSO
Как сделать загрузку фото на сервер? Node.js + Ajax

Как сделать загрузку фото на сервер? Node.js + Ajax

Пытаюсь реализовать загрузку изображения на сервер, но файл не загружаетсяПомогите исправить ошибку

300
Система линейных уравнений JavaScript [требует правки]

Система линейных уравнений JavaScript [требует правки]

Написать скрипт который решает систему линейных уравнений (должна быть реализованы подпрограммы вычисления определителя и алгебраического...

203
Angular js. Как получить результат из диалогового окна для единственной ячейки без повтора?

Angular js. Как получить результат из диалогового окна для единственной ячейки без повтора?

Есть рабочий код, который позволяет передавать данные из диалогового окна в таблицуДля одного ряда все работает хорошо

210