1. 程式人生 > >在前後端分離的專案中用vue寫電商的搜尋功能和分頁

在前後端分離的專案中用vue寫電商的搜尋功能和分頁

1,在mock.js中模擬資料

//搜尋商品初始化資料
Mock.mock("/search-service/goods", "get", {
    "count": "@integer(100,200)",
    "data|5-15": [{
        "id|+1": 1,
        "goods_name": "@ctitle(2,6)",
        "price": "@float(0.01,9999)",
        "midlogo": "@dataImage(130x130)",
        "comment_count": "@integer(0,9999)"
    }]
})

2,api.js中傳送ajax請求

//搜尋商品初始化資料
function searchGoods(search){
    return axios.get("/search-service/goods",{
        params:search
    })
}

3,初始化頁面引數

<script>
var vm = new Vue({
		el: "#app",
		data: {
			goods: [],	//頁面所有商品資訊
			totalCount: 0,//總記錄數
			totalPage: 0, //總頁數
			brands: [], //品牌
			specs: [],//規格資料
			search: { //搜尋的資料
				catid: parseInt(location.search.match(/id=\d+/)[0].split("=")[1]),
				brand_id: "",
				spec_list: [],
				min_price: "",
				max_price: "",
				per_page: 10,
				page: 1,
				sort_by: "xl",
				sort_way: "desc"
			}
		},
			methods: {
			updataGoods(){
				searchGoods(this.search).then(res => {
				//商品資訊
				this.goods = res.data.data
				//設定總的記錄數
				this.totalCount = res.data.count
				//計算頁數
				this.totalPage = Math.ceil(this.totalCount / this.search.per_page)

			})
			},
			},
      created() {
			//搜尋商品
		this.updataGoods()
})
</script>

4 顯示商品資訊

<!-- 商品列表 start-->
				<div class="goodslist mt10">
					<ul>
						<li v-for="(v,k) in goods">
							<dl>
								<dt><a :href="'goods.html?id='+ v.id"><img :src="v.midlogo" alt="" /></a></dt>
								<dd><a href="">{{v.goods_name}}</a></dt>
								<dd><strong>¥{{v.price}}</strong></dt>
								<dd><a href=""><em>已有{{v.comment_count}}人評價</em></a></dt>
							</dl>
						</li>

					</ul>
				</div>
				<!-- 商品列表 end-->

執行效果圖
在這裡插入圖片描述
5,分頁
【第一步】引入js庫檔案
ElementUI是vue的UI庫,必須依賴Vue,所以使用ElementUI必須先匯入Vue,然後匯入ElementUI資原始檔
http://element.eleme.io/#/zh-CN(這是學習網站)
5.1 根據官方網址先引入兩個樣式

    <script src="js/vue.js"></script>
    <!-- 引入樣式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入元件庫 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>

5.2 在分頁的位置匯入分頁程式碼
page-size 每頁顯示條目個數,支援 .sync 修飾符
page-sizes 每頁顯示個數選擇器的選項設定
current-page 當前頁數,支援 .sync 修飾符
layout 元件佈局,子元件名用逗號分隔
total 總條目數

   <!-- 分頁資訊 start -->
    				<el-pagination
    				@size-change="handleSizeChange"
    				@current-change="handleCurrentChange"
    				:current-page="search.page"
    				:page-sizes="[10, 20, 30, 100]"
    				:page-size="search.per_page"
    				layout="total, sizes, prev, pager, next, jumper"
    				:total="totalCount">
    			  </el-pagination>
    				<!-- 分頁資訊 end -->

5.3 根據分析:需要的操作如下
1 實現handleSizeChange函式-每頁顯示條數修改觸發的函式

handleSizeChange(val) {
				this.search.per_page = val
				this.updataGoods()
			},
			handleCurrentChange(val) {
				this.search.page = val
				this.updataGoods()

			}

在這裡插入圖片描述

6,商品排序–點選選中
在這裡插入圖片描述
【實現思路】將按鈕資料與sort_by 和sort_way進行繫結,當點選按鈕更換的時候,更換sort_by 和sort_way的值

<!-- 排序 start -->
				<div class="sort mt10">
					<dl>
						<dt>排序:</dt>
						<dd :class="{cur:search.sort_by == 'xl'}" @click.prevent="setSort('xl')"><a href="">銷量</a></dd>
						<dd :class="{cur:search.sort_by == 'jg'}" @click.prevent="setSort('jg')"><a href="">價格
								<span v-if="search.sort_by=='jg' && search.sort_way =='asc'">↑</span>
								<span v-if="search.sort_by=='jg' && search.sort_way =='desc'">↓</span>
							</a></dd>
						<dd :class="{cur:search.sort_by == 'pl'}" @click.prevent="setSort('pl')"><a href="">評論數</a></dd>
						<dd :class="{cur:search.sort_by == 'sj'}" @click.prevent="setSort('sj')"><a href="">上架時間</a></dd>
						價格:
						<input min="1" type="number" v-model="search.min_price" style="width: 50px" placeholder="¥">-
						<input min="1" type="number" v-model="search.max_price" style="width: 50px" placeholder="¥">
						<input @click="updataGoods" type="button" value="搜尋">
					</dl>
				</div>
				<!-- 排序 end -->

6.2.

setSort(sortBy) {
					//設定排序資料
					this.search.sort_by = sortBy
					// 如果點選的是價格就修改排序方式,否則就設定為降序
					if (sortBy == 'jg') {
						// 修改排序方式
						this.search.sort_way = this.search.sort_way == "desc" ? "asc" : "desc"
					} else {
						// 只要不是價格就設定成降序
						this.search.sort_way = "desc"
					}
					// 更新資料
					this.updataGoods()
				},

7, 搜尋商品-從伺服器獲取品牌
在這裡插入圖片描述
分析:品牌和分類是相關的,所以需要根據分類id查找出品牌
7.2

//獲得品牌
Mock.mock(/\/brands\/\d+/, "get", {
    "data|5-15": [{
        "id": "@id",
        "brand_name": "@ctitle(2,6)",
        "logo": "@dataImage(98x35)"
    }]
})

7.3

  //獲得品牌
    function getBrand(catid) {
        return axios.get("/web-service/brands/" + catid)
    }

7.4

created() {
			this.updataGoods()
			//獲得品牌資訊
			getBrand(this.search.catid).then(res => {
				this.brands = res.data.data
			}),
				//獲取規格資料
				getSpecifications(this.search.catid).then(res => {
					this.specs = res.data.data
				})
		}


	})

8,在頁面中顯示資料

<!-- 商品篩選 start -->
				<div class="filter mt10">
					<h2><a href="">重置篩選條件</a> <strong>商品篩選</strong></h2>
					<div class="filter_wrap">
						<dl>
							<dt>品牌:</dt>
							<dd class="cur"><a href="">不限</a></dd>
							<dd v-for="(v, k) in brands"><a href="">{{v.brand_name}}</a></dd>

					
				</div>
				<!-- 商品篩選 end -->

在這裡插入圖片描述
8.1 品牌的選中狀態
在這裡遇到一個 You may have an infinite update loop in a component render function.無限迴圈,原因在寫少寫一個等號
鑑於vue非常的靈活,

<dl>
							<dt>品牌:</dt>
							<dd :class="{cur:search.brand_id ==''}"><a @click.prevent="setBrand('')" href="">不限</a></dd>
							<dd v-for="(v, k) in brands"  :class="{cur:search.brand_id ==v.id}"><a  @click.prevent="setBrand(v.id)" href="">{{v.brand_name}}</a></dd>

						</dl>

8.2

setBrand(id){
				this.search.brand_id = id
				this.updataGoods()
			},

在這裡插入圖片描述
在這裡插入圖片描述

9,搜尋商品-獲取規格

準備資料

   //規格資料
    Mock.mock(/\/specifications\/\d+/, "get", {
        "data|2-5": [{
            "id": "@id",
            "spec_name": "@ctitle(2,6)",
            "selectd": "",  //當前勾選的規格的值
            "options|5-15":[{
                "id":"@id",
                "option_name":"@ctitle"
            }]
        }]
    })
//規格資料
function getSpecifications(catid){
    return axios.get("/web-service/specifications/" + catid)
}

在這裡插入圖片描述
在這裡插入圖片描述

<dl v-for="(v,k) in specs">
						<dt>{{v.spec_name}}:</dt>
						<dd :class="{cur:v.selected ==''}"><a @click.prevent="setSpec(k,'')" href="">不限</a></dd>
						<dd :class="{cur:v.selected== v1.option_name}" v-for="(v1,k1) in v.options">
							<a @click.prevent="setSpec(k,v1.option_name)" href="">{{v1.option_name}}</a>
						</dd>
					</dl>

9.2

//設定規格
			setSpec(k,value) {
				// 設定當前點選規格的值
				this.specs[k].selected = value
				// 呼叫updataGoods前,先將specs給spec_list
				this.search.spec_list = this.specs
				this.updataGoods()

			},

在這裡插入圖片描述