一、效果图
二、代码
首先由首页顶部的搜索跳转到真正的搜索页面,输入内容后回车即可完成搜索(假数据,无请求数据 )
① 首页布局
<template>
<view class="index">
<view class="index_header">
<view class="header_search u-flex" @click="goSearch('/pages/search/search')">
<image src="@/static/icon/search.png"></image>
<swiper :indicator-dots="false" autoplay :interval="3000" :duration="200" vertical circular>
<swiper-item class="u-flex" v-for="(item, index) in searchHotWords" :key="index">
<text>{{ item.queryName }}</text>
</swiper-item>
</swiper>
</view>
</view>
<!-- 轮播图 -->
<view class="banner_main">
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
<swiper-item class="swiper_item" v-for="(item, index) in swiperList" :key="item.id">
<image :src="item.image_url"></image>
</swiper-item>
</swiper>
</view>
<!-- 精品内容 -->
<view class="index_boutique">
<view class="boutique_title">
<view class="title_name">精选品牌</view>
<view class="title_more">更多<text decode="true">{{`>`}}</text> </view>
</view>
<view class="boutique_flex">
<view class="flex_item" v-for="(item,index) in boutiqueData" :key="index">
<image :src="item.icon"></image>
<text>{{item.name}}</text>
</view>
</view>
</view>
<!-- 秒杀内容 -->
<view class="index_goodsSeckill" v-for="(item,index) in 2" :key="index">
<view class="goodsSeckill_title">
<view>精品好货限时秒杀</view>
<view>更多<text decode="true">{{`>`}}</text> </view>
</view>
<scroll-view scroll-x="true" class="scroll_x">
<view class="group">
<view class="group_item" v-for="(item,index) in groupData" :key="index">
<image :src="item" ></image>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
searchHotWords: [], //上下轮播
swiperList: [
{
id: 0,
image_url: 'https://img1.baidu.com/it/u=3607749763,1307051166&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=395'
},
{
id: 1,
image_url: 'https://img2.baidu.com/it/u=3787232916,2002133981&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=330'
},
{
id: 2,
image_url: 'https://img1.baidu.com/it/u=1747903847,3582374480&fm=253&fmt=auto&app=138&f=JPEG?w=640&h=340'
},
],
boutiqueData:[
{
name:'最新产品',
icon:'https://img2.baidu.com/it/u=985455910,26809051&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
},
{
name:'商城优惠',
icon:'https://img0.baidu.com/it/u=3121986855,4254644576&fm=253&fmt=auto&app=138&f=JPEG?w=192&h=192'
},
{
name:'耐克',
icon:'https://img2.baidu.com/it/u=1448619545,1082052059&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889'
},
{
name:'匡威',
icon:'https://img0.baidu.com/it/u=3829531841,2525898258&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=888'
},
{
name:'安踏',
icon:'https://img2.baidu.com/it/u=2638020669,1516398200&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
},
{
name:'特步',
icon:'https://img2.baidu.com/it/u=565884609,3441124675&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200'
},
{
name:'回力',
icon:'https://img1.baidu.com/it/u=3541707458,1538767806&fm=253&fmt=auto&app=138&f=JPEG?w=325&h=260'
},
{
name:'安德玛',
icon:'https://img0.baidu.com/it/u=3641495928,1121782624&fm=253&fmt=auto&app=120&f=JPEG?w=550&h=597'
},
{
name:'更多',
icon:'https://img2.baidu.com/it/u=277836883,1911262877&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
}
],
groupData:[
'https://ecmb.bdimg.com/tam-ogel/-2064240070_1019900854_300_200.jpg',
'https://ecmb.bdimg.com/tam-ogel/-1695554568_836595986_300_200.jpg',
'https://ecmb.bdimg.com/tam-ogel/472596168_-952405378_300_200.jpg',
'http://t14.baidu.com/it/u=1046111119,3304410177&fm=224&app=112&f=JPEG?w=500&h=500',
'http://t15.baidu.com/it/u=2301462117,1422483236&fm=224&app=112&f=JPEG?w=500&h=500'
]
}
},
onLoad() {
this.getHotWords()
},
methods: {
getHotWords() {
uni.request({
url: 'https://api.tian-x.cn/api/Search/placeHolder',
}).then(res => {
console.log('res', res[1].data.data);
if (res[1].data.data.length != 0) {
this.searchHotWords = res[1].data.data
} else {
this.searchHotWords.push({
queryName: '搜一搜'
})
}
})
},
// 跳转搜索页
goSearch(url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="less">
page {
background-color: #F7F7F7;
}
.u-flex {
display: flex;
flex-direction: row;
align-items: center;
}
.index {
.index_header {
padding: 0 20rpx;
.header_search {
background-color: rgba(255, 255, 255, 0.7);
border-radius: 30rpx;
color: #aaa;
font-size: 26rpx;
padding-left: 20rpx;
height: 64rpx;
flex: 1;
image {
width: 32rpx;
height: 32rpx;
margin: 0 20rpx 0 30rpx;
}
swiper {
height: 100%;
width: 60%;
}
}
}
.banner_main {
padding: 20rpx;
swiper {
width: 100%;
height: 300rpx;
border-radius: 12rpx;
overflow: hidden;
.swiper_item{
image{
border-radius: 12rpx;
width: 100%;
height: 100%;
}
}
}
}
.index_boutique{
margin: 10rpx 20rpx 0;
padding: 18rpx 20rpx 40rpx 22rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 20rpx;
.boutique_title{
display: flex;
justify-content: space-between;
.title_name{
font-size: 30rpx;
font-weight: bold;
color: #333333;
}
.title_more{
font-size: 24rpx;
color: #333333;
}
}
.boutique_flex{
margin-top: 20rpx;
display: flex;
flex-wrap: wrap;
.flex_item{
margin-top: 60rpx;
display: flex;
flex-direction: column;
align-items: center;
width: 20%;
image{
width: 58rpx;
height: 41rpx;
}
text{
margin-top: 16rpx;
font-size: 24rpx;
font-weight: normal;
color: #333333;
}
}
}
}
.index_goodsSeckill{
margin: 25rpx 20rpx 0;
padding: 20rpx 19rpx 50rpx 21rpx;
height: 346rpx;
background: #FFFFFF;
border-radius: 20rpx;
.goodsSeckill_title{
display: flex;
justify-content: space-between;
view:first-child{
font-size: 30rpx;
font-weight: bold;
color: #333333;
}
view:last-child{
font-size: 24rpx;
color: #333333;
}
}
.scroll_x{
margin-top: 28rpx;
box-sizing: border-box;
.group{
white-space: nowrap;
.group_item{
width: 220rpx;
height: 220rpx;
display: inline-block;
margin-right: 10rpx;
image{
border-radius: 14rpx;
width: 220rpx;
height: 220rpx;
}
}
}
}
}
}
</style>
② 搜索页面布局
<template>
<view>
<view class="search">
<view class="search_box">
<image src="@/static/icon/search.png"></image>
<input type="text" confirm-type="search" v-model="keyword" @confirm="searchClick(key)" @input="changeInput" :placeholder="defaultKeyword" />
<image src="@/static/icon/del_text.png" v-show="keyword" @click="delKeyword()"></image>
</view>
<view class="search_btn" @click="searchClick(key)">搜索</view>
</view>
<view class="bottom">
<!-- 搜索关键词列表 -->
<view class="keyword-list-box" v-show="keywordList">
<view class="keyword-entry" hover-class="keyword-entry-tap" v-for="(item,idx) in keywordList" :key="idx" @click="searchClick(keyword)">
<image src="@/static/icon/search.png"></image>
<rich-text :nodes="item.htmlStr"></rich-text>
</view>
</view>
<!-- 历史记录+热搜词汇 -->
<view v-if="keywordList.length == 0">
<view class="history">
<view class="title">
<text>历史记录</text>
<image src="@/static/icon/del.png" @click="oldDelete()"></image>
</view>
<view v-if="oldKeywordList.length>0">
<view class="item_box">
<view class="item" v-for="(keyword, index) in oldKeywordList" @tap="searchClick(keyword)" :key="index">{{ keyword }}</view>
</view>
</view>
<view v-else style="font-size: 26rpx; color: #ccc;">暂无搜索记录</view>
</view>
<view class="hot">
<view class="title"><text>搜索发现</text></view>
<view class="item_box">
<view class="item" v-for="(item, index) in hotWords" :key="index" @click="searchClick(item.queryName)">
<image src="@/static/icon/hot.png" v-if="item.hot"></image>
<text>{{ item.queryName }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
keyword: '',
defaultKeyword: '',
oldKeywordList: [], //历史记录数据
keywordList: [],
searchTimer: null,
hotWords: []
}
},
onLoad(e) {
this.loadOldKeyword() //进来页面先在缓存取值
this.getHotWords()
if (e.key) {
this.keyword = e.key
}
},
methods: {
// 获取最近搜索热词
getHotWords() {
uni.request({
url:'' //请求搜索的热词
}).then(res=> {
// 模拟的数据
let mockData = [
{
queryName:'音响',
querySubType:99,
queryType:9
},
{
queryName:'高压锅',
querySubType:99,
queryType:9
},
{
queryName:'电脑',
querySubType:99,
queryType:9
},
{
queryName:'电视',
querySubType:99,
queryType:9
},
{
queryName:'笔记本',
querySubType:99,
queryType:9
}
]
this.hotWords = mockData
// this.hotWords = res.data 请求到的数据
this.getRandomKeyword()
})
},
// 获取随机热词填入输入框
getRandomKeyword() {
const random = Math.floor(Math.random() * this.hotWords.length)
this.defaultKeyword = this.hotWords[random].queryName
},
// 删除input输入的内容
delKeyword() {
this.keyword = ''
this.keywordList = []
},
loadOldKeyword() {
uni.getStorage({
key: 'OldKeys',
success: res => {
let OldKeys = JSON.parse(res.data)
this.oldKeywordList = OldKeys
}
})
},
// 删除历史记录
oldDelete() {
uni.showModal({
title: '删除',
content: '确定删除历史搜索记录吗?',
confirmColor: '#c30d23',
success: res => {
if (res.confirm) {
console.log('用户点击确定')
this.oldKeywordList = []
uni.removeStorage({
key: 'OldKeys'
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
// input事件
changeInput() {
if (!this.keyword) {
this.keywordList = []
return
}
// input的防抖
this.$u.debounce(() => {
uni.request({
url:'https://api.tian.cn/api/Search/suggest?query='+ this.keyword
}).then(res=> {
let words = res[1].data.data
if (words.length != 0) {
this.keywordList = this.drawCorrelativeKeyword(words, this.keyword)
}
})
}, 200)
},
// 高亮显示关键词
drawCorrelativeKeyword(keywords, keyword) {
var len = keywords.length,
keywordArr = []
for (var i = 0; i < len; i++) {
var row = keywords[i]
//定义高亮#9f9f9f
var html = row.queryName.replace(keyword, "<span style='color: #9f9f9f;'>" + keyword + '</span>')
html = '<div>' + html + '</div>'
var tmpObj = {
keyword: row.word,
htmlStr: html
}
keywordArr.push(tmpObj)
}
return keywordArr
},
searchClick(key) {
console.log('key============',key);
key = key ? key : this.keyword ? this.keyword : this.defaultKeyword
this.keyword = key
this.saveKeyword(key) //保存为历史
uni.navigateTo({
url: '/pages/goodsList/goodsList?key=' + key
})
},
// 保存为历史记录
saveKeyword(keyword) {
uni.getStorage({
key: 'OldKeys',
success: res => {
let OldKeys = JSON.parse(res.data)
let findIndex = OldKeys.indexOf(keyword)
if (findIndex == -1) {
OldKeys.unshift(keyword)
} else {
OldKeys.splice(findIndex, 1)
OldKeys.unshift(keyword)
}
//最多10个纪录
OldKeys.length > 10 && OldKeys.pop()
uni.setStorage({
key: 'OldKeys',
data: JSON.stringify(OldKeys)
})
this.oldKeywordList = OldKeys //更新历史搜索
},
fail: e => {
var OldKeys = [keyword]
uni.setStorage({
key: 'OldKeys',
data: JSON.stringify(OldKeys)
})
this.oldKeywordList = OldKeys //更新历史搜索
}
})
}
}
}
</script>
<style lang="scss">
.search {
display: flex;
align-items: center;
height: 120rpx;
padding-bottom: 30rpx;
background-color: #f7f7f7;
font-size: 26rpx;
& > image {
width: 18rpx;
height: 31rpx;
margin-left: 53rpx;
}
.search_box {
display: flex;
align-items: center;
width: 600rpx;
height: 60rpx;
background-color: #ffffff;
// box-shadow: 2rpx 2rpx 2rpx red;
border-radius: 30rpx;
margin: 0 12rpx 0 25rpx;
padding-left: 18rpx;
image:nth-child(1) {
margin: 0 18rpx 0 7rpx;
width: 28rpx;
height: 28rpx;
}
image:nth-child(3) {
margin: 0 14rpx 0 auto;
width: 31rpx;
height: 31rpx;
}
input {
height: 60rpx;
// letter-spacing: 4rpx;
line-height: 60rpx;
color: #969696;
}
}
.search_btn {
width: 96rpx;
height: 52rpx;
background-color: #fff;
color: pink;
border-radius: 26rpx;
line-height: 52rpx;
text-align: center;
}
}
.bottom {
margin-top: -10rpx;
border-radius: 24rpx 24rpx 0 0;
background-color: #ffffff;
overflow: hidden;
// padding: 34rpx 36rpx 0;
}
.hot,
.history {
margin: 34rpx 0;
padding: 0 36rpx;
}
.history {
margin-bottom: 68rpx !important;
}
.title {
display: flex;
align-items: center;
font-size: 30rpx;
color: #262626;
font-family: Pingfang-Bold;
margin-bottom: 34rpx;
font-weight: bold;
image {
width: 25rpx;
height: 28rpx;
margin: 0 6rpx 0 auto;
}
}
.item_box {
display: flex;
flex-direction: row;
flex-wrap: wrap;
font-size: 26rpx;
.item {
display: flex;
align-items: center;
height: 48rpx;
margin: 0 24rpx 24rpx 0;
padding: 0 24rpx;
line-height: 48rpx;
border-radius: 24rpx;
color: #333333;
background-color: #f4f4f4;
image {
margin-right: 8rpx;
width: 21rpx;
height: 26rpx;
}
}
}
.keyword-list-box {
position: fixed;
top: 120rpx;
width: 750rpx;
background-color: #fff;
z-index: 1;
}
.keyword-entry-tap {
background-color: #eee;
}
.keyword-entry {
display: flex;
align-items: center;
height: 80rpx;
font-size: 26rpx;
color: #333;
padding: 0 30rpx;
border-bottom: solid 1rpx #f7f7f7;
image {
width: 29rpx;
height: 30rpx;
margin-right: 30rpx;
}
text {
margin-left: auto;
color: #777;
font-size: 22rpx;
}
}
</style>
③ 商品列表页布局
<template>
<view class="goodsList">
<view class="header u-flex">
<view class="search-box u-flex" @click="goToSearch(queryName)">
<view class="keyword u-flex" v-if="queryName != ''">
<text>{{ queryName }}</text>
<image src="@/static/icon/close_white.png" @click.stop="goToSearch()"></image>
</view>
</view>
<!-- 右侧的菜单切换 -->
<image class="toggle-icon"
:src="isShowMenu == 'card' ? '../../static/icon/arrange_list_black.png' : '../../static/icon/arrange_cell_black.png'"
@click="switchMenu"></image>
</view>
<!-- tab切换 -->
<view class="tabs_main u-flex">
<view class="item">
<view @click="tabsPop = true" class="u-flex"
:style="{ color: tabs_id == 0 || tabs_id == 8 ? '#BF1111' : '#333' }">
<text>{{ tabs_id == 0 ? '综合' : '销量' }}</text>
<u-icon name="arrow-down" :color="tabs_id == 0 || tabs_id == 8 ? '#BF1111' : '#333' "></u-icon>
</view>
<u-popup :show="tabsPop" mode="top" round="16" @close="tabsPop=false">
<view class="sort-rule u-flex-col">
<view class="u-flex" :style="{ color: tabs_id == 0 ? '#BF1111' : '#333' }"
@click="sortClick(0), (tabsPop = false)">
<text>综合排序</text>
<u-icon v-if="tabs_id == 0" name="checkmark" :color="tabs_id ==0 ? '#BF1111':'#333'">
</u-icon>
</view>
<view class="u-flex" :style="{ color: tabs_id == 8 ? '#BF1111' : '#333' }"
@click="sortClick(8), (tabsPop = false)">
<text>销量排序</text>
<u-icon v-if="tabs_id == 8" name="checkmark"></u-icon>
</view>
</view>
</u-popup>
</view>
<view class="item" @click="sortClick(7)" :style="{ color: tabs_id == 7 ? '#BF1111' : '#333' }">新品</view>
<view class="item" @click="sortClick(3)"
:style="{ color: tabs_id == 1 || tabs_id == 2 ? '#BF1111' : '#333' }">
<view class="u-flex">
<text>价格</text>
<u-icon :name="tabs_id == 1 ?'arrow-down':'arrow-up'"
:color=" tabs_id == 1 || tabs_id == 2 ? '#BF1111' : '#333' "></u-icon>
</view>
</view>
<view class="item" @click="sortClick(6)" :style="{ color: tabs_id == 6 ? '#BF1111' : '#333' }">信用</view>
<view class="item">
<view class="u-flex" @click="screenPop = true" :style="{ color: filterColor }">
<text>筛选</text>
<u-icon name="list-dot" size="20"></u-icon>
</view>
<!-- 筛选弹出层 -->
<u-popup :show="screenPop" @close="screenPop=false" mode="right" :duration="600">
<scroll-view scroll-y class="filterPopup">
<view class="services">
<view class="services-title u-flex">
<view class="title">折扣与服务</view>
</view>
<view class="list u-flex">
<text :class="{ active: isActive(item, 'services') }" v-for="(item, index) in services"
:key="index" @click="paramsFilter(item, 'services')">
{{ item.name }}
</text>
</view>
</view>
<view class="services">
<view class="services-title u-flex">
<view class="title">价格区间</view>
</view>
<view class="price-box u-flex">
<input type="text" placeholder="最低价" v-model.number="filter.minPrice"
@blur="getGoodsList" />
<text>-</text>
<input type="text" placeholder="最高价" v-model.number="filter.maxPrice"
@blur="getGoodsList" />
</view>
</view>
<view class="services">
<view class="head u-flex">
<view class="title">分类</view>
</view>
<view class="list u-flex">
<text :class="{ active: isActive(item, 'cateOne') }"
v-for="(item, index) in screenInfo.cateOne" :key="index"
@click="paramsFilter(item, 'cateOne')">
{{ item.name }}
</text>
</view>
</view>
<view class="services" v-if="screenInfo.brands">
<view class="head u-flex">
<view class="title">品牌</view>
</view>
<view class="list u-flex">
<text :class="{ active: isActive(item, 'brands') }"
v-for="(item, index) in screenInfo.brands" :key="index"
@click="paramsFilter(item, 'brands')">
{{ item.name }}
</text>
</view>
</view>
<view class="services" v-for="(itemm, index) in screenInfo.Product" :key="index">
<view class="head u-flex">
<view class="title">{{ itemm.name }}</view>
</view>
<view class="list u-flex">
<text :class="{ active: v.selected }" v-for="(v, i) in itemm.attChildren" :key="i"
@click="prodFn(itemm, v)">
{{ v.name }}
</text>
</view>
</view>
</scroll-view>
<view class="btns u-flex">
<view class="btn reset u-flex" @click="handleReset">重置</view>
<view class="btn confirm u-flex" @click="screenPop = false">确定({{ total }}件商品)</view>
</view>
</u-popup>
</view>
</view>
<!-- 右上角菜单的切换效果 -->
<view class="goodslist-card" v-if="isShowMenu == 'card'">
<view class="item" v-for="(item, index) in goodsList" :key="index">
<view class="goods-img u-flex">
<u-image :src="item.goodsInfo.imgs || item.goodsInfo.imgq" :lazy-load="true" width="346rpx"
height="346rpx"></u-image>
</view>
<view class="labelbox">
<text v-for="(vv, lindex) in item.label.normal" :key="lindex"
:style="{ backgroundColor: getLabelColor(vv.attrs) }">{{ vv.text }}</text>
</view>
<view class="title">{{ item.goodsInfo.name }}</view>
<view class="subtitle">
<text
v-if="!item.goodsInfo.coreSellingPoint || item.goodsInfo.coreSellingPoint.length == 0">{{ item.goodsInfo.summary }}</text>
<view v-else class="selling-point">
<text v-for="(sitem, sindex) in item.goodsInfo.coreSellingPoint"
:key="sindex">{{ sitem }}</text>
</view>
</view>
<view class="price">
<text>¥</text>
<text class="priceMin">{{ item.goodsInfo.priceMin / 100 }}</text>
<text class="spec" v-if="item.goodsInfo.priceTag">起</text>
<text class="marketPrice"
v-if="item.goodsInfo.priceMin != item.goodsInfo.marketPrice">¥{{ item.goodsInfo.marketPrice / 100 }}</text>
</view>
<view class="comment">
<text>{{ item.goodsInfo.comment.count > 100000 ? '10万+' : item.goodsInfo.comment.count }}条评论</text>
<text
v-if="item.goodsInfo.comment.positiveRate > 0">{{ item.goodsInfo.comment.positiveRate }}%好评</text>
</view>
</view>
</view>
<!-- 切换为列表视图 -->
<view class="goodslist-list" v-if="isShowMenu == 'list'">
<view class="item u-flex" v-for="(item, index) in goodsList" :key="index"
@click="goToDetail(item.data.goodsInfo.gid)">
<view class="u-flex">
<u-image width="252rpx" height="252rpx" :src="item.goodsInfo.imgs || item.goodsInfo.imgq"
:lazy-load="true"></u-image>
</view>
<view class="content u-flex-col">
<view class="title u-line-1">{{ item.goodsInfo.name }}</view>
<view class="subtitle u-line-1">{{ item.goodsInfo.summary }}</view>
<view class="selling-point" v-if="item.goodsInfo.coreSellingPoint">
<text v-for="(sitem, sindex) in item.goodsInfo.coreSellingPoint"
:key="sindex">{{ sitem }}</text>
</view>
<view class="price">
<text>¥</text>
<text class="priceMin">{{ item.goodsInfo.priceMin / 100 }}</text>
<text class="spec" v-if="item.goodsInfo.priceTag">起</text>
<text class="marketPrice"
v-if="item.goodsInfo.priceMin != item.goodsInfo.marketPrice">¥{{ item.goodsInfo.marketPrice / 100 }}</text>
</view>
<view class="labelbox">
<text v-for="(litem, lindex) in item.label.normal" :key="lindex"
:style="{ backgroundColor: getLabelColor(litem.attrs) }">{{ litem.text }}</text>
</view>
<view class="comment">
<text>{{ item.goodsInfo.comment.count > 100000 ? '10万+' : item.goodsInfo.comment.count }}条评论</text>
<text
v-if="item.goodsInfo.comment.positiveRate > 0">{{ item.goodsInfo.comment.positiveRate }}%好评</text>
</view>
</view>
</view>
</view>
<view v-show="showLoadmore">
<u-loadmore :status="loadingStatus" :margin-top="20" :margin-bottom="40" bg-color="#f9f9f9" :font-size="24"
:load-text="loadingText" color="#999" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
total: 0, //总商品数
pageIdx: 0, //页数
loadingStatus: 'loadmore',
loadingText: {
loadmore: '上拉加载更多',
loading: '努力加载中~',
nomore: '我也是有底线的'
},
queryName: '洗衣机',
isShowMenu: 'card',
queryID: '',
tabsPop: false, //综合销量的弹出层
tabs_id: 0,
screenPop: false, //筛选弹出层
screenInfo: {
cateOne: [{
name: '家电类',
outIdx: -1,
outer: false
}],
brands: [{
count: 4,
name: "小米",
outer: true,
outIdx: 4
},
{
count: 5,
name: "中米",
outer: true,
outIdx: 4
},
{
count: 6,
name: "大米",
outer: true,
outIdx: 4
}
],
Product: [{
name: '产品分类',
attChildren: [{
count: 13,
name: "内衣洗衣机",
outer: true,
outIdx: 2
},
{
count: 13,
name: "迷你洗衣机",
outer: true,
outIdx: 2
},
{
count: 13,
name: "全自动洗衣机",
outer: true,
outIdx: 2
}
]
},
{
name: '等级分类',
attChildren: [{
count: 13,
name: "一级类别",
outer: true,
outIdx: 2
},
{
count: 13,
name: "二级类别",
outer: true,
outIdx: 2
},
{
count: 13,
name: "三级类别",
outer: true,
outIdx: 2
}
]
},
{
name: '排水方式',
attChildren: [{
count: 13,
name: "上排水",
outer: true,
outIdx: 2
},
{
count: 13,
name: "下排水",
outer: true,
outIdx: 2
},
]
}
]
},
services: [{
count: 1,
name: '会员',
outIdx: -1,
outer: false
},
{
count: 1,
name: '预售',
outIdx: -1,
outer: false
},
{
count: 1,
name: '包邮',
outIdx: -1,
outer: false
}
],
filter: {
attr: [],
brands: [],
cateOne: [],
category2: [],
category3: [],
maxPrice: null,
minPrice: null,
services: [],
special: [],
specialCoupon: [],
tags: []
},
filterColor: '#333',
goodsList: [{
goodsInfo: {
name: '我是商品的标题',
imgs: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
imgq: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
coreSellingPoint: [],
summary: '我是商品的小标题',
priceMin: 2000,
priceTag: 300,
marketPrice: 0,
comment: {
count: 3600,
positiveRate: 100
}
},
label: {
normal: [{
attrs: `{"font":"default","height":42,"width":192,"bgColor":"#000000",
"imageUrl":"https://img.youpin.mi-img.com/tag/4167059a2a83e6dece26ebc1300abaf8.png?w\u003d192\u0026h\u003d42",
"jumpUrl":"","priority":6001.0,"displayStatus":1,"fontColor":"#FFFFFF"}`,
businessId: 0,
ext: "null",
labelId: 825,
labelName: "会员折扣",
text: "会员折扣",
type: "sale",
}, ]
},
},
{
goodsInfo: {
name: '我是商品的标题',
imgs: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
imgq: 'https://img.alicdn.com/imgextra/i3/111735579/O1CN015OgEJV1r5EHo6M3Aj_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',
coreSellingPoint: [],
summary: '我是商品的小标题',
priceMin: 2000,
priceTag: 300,
marketPrice: 0,
comment: {
count: 3600,
positiveRate: 100
}
},
label: {
normal: [{
attrs: `{"font":"default","height":42,"width":192,"bgColor":"#000000",
"imageUrl":"https://img.youpin.mi-img.com/tag/4167059a2a83e6dece26ebc1300abaf8.png?w\u003d192\u0026h\u003d42",
"jumpUrl":"","priority":6001.0,"displayStatus":1,"fontColor":"#FFFFFF"}`,
businessId: 0,
ext: "null",
labelId: 825,
labelName: "会员折扣",
text: "会员折扣",
type: "sale",
}, ]
},
},
],
}
},
onLoad(e) {
this.queryName = e.key
this.getGoodsList()
},
computed: {
showLoadmore() {
return this.goodsList.length !== 0 ? true : false
}
},
onReachBottom() {
if (this.pageIdx < this.total) {
// this.getGoodsList('more')
this.loadingStatus = 'loading'
} else {
this.loadingStatus = 'nomore'
}
},
methods: {
getLabelColor(str) {
console.log(str, 'str=============');
return str.substr(str.indexOf('#'), 7)
},
getGoodsList() { //获取商品数据
},
// 切换右侧菜单
switchMenu() {
this.isShowMenu == 'card' ? this.isShowMenu = 'list' : this.isShowMenu = 'card'
},
sortClick(id) {
// 当点击筛选ID和目前列表的筛选ID一致时,不请求数据,节省流量
if (id == this.tabs_id) return
switch (id) {
case 3:
switch (this.tabs_id) {
case 1:
this.tabs_id = 2
console.log('降序排列')
break
case 2:
this.tabs_id = 1
console.log('升序排列')
break
default:
this.tabs_id = 2
console.log('降序排列')
}
break
default:
this.tabs_id = id
}
// this.goodsList = []
// this.pageIdx = 0
// this.sortLoading = true
// this.getGoodsList()
},
isActive(item, type) {
console.log('item', item);
console.log('type', type);
if (this.filter[type].indexOf(item.name) == -1) {
return false
} else {
return true
}
},
paramsFilter(item, type) {
if (this.filter[type].indexOf(item.name) == -1) {
this.filter[type].push(item.name)
} else {
this.filter[type].splice(this.filter[type].indexOf(item.name), 1)
}
this.filterColor = '#BF1111'
// this.getGoodsList()
},
prodFn(item, v) {
console.log('item', item)
console.log('v', v)
let result = []
item.attChildren.some((vv, i) => {
if (vv.name == v.name) {
if (!vv.selected) {
this.$set(vv, 'selected', true)
} else {
vv.selected = false
}
}
if (vv.selected) {
result.push(vv)
} else {
result.splice(i, 1)
}
})
// console.log('result',result)
let str = []
result.forEach(x => {
str.push(x.name)
})
// console.log(str)
let obj = {
name: item.name,
attrValue: []
}
// console.log(obj)
let flag = true
this.filter.attr.forEach(item => {
if (item.name === obj.name) {
// 对象里的唯一标识name
flag = false
}
})
if (flag) {
this.filter.attr.push(obj)
}
this.filter.attr.forEach((x, i) => {
if (x.name == item.name) {
x.attrValue = str
}
if (x.attrValue.length == 0) {
this.filter.attr.splice(i, 1)
}
})
this.filterColor = '#BF1111'
this.getGoodsList()
},
// 弹框重置按钮
handleReset() {
Object.assign(this.$data.filter, this.$options.data().filter)
this.screenInfo.Product.forEach(x => {
x.attChildren.forEach(s => {
s.selected = false
})
})
this.filterColor = '#333'
this.getGoodsList()
},
goToSearch(key) {
if (key) {
uni.redirectTo({
url: '../search/search?key=' + key
})
} else {
uni.redirectTo({
url: '../search/search'
})
}
},
}
}
</script>
<style lang="less">
.u-flex {
display: flex;
align-items: center;
flex-direction: row;
}
.u-flex-col {
display: flex;
flex-direction: column;
}
page {
background-color: #f7f7f7;
}
.goodsList {
.header,
.tabs_main {
position: fixed;
width: 750rpx;
font-size: 26rpx;
background-color: #f7f7f7;
z-index: 1080;
}
.header {
top: 0;
justify-content: space-between;
// padding: 0 20rpx;
height: 60rpx;
.search-box {
flex: 1;
padding-left: 18rpx;
height: 60rpx;
background-color: #ffffff;
border-radius: 30rpx;
.keyword {
padding: 2rpx 16rpx;
color: #fff;
border-radius: 30rpx;
background-color: rgb(153, 153, 153);
image {
width: 32rpx;
height: 32rpx;
}
}
}
.toggle-icon {
width: 64rpx;
height: 64rpx;
}
}
.tabs_main {
top: 60rpx;
height: 80rpx;
color: #333333;
.item {
display: flex;
align-items: center;
justify-content: center;
width: 20%;
height: inherit;
&>view {
width: 100%;
height: inherit;
justify-content: center;
}
u-icon {
margin-left: 4rpx;
}
.sort-rule {
justify-content: space-around;
padding: 10rpx 24rpx;
height: 160rpx;
background-color: #f7f7f7;
&>view {
justify-content: space-between;
}
}
.filterPopup {
height: 92%;
// padding: 10rpx 0;
.services {
margin-bottom: 20rpx;
padding: 0 20rpx;
.services-title {
justify-content: space-between;
height: 60rpx;
font-size: 28rpx;
color: #555;
.title {
font-weight: bold;
}
.all {
color: #999;
font-size: 22rpx;
}
}
.list {
flex-wrap: wrap;
margin-top: 10rpx;
text {
margin: 0 16rpx 20rpx 0;
padding: 0 10rpx;
height: 52rpx;
width: 176rpx;
max-width: 176rpx;
font-size: 24rpx;
line-height: 51rpx;
text-align: center;
border-radius: 26rpx;
background-color: rgb(244, 244, 244);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
border: 1rpx solid rgb(244, 244, 244);
}
text:nth-child(3n) {
margin-right: 0;
}
.active {
color: #bf1111;
border: 1rpx solid rgb(191, 17, 17);
background-color: rgb(246, 237, 237);
}
}
.price-box {
justify-content: space-between;
margin-top: 10rpx;
input {
height: 52rpx;
width: 240rpx;
margin-bottom: 20rpx;
text-align: center;
border-radius: 26rpx;
background-color: rgb(244, 244, 244);
}
text {
margin-bottom: 20rpx;
}
}
}
}
.btns {
justify-content: space-around;
height: 8%;
// background-color: #EEEEEE;
.btn {
justify-content: center;
height: 80%;
width: 46%;
border-radius: 60rpx;
}
.reset {
color: rgb(51, 51, 51);
border: 1rpx solid rgb(204, 204, 204);
}
.confirm {
color: #fff;
background: linear-gradient(to right, rgb(240, 78, 46), rgb(213, 16, 16));
}
}
}
}
.goodslist-card {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 0 20rpx;
margin-top: 140rpx;
background-color: #f7f7f7;
.item {
position: relative;
width: 346rpx;
margin-bottom: 24rpx;
padding-bottom: 20rpx;
border-radius: 8rpx;
background-color: #ffffff;
font-size: 28rpx;
overflow: hidden;
.goods-img {
justify-content: center;
width: 346rpx;
height: 346rpx;
border-radius: 8rpx 8rpx 0 0;
}
.labelbox {
position: absolute;
top: 308rpx;
left: 0;
text {
display: inline-block;
border-radius: 2rpx;
color: #ffffff;
margin-right: 10rpx;
text-align: center;
height: 32rpx;
padding: 0 10rpx;
line-height: 32rpx;
font-size: 24rpx;
}
}
.title,
.subtitle {
width: 346rpx;
padding-left: 16rpx;
padding-right: 6rpx;
white-space: nowrap;
text-overflow: ellipsis;
-webkit-box-pack: center;
overflow: hidden;
}
.title {
font-size: 30rpx;
color: rgb(51, 51, 51);
line-height: 42rpx;
margin-top: 6rpx;
}
.subtitle {
font-size: 26rpx;
color: rgb(153, 153, 153);
margin-top: 4rpx;
line-height: 36rpx;
.selling-point {
text {
font-size: 22rpx;
display: inline-block;
margin-right: 8rpx;
padding: 0 12rpx;
border-radius: 36rpx;
background-color: rgb(248, 248, 248);
}
}
}
.price {
margin-top: 10rpx;
padding-left: 16rpx;
color: rgb(227, 13, 13);
font-size: 26rpx;
height: 40rpx;
font-family: 'AllAndNone';
.priceMin {
font-size: 34rpx;
margin-right: 4rpx;
font-weight: bold;
}
.marketPrice {
margin-left: 6rpx;
font-size: 24rpx;
color: #999;
text-decoration: line-through;
}
.spec {
font-size: 24rpx;
}
}
.comment {
margin-top: 6rpx;
padding-left: 16rpx;
font-size: 22rpx;
color: #999;
text {
margin-right: 12rpx;
}
}
}
}
.goodslist-list {
padding: 0 20rpx;
margin-top: 140rpx;
background-color: #fff;
border-radius: 24rpx 24rpx 0 0;
overflow: hidden;
.item {
margin: 30rpx 0;
font-size: 28rpx;
.content {
height: 252rpx;
padding: 4rpx 0 2rpx 16rpx;
}
.title,
.subtitle {
width: 440rpx;
}
.title {
font-size: 28rpx;
color: #333;
line-height: 42rpx;
}
.subtitle {
font-size: 24rpx;
color: rgb(153, 153, 153);
margin-top: 4rpx;
line-height: 36rpx;
}
.selling-point {
text {
display: inline-block;
margin-right: 8rpx;
padding: 0 12rpx;
font-size: 22rpx;
color: #999;
border-radius: 36rpx;
background-color: rgb(248, 248, 248);
}
}
.price {
margin-top: auto;
color: rgb(227, 13, 13);
font-size: 26rpx;
height: 40rpx;
font-family: 'AllAndNone';
.priceMin {
font-size: 34rpx;
margin-right: 4rpx;
font-weight: bold;
}
.marketPrice {
margin-left: 6rpx;
font-size: 24rpx;
color: #999;
text-decoration: line-through;
}
.spec {
font-size: 24rpx;
}
}
.labelbox {
text {
display: inline-block;
border-radius: 4rpx;
color: #ffffff;
margin-right: 10rpx;
text-align: center;
height: 32rpx;
padding: 0 10rpx;
line-height: 32rpx;
font-size: 24rpx;
}
}
.comment {
margin-top: 6rpx;
font-size: 22rpx;
color: #999;
text {
margin-right: 12rpx;
}
}
}
}
}
</style>