在 src/restful/api.js 中寫入添加購物車接口:javascript
// 加入購物車的接口 export const shopCart = (params) => { return Axios.post('user/shop_cart/create/', params).then(res=>res.data) };
Axios 的攔截器:在請求或響應被 then
或 catch
處理前攔截它們,說明文檔:Axios使用說明。模板以下所示:html
// 添加請求攔截器 axios.interceptors.request.use(function (config) { // 在發送請求以前作些什麼 return config; }, function (error) { // 對請求錯誤作些什麼 return Promise.reject(error); }); // 添加響應攔截器 axios.interceptors.response.use(function (response) { // 對響應數據作點什麼 return response; }, function (error) { // 對響應錯誤作點什麼 return Promise.reject(error); });
在項目 src/restful/api.js 中添加請求攔截器:vue
import Axios from 'axios' // 導入axios Axios.defaults.baseURL = 'https://www.luffycity.com/api/v1/'; // 設置公共url // 添加請求攔截器 Axios.interceptors.request.use(function (config) { // 在發送請求以前作些什麼 if (localStorage.getItem('access_token')){ // 配置的默認值/defaults // Axios.defaults.headers.common['Authorization'] = localStorage.getItem('access_token'); console.log(config.headers); config.headers.Authorization = localStorage.getItem('access_token'); } return config; }, function (error) { // 對請求錯誤作些什麼 return Promise.reject(error); });
查看控制檯 config.headers 中包含的信息:java
添加購物車首先要獲取當前課程信息。ios
<script> export default { name: 'CourseDetail', data(){ return { // 聲明變量存儲數據 coursedetailtop: {}, // 課程頂部詳情數據 content: "", // currentIndex: 0, // 爲0時,頁面刷新默認選擇了第一項 currentIndex: null, // 默認不選擇 prices: [] } }, methods: { // 加入購物車事件 addShopCart(){ if(this.currentIndex){ // 判斷當前currentIndex是否有值 if(window.localStorage.getItem('access_token')){ // 判斷用戶是否登陸 // 添加到購物車 alert('買吧'); let course = { courseId: this.$route.params.detailId, // 課程id validPeriodId: this.prices[this.currentIndex].valid_period, }; console.log(course); // this.$http.shopCart(); } else { // 跳轉登陸頁面 // 使用編程式導航來跳轉// 代碼略 </script>
在控制檯查看打印的course對象:web
methods: { // 加入購物車事件 addShopCart(){ if(this.currentIndex){ // 判斷當前currentIndex是否有值 if(window.localStorage.getItem('access_token')){ // 判斷用戶是否登陸 // 添加到購物車 alert('買吧'); let course = { courseId: this.$route.params.detailId, // 課程id validPeriodId: this.prices[this.currentIndex].valid_period, }; console.log(course); this.$http.shopCart(course) .then(res=>{ console.log("當前添加是否成功", res); }) .catch(err=>{ console.log('添加失敗', err); }) } else { // 跳轉登陸頁面 // 使用編程式導航來跳轉 this.$router.push({ name: 'Login', query: { // window.location 只讀屬性,返回一個 Location 對象,其中包含有關文檔當前位置的信息 return_url: window.location.href, // 將當前頁面地址做爲查詢參數 } }) } } else { // element組件錯誤提示 this.$message({ message: '您尚未選擇要加入的套餐哦!', center: true // 使用 center 屬性讓文字水平居中 }); } },
點擊添加購物車顯示效果以下:編程
購物車沒有當前課程時,點擊添加後,信息爲error_no:0,顯示 「添加成功」。axios
若是購物車已經有了當前課程,選擇一個套餐後點擊添加,信息爲error_no:10,顯示「購物車中該課程已更新成功」。api
elementui中Message消息提示:經常使用於主動操做後的反饋提示。這裏引入基礎用法,從頂部出現,3秒後自動消失。數組
methods: { // 加入購物車事件 addShopCart(){ if(this.prices[this.currentIndex]){ // 不能直接使用this.currentIndex,由於第一個值爲0 if(window.localStorage.getItem('access_token')){ // 判斷用戶是否登陸 // 添加到購物車 alert('買吧'); let course = { courseId: this.$route.params.detailId, // 課程id validPeriodId: this.prices[this.currentIndex].valid_period, }; console.log(course); this.$http.shopCart(course) .then(res=>{ console.log("當前添加是否成功", res); if(res.error_no===0){ this.$message('購物車' + res.data.status); // elementui提示框 } if(res.error_no===10){ this.$message(res.msg); } }) .catch(err=>{ console.log('添加失敗', err); }) } else { // 跳轉登陸頁面 // 使用編程式導航來跳轉 this.$router.push({ name: 'Login', query: { // window.location 只讀屬性,返回一個 Location 對象,其中包含有關文檔當前位置的信息 return_url: window.location.href, // 將當前頁面地址做爲查詢參數 } }) } } else { // element組件錯誤提示 this.$message({ message: '您尚未選擇要加入的套餐哦!', center: true // 使用 center 屬性讓文字水平居中 }); } },
選擇套餐後點擊「加入購物車」,顯示以下信息:
// 代碼略 import Cart from '@/components/Cart/Cart' Vue.use(Router); // 配置路由規則 export default new Router({ linkActiveClass: 'is-active', mode: 'history', // 改成history模式 routes: [ // 代碼略 // 購物車頁面 { path: '/purchase/shopping_cart', name: 'purchase.shop', component: Cart } ] })
建立購物車文件夾及文件:src/components/Cart/Cart.vue
使用elementUI中Table表格模板來構築組件頁面結構。Table表格可用於展現多條結構相似的數據,可對數據進行排序、篩選、對比或其餘自定義操做。
實現多選很是簡單: 手動添加一個el-table-column
,設type
屬性爲selection
便可。每一個 el-table-column 組件中有 template,能夠定義當前內容的展現。
scope.row至關於獲取了數組中的每一條數據。
<template> <div class="shopping-cart-wrap"> <h3 class="shopping-cart-tit">個人購物車<small>共1門課程</small></h3> <div class="row"> <el-table ref="multipleTable" :data="shopCartList" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55"> </el-table-column> <el-table-column label="日期" width="120"> <template slot-scope="scope">{{ scope.row.date }}</template> </el-table-column> <el-table-column prop="name" label="姓名" width="120"> </el-table-column> <el-table-column prop="address" label="地址" show-overflow-tooltip> </el-table-column> </el-table> </div> <div class="total"> <el-button type="primary">去結算</el-button> <h3>總計: ¥399</h3> </div> </div> </template> <script> export default { name:'Cart', data(){ return { } }, }; </script>
<div class="nav-right" v-if="userInfo.access_token" @mouseenter="enterHandler" @mouseleave="leaveHandler"> <span class = 'el-dropdown-link'>學習中心</span> <span class="user">{{userInfo.username}}</span> <img :src="userInfo.avatar" alt=""> <ul class="my_account" v-show="isShow"> <li>個人帳戶<i>></i></li> <li>個人訂單<i>></i></li> <li>個人優惠券<i>></i></li> <li>個人消息<span class="msg">({{userInfo.notice_num}})</span><i>></i></li> <li @click="shopCartInfo">購物車<span class="count">({{userInfo.shop_cart_num}})</span></li> <li>退出<i>></i></li> </ul> </div> methods: { shopCartInfo(){ // 跳轉到購物車路由 this.$router.push({ name: 'purchase.shop' }) },
在 src/restful/api.js 添加以下信息:
// 購物車數據 export const shopCartList = () => { return Axios.get('user/shop_cart/list/').then(res=>res.data); };
修改Cart.vue組件。
handleSelectionChange(val) { this.multipleSelection = val; } 其中,val 爲選中數據的集合。經過this.multipleSelection.prop字段 取得每個選項的值,prop字段就是表格裏面子項的prop值。this.multipleSelection.length爲選擇了多少項。
<script> export default { name:'Cart', data(){ return { multipleSelection: [], // 存放選中的當前數據 shopCartList: [], } }, methods: { getShopCartList(){ this.$http.shopCartList() .then(res=>{ console.log(res); if(res.error_no === 0){ this.shopCartList = res.data.myShopCart; } }) .catch(err=>{ console.log(err); }) }, handleSelectionChange(val){ // 處理點選 this.multipleSelection = val; } }, created() { this.getShopCartList(); } }; </script>
javascript:void(0) 中最關鍵的是 void 關鍵字, void 是 JavaScript 中很是重要的關鍵字,該操做符指定要計算一個表達式可是不返回值。
有效期欄目中,添加select組件,點選到對應的有效期。HTML <select>
元素表示一個控件,提供一個選項菜單。菜單內的選項爲
, 能夠由 <option>
元素分組。選項能夠被用戶預先選擇。<optgroup>
<div class="row"> <el-table ref="multipleTable" :data="shopCartList" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55"> </el-table-column> <el-table-column label="課程" width="555"> <template slot-scope="scope"> <img :src="scope.row.courseImg" alt=""> <a href="javascript:void(0);">{{scope.row.courseName}}</a> </template> </el-table-column> <el-table-column prop="name" label="有效期" width="212"> <template slot-scope="scope"> <select> <option v-for="(item, index) in scope.row.validPeriodChoices" :value="item.validPeriodId" :key="index"> 有效期: {{item.validPeriodId}} </option> </select> </template> </el-table-column> <el-table-column prop="address" label="單價" show-overflow-tooltip> <template slot-scope="scope"> ¥{{scope.row.coursePrice}} </template> </el-table-column> </el-table> </div>
顯示效果以下所示:
在select中,當v-model的值等於option中的value,則默認選中。
<el-table-column prop="name" label="有效期" width="212"> <template slot-scope="scope"> <select v-model="scope.row.validPeriodId"> <option v-for="(item, index) in scope.row.validPeriodChoices" :value="item.validPeriodId" :key="index"> 有效期: {{item.validPeriodId}} </option> </select> </template> </el-table-column>
@click.native.prevent:調用組件原生的click事件,阻止默認事件發生。在封裝好的組件上使用,因此要加上.native才能click。
prevent就至關於 event.preventDefault():若是此事件沒有被顯式處理,那麼它默認的動做也不要作(由於默認是要作的)。此事件仍是繼續傳播,除非碰到事件偵聽器調用stopPropagation()
或stopImmediatePropagation()
,才中止傳播。
<el-table> <!--代碼略--> <el-table-column fixed="right" label="操做" width="100"> <template slot-scope="scope"> <el-button @click.native.prevent="deleteRow(scope.$index, shopCartList)" type="text" size="small"> 刪除 </el-button> <el-button type="text" size="small">編輯</el-button> </template> </el-table-column> </el-table>
未完成
methods: { // 刪除課程 deleteRow(index, rows){ console.log(index); console.log(rows); rows.splice(index, 1); },
使用computed實時監控鼠標點選課程總價變化。
computed: { totalPrice(){ let total_price = 0; this.multipleSelection.forEach((item,index)=>{ // 遍歷數組中對象的價格 // parseInt() 方法用於將字符串參數做爲有符號的十進制整數進行解析 total_price += parseInt(item.coursePrice) // 將獲取的價格相加 }); return total_price; } },
顯示效果以下所示