Vue項目實戰:購物車頁面實現與ElementUI集成

目錄

1. 購物車頁面

2. ElementUI集成

3. Babel介紹

購物車頁面

(1)Order-Header組件

  • 在Order-Header.vue中:
<template>
    <div class="order-header">
        <div class="container clearfix">
            <div class="header-logo">
                <a href="/#/index"></a>
            </div>
            <div class="title">
                <h2>{{title}}<slot name="tip"></slot></h2>
            </div>
            <div class="username">
                <a href="javascript:;">{{username}}</a>
            </div>
        </div>
    </div>
</template>
<script>
import {mapState} from 'vuex'
export default {
    name:'order-header',
    props: {
        title:String, 
    },
    computed: {
        ...mapState(['username'])
    }
}
</script>
<!--省略樣式-->
  • 在使用該樣式的文件中:
        <order-header title="我的購物車">
            <template v-slot:tip>
                <span>溫馨提示:產品是否購買成功,以最終下單爲準哦,請儘快結算。</span>
            </template>    
        </order-header> 

(2)購物車列表渲染

在cart.vue中:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-s2gwmOkK-1586148382756)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\1585986466180.png)]

        <div class="cart-box">       
          <ul class="cart-item-head">
            <li class="col-1"><span class="checkbox" v-bind:class="{'checked':allChecked}"></span>全選</li>
            <li class="col-3">商品 名稱</li>
            <li class="col-1">單價</li>
            <li class="col-2">數量</li>
            <li class="col-1">小計</li>
            <li class="col-1">操作</li>
          </ul>
            
          <ul class="cart-item-list">
            <li class="cart-item" v-for="(item,index) in list" v-bind:key="index">
              <div class="item-check">
                <span class="checkbox" v-bind:class="{'checked':item.productSelected}"></span>
              </div>
              <div class="item-name">
                <img v-lazy="item.productMainImage" alt="">
                <span>{{item.productName + ' , ' + item.productSubtitle}}</span>
              </div>
              <div class="item-price">{{item.productPrice}}</div>
              <div class="item-num">
                <div class="num-box">
                  <a href="javascript:;">-</a>
                  <span>{{item.quantity}}</span>
                  <a href="javascript:;" >+</a>
                </div>
              </div>
              <div class="item-total">{{item.productTotalPrice}}</div>
              <div class="item-del"></div>
            </li>
          </ul>   
        </div>
     
        <div class="order-wrap clearfix">
          <div class="cart-tip fl">
            <a href="/#/index">繼續購物</a><span>{{list.length}}</span>件商品,已選擇<span>{{checkedNum}}</span></div>
          <div class="total fr">
            合計:<span>{{cartTotalPrice}}</span><a href="javascript:;" class="btn">去結算</a>
          </div>
        </div>

<script>
export default {
    name: 'cart',
    data() {
        return {
            list: [],
            allChecked: false,
            cartTotalPrice:0,
            checkedNum:0
        }
    },
    mounted() {
        this.getCartList();
    },
    methods: {
        getCartList() {
            this.axois.get('/carts').then((res) => {
                this.list = res.cartProductVoList || [];
                this.allChecked = res.selectedAll;
                this.cartTotalPrice =res.cartTotalPrice;
                this.checkedNum = this.list.filter(item => item.productSelected).length;

            })
        }
    }
}
</script>

(3)購物車全選和非全選

在cart.vue中添加:

 <!--添加click事件在span元素上-->  
          <ul class="cart-item-head">
            <li class="col-1"><span class="checkbox" v-bind:class="{'checked':allChecked}"  @click="toggleAll"></span>全選</li>
            <li class="col-3">商品 名稱</li>
            <li class="col-1">單價</li>
            <li class="col-2">數量</li>
            <li class="col-1">小計</li>
            <li class="col-1">操作</li>
          </ul>
            
<script>
export default {
    data() {
        return {
            list: [],
            allChecked: false,
            cartTotalPrice:0,
            checkedNum:0
        }
    },
    mounted() {
        this.getCartList();
    },
    methods: {
        getCartList() {
            this.axois.get('/carts').then((res) => {
                this.renderData(res);

            })
        },
        toggleAll() {
            let url = this.allChecked ? '/carts/unSelectAll' : '/carts/selectedAll';
            this.axois.put(url).then((res) => {
                this.renderData(res);


            })
        },
         renderData(res) {
             this.list = res.cartProductVoList || [];
             this.allChecked = res.selectedAll;
             this.cartTotalPrice = res.cartTotalPrice;
             this.checkedNum = this.list.filter(item => item.productSelected).length;
         }
    }
}
</script>

(4)購物車商品更新和刪除

在cart.vue中添加:

          <ul class="cart-item-list">
            <li class="cart-item" v-for="(item,index) in list" v-bind:key="index">
              <div class="item-check">
                <span class="checkbox" v-bind:class="{'checked':item.productSelected}"  @click="updateCart(item)"></span>
              </div>
              <div class="item-name">
                <img v-lazy="item.productMainImage" alt="">
                <span>{{item.productName + ' , ' + item.productSubtitle}}</span>
              </div>
              <div class="item-price">{{item.productPrice}}</div>
              <div class="item-num">
                <div class="num-box">
                  <a href="javascript:;" @click="updateCart(item,'-')">-</a>
                  <span>{{item.quantity}}</span>
                  <a href="javascript:;"  @click="updateCart(item,'+')">+</a>
                </div>
              </div>
              <div class="item-total">{{item.productTotalPrice}}</div>
              <div class="item-del" @click="delProduct(item)"></div>
            </li>
          </ul
<script>
export default {
    //在methods中添加兩個方法。
    methods: {
        updateCart(item, type) {
            let quantity = item.quantity,
                selected = item.productSelected;
            if (type == '-') {
              if (quantity == 1) {
                alert('商品至少保留一件');
                return;
              }
              -- quantity;
            } else if (type == "+") {
              if (quantity > item.productStock) {
                alert('商品不能超過庫存數量');
                return;
              }
              ++ quantity;
            } else {
              selected = !item.productSelected;
            }
            this.axois.put(`/carts/${item.productId}`,{
              quantity,
              selected
            }).then((res) => {
              this.renderData(res)
            })

        },
        delProduct(item) {
          this.axois.delete(`/carts/${item.productId}`).then((res) => {
            this.renderData(res)
          })
        }              
   }
}
</script>

(5)購物車結算

在cart.vue中添加:

<a href="javascript:;" class="btn" @click="order">去結算</a>
<script>
export default {
    //在methods中添加兩個方法。
    methods: {
        //購物車下單
        order() {
          let isCheck = this.list.every( item => !item.productSelected);
          if (isCheck) {
            alert('請選擇一件商品')
          } else {
            this.$router.push('/order/confirm');
          }
        }
    }
}
</script>

ElementUI集成

  • 安裝ElementUI與balel-plugin-component:

    npm i element-ui babel-plugin-component --save-dev

  • 安裝@babel/preset-env:

    npm i @babel/preset-env -D

  • 在項目根目錄下創建文件.babelrc,並添加配置:

{
    "presets": [["@babel/preset-env", {"modules": false}]],
    "plugins": [
        [
            "component",
            {
                "libraryName": "element-ui",
                "styleLibraryName": "theme-chalk"
            }
        ]
    ]
}

下面以使用ElementUI中的Message插件爲例:

由於Message是一個插件,插件有兩種使用方式。

第1種是在使用到的文件中導入。如:

  • 在main.js中引入ElementUI並使用:
import {Message} from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

axios.interceptors.response.use(function(response) {
  let res = response.data;
  let path = location.hash;
  if (res.status == 0) {
    return res.data;
  } else if (res.status == 10) {
      if (path != '#/index') {
        window.location.href = '/#/login';
        
      } 
      return Promise.reject(res);
  } else {
    Message.warning(res.msg);  //使用ElementUI
    return Promise.reject(res);
  }
})
  • 在cart.vue中使用:
<script>
import {Message} from 'element-ui'
//購物車下單
        order() {
          let isCheck = this.list.every( item => !item.productSelected);
          if (isCheck) {
            Message.warning('請選擇一件商品')
          } else {
            this.$router.push('/order/confirm');
          }
        }
</script>

第2中是通過prototype將其擴展到Vue原型上,通過this調用。如:

  • 在main.js中引入ElementUI並使用:
import {Message} from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.prototype.$message = Message;

axios.interceptors.response.use(function(response) {
  let res = response.data;
  let path = location.hash;
  if (res.status == 0) {
    return res.data;
  } else if (res.status == 10) {
      if (path != '#/index') {
        window.location.href = '/#/login';
        
      } 
      return Promise.reject(res);
  } else {
    this.$message.warning(res.msg);  //使用ElementUI
    return Promise.reject(res);
  }
})
  • 在cart.vue中使用:
<script>
//購物車下單
        order() {
          let isCheck = this.list.every( item => !item.productSelected);
          if (isCheck) {
            this.$message.warning('請選擇一件商品')
          } else {
            this.$router.push('/order/confirm');
          }
        }
</script>

Babel介紹

Babel 是一個JavaScript編譯器

Babel是一個工具鏈,主要用於將ECMAScript2015+版本的代碼轉換爲向後兼容的JavaScript語法,以便能夠運行在當前和就版本的瀏覽器或其他環境中。

  • 將文件.babelrc合併到babel.config.js,並刪除該文件:
{
    "presets": [["@babel/preset-env", {"modules": false}]],
    "plugins": [
        [
            "component",
            {
                "libraryName": "element-ui",
                "styleLibraryName": "theme-chalk"
            }
        ]
    ]
}
  • 在babel.config.js中:
module.exports = {
  "presets": [
    '@vue/cli-plugin-babel/preset'
  ],
  "plugins": [
    [
        "component",
        {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
        }
    ]
]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章