2017-08-31 17 views
1

私はホテルの予約申込み書を作成していますが、現在私は予約の部分に取り組んでいます。Vue.jsを使用した動的価格計算

ここでは、選択した部屋のタイプと大人の人数と選択ボックスを使用している子供の人数を編集するオプションをユーザに提供しています。

明らかに、ユーザーが1人の大人と子供がいない部屋タイプ「スタンダードルーム」を選択した場合、その特定のルームに既に保存されているデフォルト価格値を取得できます。

私は、このステップにバイオリンを添付しました:

https://jsfiddle.net/c1ud4mkv/

私はこのステップの後で助けが必要です。ユーザーが大人2名と子供1名または2名で宿泊する必要がある場合は、それに応じて価格を変更する必要があります。

たとえば、大人1名様のスタンダードルームタイプの料金は、現在Rs.1000です。

ユーザーが大人1人を追加したい場合は、価格をRs.2000に変更する必要があることを意味します。また、大人2名と一緒に1名の子供を追加する必要がある場合は、Rs.3000(Rs.2000 + Rs.1000)として計算する必要があることを意味します(Rs.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

合計金額は、データから計算された計算プロパティである必要があります。

更新

あなたはx行をしたいので、各行は同じ動作を繰り返すことで、あなたは私が予約を呼ばれていることを、行を表すコンポーネントが必要になります。コンポーネントが直前のVueのコピーペーストであることをすばやく検出します。ほとんど何も変わりません。

トップレベルのvueテンプレートは、コンポーネントを作成するためのfor-loopになりました。コンポーネントは共有データ(ルーム)のストアを直接参照できますが、そのプロパティを使用して一意性を取得する必要があることに注意してください。

ページの全体の状態は、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 
    }) 
    } 
    } 
}); 
+0

です。複数の部屋はどうですか? –

+0

私は単純な(そして素早い)例を望んでいました。後は、あなたが好きなように複雑にしてください:-)状態はマークアップから店に出て、総価格は計算されたプロパティである必要があります。 (それが反応するのでメソッドより優れています) – bbsimonbb

+0

計算されたプロパティはより良い、同意です。しかし、コンポーネントを使用せずに配列のオブジェクトの計算されたプロパティを宣言するにはどうすればいいですか? –

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。部屋のプロパティを含めるために「行を追加」機能をどのように変更したかに注目してください。

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があります。

関連する問題