利用Vue.js2.0實現購物車和地址選配功能
根據慕課網-利用Vue2.0實現購物車和地址選配功能教程,通過利用Vue2.0來實現電商平臺的簡單功能。
vue中的$http
請求服務.
通過呼叫http服務,對.json檔案傳送http請求,通過遍歷陣列資料完成頁面渲染
引入vue-resource.js,即可以使用全域性的 Vue.http 或者在 Vue 例項中的 this.$http
呼叫 http 服務。
使用方法:
// 全域性 Vue 物件
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback) ;
Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
// Vue 例項
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
部分原始碼:
cartView: function () { // var _this = this; this.$http.get('data/cartData.json').then(res=>{ //then()方法是非同步執行就是當.then()前的方法執行完後再執行then()內部的程式.避免了資料沒獲取到等的問題 //此處使用了箭頭函式,使得內部的this與外部this保持一致,可以不用上面宣告的_this了 this.productList = res.data.result.list; // this.totalMoney = res.data.result.totalMoney; })
其中
then()方法是非同步執行。
就是當.then()前的方法執行完後再執行then()內部的程式,避免了資料沒獲取到等的問題。
語法:
promise.then(onCompleted, onRejected);
Promise 為方法物件.
onCompleted必需,為承諾成功完成時要執行的正確處理程式函式。
onRejected可選,為承諾被拒絕時要執行的錯誤處理程式函式。
建立過濾器格式化價格
建立過濾器,通過管道符號改變資料內容
{ { item.productPrice | formatMoney } }
起初,根據教程建立了局部過濾器和全域性過濾器,執行時會發現chrome一直報錯
[Vue warn]: Failed to resolve filter: formatMoney
(found in <Anonymous>)
經過不斷的嘗試和修改,最終發現,出現這種錯誤應該是因為filter的程式碼順序問題。
應該在建立 Vue 例項之前全域性定義過濾器
Vue.filter("money",function(value,type){
return ("¥" + value.toFixed(2) + type);
})
其中,Vue 2.0 在過濾器引數格式處
現在過濾器引數形式可以更好地與 js 函式呼叫方式一致,因此不用再用空格分隔引數:
<p>{ { date | formatDate 'YY-MM-DD' timeZone } }</p>
現在用圓括號括起來並用逗號分隔:
<p>{ { date | formatDate('YY-MM-DD', timeZone) } }</p>
通過動態繫結HTML Class,設定商品選擇情況
利用v-bind:class="{'check':item.checked}"
,將item.checked與HTML中的check狀態動態繫結。
@click="selectProduct(item)"
此處應為item設定一個屬性checked
,以確定商品是否被選定。
利用
Vue.set( target, key, value )
向響應式物件中新增一個屬性,並確保這個新屬性同樣是響應式的,且觸發檢視更新。
它必須用於向響應式物件上新增新屬性,因為 Vue 無法探測普通的新增屬性 (比如 this.myObject.newProperty = ‘hi’)
注意物件不能是 Vue 例項,或者 Vue 例項的根資料物件。
selectProduct:function(item){
if(typeof item.checked == "undefined"){
Vue.set(item,'checked',true); //若item沒有checked這個屬性,註冊該屬性
}else{
item.checked = !item.checked;
}
全選/取消全選按鈕:
繫結一個點選函式,若引數為true,就全選,false就取消全選。
class="{'check':checkAllFlag}" @click="checkAll(true)"
因為無論是全選還是取消全選,都要對所有商品進行遍歷,改變每一個商品的checked屬性,用this.productList.forEach(function(item){ ... })
函式,對每一個商品進行遍歷,改變item.checked
屬性值
特殊的,要注意到,當頁面載入完成後,還未點選選擇按鈕,即此時item.checked
屬性還不存在,所以遍歷時要判斷是否存在item.checked
屬性。
checkAll:function(flag){
this.checkAllFlag = flag;
var _this = this;
this.productList.forEach(function(item){
if(typeof item.checked == "undefined"){
Vue.set(item,'checked',_this.checkAllFlag);
}else{
item.checked = _this.checkAllFlag;
}
})
}
實現商品金額的計算
單個商品的金額計算:{ { item.productPrice * item.productQuantity | money('元')} }
總金額的計算:{ {totalMoney | money('元')} }
要計算totalMoney,可定義一個函式,分析其動態變化情況來源。
對於totalMoney來說,一共有三種動態變化情況:
- 單個商品的選擇與否
- 單個商品的數量改變
- 全選/ 取消全選
所以,對於每一種變化情況,都要對totalMoney進行重新計算,即在相應函式的最後,呼叫一次this.calcTotalPrice();
對於calTotalPrice函式,先對totalMoney清零,再遍歷陣列productList,
_this.totalMoney += item.productPrice*item.productQuantity;
實現總金額的計算。
calTotalPrice:function(){
var _this = this;
this.totalMoney = 0;
this.productList.forEach(function(item){
if(item.checked){
_this.totalMoney += item.productPrice*item.productQuantity;
}
});
}
實現單個商品的刪除
具體要求:點選商品刪除按鈕,跳轉至確認刪除介面,點選yes,刪除該商品;點選no,返回至上一頁。
delConfirm:function(item){
this.delFlag = true;
this.curProduct = item;//確認當前刪除的物件
},
delProduct:function(){
var index = this.productList.indexOf(this.curProduct);//確定要刪除物件的索引值
this.productList.splice(index,1);//刪除該物件
this.delFlag = false;
}
使頁面預設顯示三個地址卡片
利用計算屬性,返回地址列表的前三個,實現地址列表過濾
要限制頁面中載入的資料數量,
在Vue1.0中,通常使用limitBy過濾器,
<p v-for="item in items | limitBy 10">{ { item } }</p>
在Vue2.0中,在 computed 屬性中使用 js 內建方法:.slice
method:
<li v-for="(item,index) in filterAddress">
computed:{
filterAddress:function(){
return this.addressList.slice(0,3);
}
}
卡片和配送方式選中
比較每一張地址卡片的index與當前選中的curIndex,若相同,則令check屬性為true
<li v-for="(item,index) in filterAddress" v-bind:class="{'check':index == curIndex}" @click="curIndex = index">
在點選某一地址卡片後,會將當前卡片的索引值賦給curIndex,之後選擇出
index == curIndex
的那一張卡片,其check屬性為true,則完成卡片選中功能。
對於配送方式,也是一樣的思路,在Vue例項中的data裡,設定一個shipping值,代表著配送方式。
當shipping為1時,表示普通配送。當shipping為2時,表示高階配送。
<li v-bind:class="{'check':shipping == 1}" @click="shipping = 1">
<li v-bind:class="{'check':shipping == 2}" @click="shipping = 2">
將當前地址卡片設為預設地址
根據每一個地址的isDefault
屬性,利用v-if="item.isDefault"
判斷。
@click="setDefault(item.addressId)
設為預設地址
對於設定預設地址函式,應對所有地址進行遍歷,通過傳入的引數(唯一地址名稱),尋找到相應的address物件,設定address.isDefault = true;
setDefault:function(addressId){
this.addressList.forEach(function(address,index){
if(address.addressId == addressId){
address.isDefault = true;
}else{
address.isDefault = false;
}
})
}
總結:
- 無論是商品還是地址的重複渲染,均通過
v-for
指令來遍歷所有資料元素。 - 利用
v-bind:class="{'checked': condition}" @click='change-condition'
來實現通過滑鼠點選動態改變頁面 - 引入vue-resource.js,Vue 例項中利用
this.$http
呼叫 http 服務,請求.json檔案。 - 通過建立過濾器,來格式化價格顯示形式。
教程地址:
慕課網-利用Vue2.0實現購物車和地址選配功能
相關資料參考: