使用Vue.js计算动态价格

时间:2017-08-31 07:37:11

标签: javascript vue.js vuejs2 vue-component

我正在建立酒店预订申请,目前我正在处理预订部分。

在这里,我为用户提供了使用选择框编辑首选房间类型和成人人数以及孩子数量的选项。

清楚地说,如果用户选择了房间类型"标准房间"如果有一个成人而没有孩子,那么我们就可以获得已经为该特定房间存储的默认价格值。

我已经把小提琴放到了这一步:

https://jsfiddle.net/c1ud4mkv/

这一步之后我需要帮助。如果用户需要与2名成人和1或2名儿童住在一起,那么价格需要相应地改变。

例如;目前,1名成人的标准房型价格为1000卢比。

如果用户想要添加1个额外成人,则意味着价格需要更改为2000卢比。如果用户需要添加1个孩子和2个成人,则意味着价格需要计算为Rs.3000(2000卢比+ 1000卢比)(1000卢比是额外1个孩子的价格)。

HTML:

<div id="app">
 <table>
    <thead>
     <td>Room Type</td>
     <td>Adult</td>
     <td>Children</td>
     <td>Total Price</td>
    </thead>
        <tbody>
          <tr v-for="(row, index) in rows">
            <td>
              <select data-value="Room Type">
                <option v-for="room in rooms">{{room.title}}</option>
              </select>
            </td>
            <td>
              <select data-value="1 Adult">
              <option value="1">1 Adult</option>
              <option value="2">2 Adults</option>
            </select>
          </td>
          <td>
            <select data-value="No Child">
            <option value="1">No Child</option>
            <option value="2">1 Child</option>
            <option value="3">2 Children</option>
          </select>
        </td>
        <td v-for="item in items">
          {{item.price}}
        </td>
      </tr>
    </tbody>
  </table>
    <div class="add-remove">
    <div class="col-md-6 text-center add">
      <a @click="addRoom" class="add-room"> Add Room </a>
    </div>
    <div class="col-md-6 text-center remove">
      <a @click="removeRoom(index)" class="remove-room"> Remove Room </a>
    </div>
  </div>
</div>

脚本是:

new Vue({
  el: '#app',

  data: {
    rows: [],
    rooms: [
    {
        value:0,
        title: 'Standard Room'
    },
    {
        value:0,
        title: 'Deluxe Room'
    },
    ],
    items: [{
        price: 1000,
    }]
  },

  methods: {
    addRoom: function() {
      var elem = document.createElement('tr');
      this.rows.push({
      });
    },

    removeRoom: function(index) {
      this.rows.splice(index, 1);
    },

    }

  })

jsfiddle链接是https://jsfiddle.net/c1ud4mkv/

2 个答案:

答案 0 :(得分:2)

总价格应为计算属性,根据您的数据计算。

<强>更新

由于你想要x行,每行重复相同的行为,你需要一个代表一行的组件,我称之为预留。您很快就会发现该组件是以前Vue的复制粘贴。几乎没有任何变化。

现在,顶级vue模板只是一个用于创建组件的for循环。请注意,组件可以直接引用商店以获取共享数据(会议室),但必须通过其属性获得其唯一性。

请注意,页面的整个状态由结构合理的商店表示,与Vue内容分开,状态项之间没有依赖关系。因此,计算值totalPrice不在商店中,而是从值中得出。要构建这样的问题,我首先要编写商店,然后考虑如何显示它。

AddRow是一种方法,因为它在选定的时间运行,不返回任何内容并更新商店。方法通常将数据上传到上游TotalPrice是一个计算属性,因为我们希望它是反应性的,它在模板中使用,它在下游侧。

看到它正在运行here

所以这就是整个事情......

<强>标记

<div id="vueRoot">
  <reservation v-for="myReservation in store.reservations" :reservation="myReservation"></reservation>
  <a class="myPlus" v-on:click="addRow">+</a>
</div>

<强>码

var vueStore = {
  rooms : [
    {label : 'palatial suite', price : 1000.73},
    {label : 'presidential suite', price : 2000.36}
  ],
  reservations : [{
      selectedRoom : null,
      numAdults : 1,
      numChildren : 0
  }]
};
Vue.component("reservation",{
  template : `<div style="padding:12px">
  Room :
  <select v-model="reservation.selectedRoom">
    <option v-for="room in rooms" v-bind:value="room.price">
      {{room.label}}
    </option>
  </select>
  Number of adults :
  <select v-model="reservation.numAdults">
    <option>1</option>
    <option>2</option>
  </select>
  Number of children :
  <select v-model="reservation.numChildren">
    <option>0</option>
    <option>1</option>
    <option>2</option>
  </select>
  Total Price : {{totalPrice}}
</div>`,
  data : function(){
    return {
      rooms : vueStore.rooms
    }
  },
  props : [ 'reservation' ],
  computed : {
    totalPrice : function(){
      if(this.reservation.selectedRoom){
        return this.reservation.selectedRoom 
          + this.reservation.numAdults * 500 
          + this.reservation.numChildren * 200
      }
      else return '';
    }
  }
});
vm = new Vue({
  el : "#vueRoot",
  data : {store : vueStore},
  methods : {
  addRow : function(){
  this.store.reservations.push({
      selectedRoom : null,
      numAdults : 1,
      numChildren : 0
  })
  }
  }
});

答案 1 :(得分:1)

使用组件最好解决这个问题。但是,使用你在这里的配置,我已经修改如下以获得有用的东西:

首先是HTML。请注意我是如何使用v-model将select元素正确绑定到Vue实例的。

<div id="app">
<table>
<thead>
<td>Room Type</td>
<td>Adult</td>
<td>Children</td>
<td>Total Price</td>
</thead>
        <tbody>
          <tr v-for="(row, index) in rows">
            <td>
              <select v-model="row.roomType">
                <option v-for="room in rooms" v-bind:value="room.title">{{room.title}}</option>
              </select>
            </td>
            <td>
              <select v-model="row.adultCount">
              <option value="1">1 Adult</option>
              <option value="2">2 Adults</option>
            </select>
          </td>
          <td>
            <select v-model="row.childCount">
            <option value="0">No Child</option>
            <option value="1">1 Child</option>
            <option value="2">2 Children</option>
          </select>
        </td>
        <td>
          {{calcRoomTotal(row)}}
        </td>
      </tr>
    </tbody>
  </table>
    <div class="add-remove">
    <div class="col-md-6 text-center add">
      <a @click="addRoom" class="add-room"> Add Room </a>
    </div>
    <div class="col-md-6 text-center remove">
      <a @click="removeRoom(index)" class="remove-room"> Remove Room </a>
    </div>
  </div>

接下来是JavaScript。注意我是如何改变&#34;添加行&#34;功能包括房间的属性。

new Vue({
  el: '#app',

  data: {
    rows: [{
      roomType : "Standard Room",
      adultCount : 1,
      childCount : 0
      }],
    rooms: [
    {
        value:0,
        title: 'Standard Room'
    },
    {
        value:0,
        title: 'Deluxe Room'
    },
    ],
    items: [{
        price: 1000,
    }]
  },

  methods: {
    addRoom: function() {
      this.rows.push({
      roomType : "Standard Room",
      adultCount : 1,
      childCount : 0
      });
    },

    removeRoom: function(index) {
      this.rows.splice(index, 1);
    },

    calcRoomTotal: function(row) {
        return (parseInt(row.adultCount) + parseInt(row.childCount)) * 1000;
    }   
}

最后请注意,新的calcRoomTotal方法用于显示每行的房间总数。

这里是JSFiddle with the new setup