VUE進(jìn)階筆記(3) -購(gòu)物車解析

(1) 構(gòu)建VUE實(shí)例

cart.js
--------

var vm = new Vue({   //實(shí)例對(duì)象,注意Vue首字母要大寫。一般用vm (ViewModel 的簡(jiǎn)稱) 這個(gè)變量名表示 Vue 實(shí)例
    el:"#app",    //dom掛載點(diǎn)
    data: { },  //data對(duì)象中放初始化的數(shù)據(jù),相當(dāng)于react中的state中的數(shù)據(jù)
    filters:{ }, //局部過(guò)濾器
    mounted: function() { } //鉤子函數(shù),相當(dāng)于react中的componentDidMount,數(shù)據(jù)渲染完成時(shí),將做的事情
    methods: { },  //方法函數(shù)
})

(2) v-for指令

v-for
-------

語(yǔ)法:(item, index) in items           //這里的in也可以寫成of   即( item of items )
item:item是數(shù)組元素迭代的別名。
index: index是數(shù)組元素的索引值。
items:items 是源數(shù)據(jù)數(shù)組
v-for 對(duì)象迭代
-------
你也可以用 v-for 通過(guò)一個(gè)對(duì)象的屬性來(lái)迭代

html

<div id="app">
    <div v-for="(value, key, index) in age">
         {{ index }}. {{ key }} : {{ value }}
    </div>
</div>

第一個(gè)參數(shù)value:鍵值
第二個(gè)參數(shù)key:鍵名
第三個(gè)參數(shù)index:索引

以上的輸出結(jié)果為:
0. firstName : John
1. lastName : Doe
2. ages : 30
---------------------------------------------------------

js

 var vm = new Vue({
    el:'#app',
    data:{
        age:{
            firstName: 'John',
            lastName: 'Doe',
            ages: 30
        }
    },

});

(3) 用axios.get() 發(fā)送get請(qǐng)求

var vm = new Vue({
    el:'#app',
    data:{
        porductList: []
    },
    filters: {

    },
    mounted: function() {
        this.cartView();
    },
    methods: {
        cartView: function() {
            axios.get('data/cartData.json')
                // .get('http://api.tianapi.com/meinv/?key=510b4ed16cb0b11b6ccfb7f3236fa8a6&num=10')
                .then( response => {
                    // console.log(response);
                    this.porductList = response.data.result.list;
                    // console.log(this.porductList)
                })
                .catch( err => { console.log(err) })
        }
    }

});

(4)點(diǎn)擊+-號(hào)實(shí)現(xiàn)購(gòu)買數(shù)量的+-,input輸入框的數(shù)據(jù)雙向綁定

html

<div class="quentity">
      <a href="javascript:;" v-on:click="changeMoney(product,-1)">-</a>
      <input type="text" v-model="product.productQuentity" disabled>
      <a href="javascript:;" v-on:click="changeMoney(product,1)">+</a>
</div>

----------------------------------
js

  changeMoney: function(product,choose) {  
            if( choose == 1){
                product.productQuentity++;
            }else if( choose == -1){
                product.productQuentity--;
                if(product.productQuentity < 1) {
                    product.productQuentity = 1;
                }
            }
        }

(5) v-bind指令

( prop: 給img綁定src屬性,給元素綁定class,style屬性等 )

.prop - 被用于綁定 DOM 屬性。(what’s the difference?)
.camel - (2.1.0+) 將 kebab-case 特性名轉(zhuǎn)換為 camelCase. (從 2.1.0 開(kāi)始支持)
.sync (2.3.0+) 語(yǔ)法糖,會(huì)擴(kuò)展成一個(gè)更新父組件綁定值的 v-on 偵聽(tīng)器。


購(gòu)物車中的例子:
![](product.productImage)
<div  id="showOverLay" v-bind:class="{ 'md-overlay': showModal }"></div>


官網(wǎng)的例子:
<!-- 綁定一個(gè)屬性 -->
![](imageSrc)

<!-- 縮寫 -->
![](imageSrc)

<!-- 內(nèi)聯(lián)字符串拼接 -->
![]('/path/to/images/' + fileName)

<!-- class 綁定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 綁定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 綁定一個(gè)有屬性的對(duì)象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通過(guò) prop 修飾符綁定 DOM 屬性 -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 綁定?!皃rop”必須在 my-component 中聲明。-->
<my-component :prop="someThing"></my-component>

<!-- 通過(guò) $props 將父組件的 props 一起傳給子組件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>
.camel 修飾符允許在使用 DOM 模板時(shí)將 v-bind 屬性名稱駝峰化,例如 SVG 的 viewBox 屬性:
<svg :view-box.camel="viewBox"></svg>

(6)mounted鉤子函和this.$nextTick(vue.nextTick)的關(guān)系

  • 當(dāng)數(shù)據(jù)修改之后,DOM沒(méi)有立即更新,這個(gè)之后執(zhí)行函數(shù)將是異步的,所以要想在DOM更新后立即執(zhí)行函數(shù)的話,需要用到Vue.nextTick(),在組件內(nèi)部一般使用this.$nextTick()
    mounted: function() {
        this.$nextTick(function() {
             // 代碼保證 this.$el 在 document 中
            // this.cartView();
            vm.cartView();
        });
    }
使用 mounted 并不能保證鉤子函數(shù)中的 this.$el 在 document 中。
為此還應(yīng)該引入 Vue.nextTick/vm.$nextTick

 Vue.nextTick( [callback, context] ) 

 作用:在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。
 用法:在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM。

 // 修改數(shù)據(jù)
vm.msg = 'Hello'
// DOM 還沒(méi)有更新
Vue.nextTick(function () {
  // DOM 更新了
})

---------------------------------------------

在組件內(nèi)部一般使用this.$nextTick()

Vue.component('example', {
  template: '<span>{{ message }}</span>',
  data: function () {
    return {
      message: '沒(méi)有更新'
    }
  },
  methods: {
    updateMessage: function () {
      this.message = '更新完成'
      console.log(this.$el.textContent) // => '沒(méi)有更新'
      this.$nextTick(function () {
        console.log(this.$el.textContent) // => '更新完成'
      })
    }
  }
})

(6) 用filter過(guò)濾器對(duì)金額做(單位,小數(shù))等處理

  • 全局過(guò)濾器vue.filter():所有頁(yè)面都能使用
  • 局部過(guò)濾器filters: { } :只能在當(dāng)前實(shí)例使用
局部過(guò)濾器:

js

filters: {
        formatMoney: function(value, params) {  //value是默認(rèn)參數(shù),params是需要傳入的參數(shù)
            return "¥" + value.toFixed(2) + params;
        }
    }
------------------------------
html

<div class="item-price" >{{ product.productPrice | formatMoney('') }}</div>

<div class="item-price-total">
   {{product.productPrice*product.productQuentity | formatMoney('元') }}
</div>

----------

輸出結(jié)果:¥xx.00
輸出結(jié)果:¥xx.00元

全局過(guò)濾器:

Vue.filter( id, [definition] )
--------------------------------------

參數(shù):
- {string} id
- {Function} [definition]
--------------------------------------

用法:
// 注冊(cè)
Vue.filter('my-filter', function (value) {
  // 返回處理后的值
})

// getter,返回已注冊(cè)的過(guò)濾器
var myFilter = Vue.filter('my-filter')
-------------------------------------------
例子:
Vue.filter('formatMoney', function(value,type) {
      return "¥ "+value.toFixed(2) + type;
} )

(7)單選功能

  • 注意:因?yàn)閱芜x是在循環(huán)列表中,所以不能直接在data里面加狀態(tài)變量,需要在data中的productList數(shù)組中添加checked狀態(tài)變量

html

<div class="cart-item-check">
    <a href="javascipt:;" class="item-check-btn"
         v-bind:class="{ 'check': product.checked }"  //控制ui顯示隱藏的狀態(tài)
         v-on:click="selectedProduct(product)"   //單選功能函數(shù)
    >
         <svg class="icon icon-ok"><use xlink:href="#icon-ok"></use></svg>
   </a>
</div>

------------------------------------------

js

   selectedProduct: function(product) {
    if(typeof product.checked == 'undefined') {
        Vue.set(product,'checked',true)
    } else {
        product.checked = !product.checked
    }
     this.calculateTotalMoney();   //計(jì)算總金額
 }

(8)全選功能和全部刪除功能


html

<div class="cart-foot-l">
   <div class="item-all-check">
      <a href="javascipt:;" v-on:click="checkAll(true)">
          <span class="item-check-btn" v-bind:class="{ 'check': checkedAll }">
              <svg class="icon icon-ok"><use xlink:href="#icon-ok"></use></svg>
          </span>
          <span>全選</span>
      </a>
   </div>
   <div class="item-all-del">
     <a href="javascipt:;" class="item-del-btn" v-on:click="checkAll(false)">
                                取消全選
     </a>
 </div>
</div>
----------------------------------------------

js

data:{
        productList: [],
        showModal: false,
        checkedAll: false, //循環(huán)列表中的class狀態(tài)不能在data中定義,因?yàn)槭莻€(gè)循環(huán)
        totalMoneys:10
    },



checkAll: function(bool) {
            this.checkedAll = bool;
            this.productList.forEach( ( porduct,index ) => {
                if(typeof porduct.checked == 'undefined'){
                    Vue.set(porduct,'checked',this.checkedAll)
                }else{
                    porduct.checked = this.checkedAll;
                }
            });
            this.calculateTotalMoney();
        },
calculateTotalMoney:function() {
            this.totalMoneys = 0 ; //必須先清零,防止重復(fù)點(diǎn)擊的情況
            this.productList.forEach( (item,index) => {
                if(item.checked){  //這里必須篩選出選中狀態(tài),切記記記記記記記記記記記                   
                    this.totalMoneys += item.productPrice * item.productQuentity;
                }
            } )
        }

(9)刪除功能

  • (1) indexOf()

indexOf() 方法可返回某個(gè)指定的字符串值在字符串中首次出現(xiàn)的位置。

stringObject.indexOf(searchvalue,fromindex)
- searchvalue:必需。規(guī)定需檢索的字符串值。
- fromindex:可選的整數(shù)參數(shù)。規(guī)定在字符串中開(kāi)始檢索的位置。
  它的合法取值是 0 到 stringObject.length - 1。如省略該參數(shù),則將從字符串的首字符開(kāi)始檢索。

注釋:indexOf() 方法對(duì)大小寫敏感!
注釋:如果要檢索的字符串值沒(méi)有出現(xiàn),則該方法返回 -1。

例子:
<script type="text/javascript">
var str="Hello world!"
document.write(str.indexOf("Hello") + "<br />")
document.write(str.indexOf("World") + "<br />")  //沒(méi)有出現(xiàn) world+空格 
document.write(str.indexOf("world"))
</script>

輸出結(jié)果:
0
-1
6
  • (2) splice()
splice():

arrayObject.splice(index,howmany,item1,.....,itemX)

- index :必需。整數(shù),規(guī)定添加/刪除項(xiàng)目的位置,使用負(fù)數(shù)可從數(shù)組結(jié)尾處規(guī)定位置。
- howmany:必需。要?jiǎng)h除的項(xiàng)目數(shù)量。如果設(shè)置為 0,則不會(huì)刪除項(xiàng)目。
- item1, ..., itemX:可選。向數(shù)組添加的新項(xiàng)目

購(gòu)物車刪除案列:


js部分

    delateConfirm: function(product) {
            this.showModal = true;
            this.currentItem = product;
        },
    delProduct: function() {
            this.showModal = false;
            var index = this.productList.indexOf(this.currentItem);
                 //在productList中檢索this.currentItem第一次出現(xiàn)的位置
            this.productList.splice(index,1); //刪除的位置是index,數(shù)量是1,返回被刪除的項(xiàng)目
            this.calculateTotalMoney(); //刪除后,重新計(jì)算總價(jià)格
        }

-------------------

html

 <div class="md-modal modal-msg md-modal-transition" 
         id="showModal" 
         v-bind:class="{ 'md-show': showModal }"
 >
            <div class="md-modal-inner">
                <div class="md-top">
                    <button class="md-close" v-on:click="showModal=false">關(guān)閉</button>
                </div>
                <div class="md-content">
                    <div class="confirm-tips">
                        <p id="cusLanInfo" lan="Cart.Del.Confirm">你確認(rèn)刪除此訂單信息嗎?</p>
                    </div>
                    <div class="btn-wrap col-2">
                        <button class="btn btn--m" id="btnModalConfirm" v-on:click="delProduct()">Yes</button>
                        <button class="btn btn--m btn--red" id="btnModalCancel"v-on:click="showModal=false">No</button>
                    </div>
                </div>
            </div>
        </div>

(10) v-for循環(huán)列表的item數(shù)量控制

( computed計(jì)算屬性 ) ( slice分割數(shù)組 )

  • slice() 方法可從已有的數(shù)組中返回選定的元素。

arrayObject.slice(start,end)   //分割數(shù)組,對(duì)比: (   splice() 刪除數(shù)組   )

返回值
返回一個(gè)新的數(shù)組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素。

說(shuō)明
請(qǐng)注意,該方法并不會(huì)修改數(shù)組,而是返回一個(gè)子數(shù)組。
如果想刪除數(shù)組中的一段元素,應(yīng)該使用方法 Array.splice()。

(1) start:必需。
規(guī)定從何處開(kāi)始選取。如果是負(fù)數(shù),那么它規(guī)定從數(shù)組尾部開(kāi)始算起的位置。
也就是說(shuō),-1 指最后一個(gè)元素,-2 指倒數(shù)第二個(gè)元素,以此類推。

(2) end:可選。
規(guī)定從何處結(jié)束選取。該參數(shù)是數(shù)組片斷結(jié)束處的數(shù)組下標(biāo)。如果沒(méi)有指定該參數(shù),
那么切分的數(shù)組包含從 start 到數(shù)組結(jié)束的所有元素。
如果這個(gè)參數(shù)是負(fù)數(shù),那么它規(guī)定的是從數(shù)組尾部開(kāi)始算起的元素。

下面是購(gòu)物車選址實(shí)例:

js

computed: {
        filteAddress:function (){
            return this.addressList.slice(0,3)        }
    },
//addressList是請(qǐng)求的json數(shù)據(jù),存放在data中

//這里需要注意:
// slice()  返回的是全新的數(shù)組,不會(huì)破壞原數(shù)組addressList。
// splice() 會(huì)對(duì)addressList直接進(jìn)行刪除操作。

--------------------------------------

html

 <li v-for=" (item,index) in filteAddress ">

(11) 點(diǎn)擊more加載所有的地址列表

js部分


 var vm = new Vue({
    el:".container",
    data: {
        addressList: [],
        addressLength:3
    },
    computed: {
        filteAddress:function (){
            return this.addressList.slice(0,this.addressLength)
        }
    },
    methods: {
        showAllAddresss: function() {
            // return this.addressList; 這里不能直接返回addressList,因?yàn)檠h(huán)的是filteAddress
            this.addressLength = this.addressList.length;   //改變data從而改變computed
        }
    }
});
----------------------------------------------------



html部分

 <div class="shipping-addr-more" v-on:click="showAllAddresss()">
            ...
 </div>
--------------------

也可以在click中直接寫表達(dá)式,如下面這樣:
 <div class="shipping-addr-more" v-on:click="addressLength = addressList.length">
            ...
 </div>


注意:在指令里面( v-xxx ),在視圖view中 ( html )中都不要使用this
注意:在指令里面( v-xxx ),在視圖view中 ( html )中都不要使用this
注意:在指令里面( v-xxx ),在視圖view中 ( html )中都不要使用this

(12) 點(diǎn)擊選中某一個(gè)卡片

  <li v-for=" (item,index) in filteAddress "
      v-bind:class="{ 'check' : index == currentCard }"
      v-on:click=" currentCard = index"
  >

解析: 
當(dāng)點(diǎn)擊某個(gè)卡片的時(shí)候,讓該卡片的 index 賦值給currentCard 變量,
而當(dāng)index==currentCard ,就出現(xiàn)check的ui狀態(tài)

(12) 設(shè)為默認(rèn)卡片

js部分:

setDefaultAddress: function(addressId) {
            this.addressList.forEach( (item,index) => {
                if( item.addressId == addressId ){
                    item.isDefault = true
                }else{
                    item.isDefault = false
                }
            })
        }
-----------------------------------------------

html部分

  <div class="addr-opration addr-set-default"
       v-if="!item.isDefault"
       v-on:click="setDefaultAddress(item.addressId)"
   >
     <a href="javascript:;" class="addr-set-default-btn" ><i>設(shè)為默認(rèn)</i></a>
 </div>

 <div class="addr-opration addr-default" v-if="item.isDefault">默認(rèn)地址</div>

解析: 

如果點(diǎn)擊的是第三個(gè)卡片,傳過(guò)來(lái)的卡片的id=3,
而在循環(huán)addressList中,假如正在循環(huán)的是第一個(gè)卡片,那么卡片id是1,
  1 != 3,
所以執(zhí)行:item.isDefault = false,所以第一個(gè)卡片不顯示(默認(rèn)地址)

(13) 只切換兩張選項(xiàng)卡

  <ul>
      <li  v-bind:class="{'check': switchPeisong == 1 }" v-on:click=" switchPeisong = 1">
            <div class="name" >標(biāo)準(zhǔn)配送</div>
             <div class="price">Free</div>
      </li>
      <li  v-bind:class="{'check': switchPeisong == 2 }" v-on:click=" switchPeisong = 2">
              <div class="name">高級(jí)配送</div>
              <div class="price">180</div>
      </li>
  </ul>
購(gòu)物車
購(gòu)物車地址
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容