1. 程式人生 > >利用Vue.js2.0實現購物車和地址選配功能

利用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來說,一共有三種動態變化情況:

  1. 單個商品的選擇與否
  2. 單個商品的數量改變
  3. 全選/ 取消全選

所以,對於每一種變化情況,都要對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;
    }
  })
}

 

總結:

  1. 無論是商品還是地址的重複渲染,均通過v-for指令來遍歷所有資料元素。
  2. 利用v-bind:class="{'checked': condition}" @click='change-condition' 來實現通過滑鼠點選動態改變頁面
  3. 引入vue-resource.js,Vue 例項中利用 this.$http 呼叫 http 服務,請求.json檔案。
  4. 通過建立過濾器,來格式化價格顯示形式。

 


教程地址:
慕課網-利用Vue2.0實現購物車和地址選配功能

相關資料參考: