本地生活
includes
search-bar.wxml
<view class="weui-search-bar">
<view class="weui-search-bar__form">
<view class="weui-search-bar__box">
<icon class="weui-icon-search_in-box" type="search" size="14"/>
<input type="text" class="weui-search-bar__input" placeholder="搜索" value="{{searchText}}" focus="{{searchShowed}}" bindinput="searchChangeHandle" bindconfirm="searchHandle"/>
<view class="weui-icon-clear" wx:if="{{searchText}}" bindtap="clearSearchHandle">
<icon type="clear" size="14"/>
</view>
</view>
<!-- 进入显示的搜索框 -->
<label class="weui-search-bar__label" hidden="{{searchShowed}}" bindtap="showSearchHandle">
<icon class="weui-icon-search" type="search" size="14"/>
<view class="weui-search-bar__text">显示搜索框</view>
</label>
</view>
<view class="weui-search-bar__cancel-btn" hidden="{{!searchShowed}}" bindtap="hideSearchHandle">取消</view>
</view>
pages
index
index.wxml
<swiper class="slides" autoplay="{{slides.length>1}}" indicator-dots="{{slides.length>1}}" indicator-color="#bcc0c9" indicator-active-color="#3a4861">
<swiper-item wx:for="{{slides}}" wx:key="id">
<navigator wx:if="{{item.link}}" url="{{item.link}}">
<image src="{{item.image}}" mode="aspectFill"></image>
</navigator>
<image wx:else src="{{item.image}}" mode="aspectFill"></image>
</swiper-item>
</swiper>
<view class="grids">
<navigator class="item" wx:for="{{categories}}" wx:key="id" url="/pages/list/list?cat={{item.id}}">
<image src="{{item.icon}}"></image>
<text>{{item.name}}</text>
</navigator>
</view>
<view class="links">
<navigator url="/pages/list/list?type=recommend">
<image src="/assets/images/link-01.png"></image>
</navigator>
<navigator url="/pages/forum/forum">
<image src="/assets/images/link-02.png"></image>
</navigator>
</view>
index.js
const fetch = require('../../utils/fetch')
Page({
data: {
slides:[],
categories:[]
},
//事件处理函数
onLoad: function (options) {
fetch('/slides').then(res=>{
this.setData({slides:res.data})
}),
fetch('/categories').then(res=>{
this.setData({categories:res.data})
})
},
})
index.wxss
.slides {
height: 380rpx;
}
.slides navigator,
.slides image {
min-width: 100%;
height: 100%;
}
.grids{
display: flex;
flex-wrap: wrap;
border-top: 1rpx solid #eee;
border-left: 1rpx solid #eee;
background-color: #fff;
}
.grids .item{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 33.3333333333%;
height: 250rpx;
border-right: 1rpx solid #eee;
border-bottom: 1rpx solid #eee;
box-sizing: border-box;
}
.grids .item image {
width: 70rpx;
height: 70rpx;
}
.grids .item text{
margin-top: 20rpx;
color: #999;
font-size: 28rpx;
}
.links{
display: flex;
justify-content: space-between;
margin: 10rpx 0;
padding: 30rpx;
background-color: #fff;
}
.links image{
width: 330rpx;
height: 185rpx;
}
list
list.wxml
<!-- 通过include包含引入我们的其他页面 -->
<include src="/includes/search-bar.wxml"></include>
<view class="cells">
<navigator class="item" wx:for="{{shops}}" wx:key="id" url="/pages/detail/detail?item={{item.id}}">
<image src="{{item.images[0]}}" mode="aspectFill"></image>
<view class="meta">
<text class="name">{{item.name}}</text>
<text class="phone">电话:{{item.phone||'none'}}</text>
<text class="address">地址:{{item.address}}</text>
<text class="hours">营业时间:{{item.businessHours}}</text>
</view>
<view class="score">{{item.score||'none'}}</view>
</navigator>
</view>
<view wx:if="{{hasMore}}" class="loadmore loading">正在加载...</view>
<view wx:else class="loadmore">没有更多内容了</view>
list.js
// pages/list/list.js
var fetch = require("../../utils/fetch")
Page({
/**
* 页面的初始数据
*/
data: {
category: null, //当前分页
pageIndex: 0, //当前页码
pageSize: 20, //每页现实的条数
shops: [], //列表数据
hasMore: true //判断是否还有数据
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this;
//得到当前分类的数据
fetch(`/categories/${options.cat}`).then(res => {
that.setData({
category: res.data
})
//将当前的跳转分类的头设置成分类名称
wx.setNavigationBarTitle({
title: res.data.name,
})
that.loadMore()
})
},
loadMore() {
var that = this
//let { pageIndex, pageSize, searchText } = this.data
var searchText = that.data.searchText
var pageIndex = that.data.pageIndex
var pageSize = that.data.pageSize
var params = {
_page: ++pageIndex,
_limit: pageSize
}
if(searchText) params.q =searchText
return fetch(`/categories/${this.data.category.id}/shops`, params).then(res => {
// console.log(res);
// 得到总条数
const totalCount = parseInt(res.header['X-Total_Count'])
// 判断是否加载完毕
const hasMore = that.data.pageIndex * that.data.pageSize < totalCount
// 拼接数据
const shops = this.data.shops.concat(res.data)
that.setData({
shops: shops,
hasMore: hasMore,
pageIndex: pageIndex
})
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
this.setData({
shops: [],
pageIndex: 0,
hasMore: true
})
this.loadMore().then(() => wx.stopPullDownRefresh())
// console.log("触发下拉");
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
this.loadMore()
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
// 进入列表页触发:让显示搜索框隐藏,和取消两字显示
showSearchHandle() {
this.setData({ searchShowed: true })
},
// 点击搜索框触发:实时记录搜索框的值
searchChangeHandle(e) {
this.setData({ searchText: e.detail.value })
},
// 确认搜索
searchHandle(){
// console.log(this.data.searchText);
this.setData({ shops: [], pageIndex: 0, hasMore: true })
this.loadMore()
},
// 取消按钮,用于隐藏取消两字
hideSearchHandle () {
this.setData({ searchText: '', searchShowed: false })
},
// 清除搜索框
clearSearchHandle () {
this.setData({ searchText: '' })
},
})
list.wxss
.cells{
background-color: #fff;
}
.cells .item{
display: flex;
align-items:flex-start ;
border-bottom: 1rpx solid #eee;
}
.cells .item image {
width: 160rpx;
height: 160rpx;
margin: 20rpx;
}
.cells .item .meta{
display: flex;
flex-direction: column;
flex: 1;
padding: 10rpx 0;
font-size: 30rpx;
}
.cells .item .meta .name {
color: #234;
font-size: 28rpx;
}
.cells .item .meta .phone,
.cells .item .meta .address {
color: #678;
font-size: 24rpx;
}
.cells .item .meta .hours {
/*color: #ff69b4;*/
color: #456;
font-size: 22rpx;
}
.cells .item .score{
margin:20rpx 20rpx 0 -40rpx;
padding: 0 10rpx;
background-color: #ee523d;
border-radius: 30rpx;
color: #fff;
font-size: 24rpx;
text-align: center;
}
.loadmore{
color: #888;
font-size: 30rpx;
line-height: 100rpx;
text-align: center;
}
.loadmore.loading::before {
content: '';
width: 40rpx;
height: 40rpx;
margin-top: -10rpx;
margin-right: 10rpx;
display: inline-block;
vertical-align: middle;
animation: loading 1s steps(12) infinite;
background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0HJlY未完) no-repeat;
background-size: 100%
}
@keyframes loading {
from {
transform: rotate(0deg)
}
to {
transform: rotate(-360deg)
}
}
list.json
下拉设置
{
"enablePullDownRefresh":true,
"onReachBottomDistance": 5
}
detail
detail.wxml
<swiper class="slides" indicator-dots="{{shop.images.length > 1}}" indicator-color="#bcc0c9" indicator-active-color="#3a4861">
<swiper-item wx:for="{{shop.images}}" wx:key="id">
<image src="{{item}}" mode="aspectFill" bindtap="previewHandle" data-src="{{item}}"/>
</swiper-item>
</swiper>
detail.js
// pages/detail/detail.js
var fetch = require("../../utils/fetch")
Page({
/**
* 页面的初始数据
*/
data: {
shop:{}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// console.log(options);
fetch(`/shops/${options.item}`).then((res)=>{
this.setData({
shop:res.data
})
wx.setNavigationBarTitle({
title: res.data.name
})
})
},
previewHandle(e){
var that = this
wx.previewImage({
urls: that.data.shop.images,
current:e.target.dataset.src,
})
},
detail.wxss
.slides{
height:580rpx;
}
.slides image {
min-width: 100%;
height: 100%;
}
utils
fetch.js
var app = getApp()
module.exports=(url,data,method="GET",header={})=>{
wx.showLoading({title:"loading..."})
return new Promise((resolve,reject)=>{
wx.request({
url:app.config.apiBase+url,
data,
header,
method,
dataType:'json',
success:resolve,
fail:reject,
complete:wx.hideLoading
})
})
}
app.js
App({
// 配置接口连接
config:{
apiBase:"https://locally.uieee.com"
}
})
app.json
{
"pages": [
"pages/index/index",
"pages/logs/logs",
"pages/list/list",
"pages/detail/detail",
"pages/message/message",
"pages/settings/settings",
"pages/profile/profile",
"pages/forum/forum"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#3a4861",
"navigationBarTitleText": "本地生活",
"navigationBarTextStyle": "white",
"backgroundColor": "#bcc0c9",
"enablePullDownRefresh": false,
"onReachBottomDistance": 50
},
"tabBar": {
"color": "#999",
"selectedColor": "#444",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "assets/tabs/home.png",
"selectedIconPath": "assets/tabs/home-active.png"
},
{
"pagePath": "pages/message/message",
"text": "消息",
"iconPath": "assets/tabs/message.png",
"selectedIconPath": "assets/tabs/message-active.png"
},
{
"pagePath": "pages/profile/profile",
"text": "我的",
"iconPath": "assets/tabs/profile.png",
"selectedIconPath": "assets/tabs/profile-active.png"
}
],
"position": "bottom"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
app.wxss
引入外部统一的样式
@import "/vendors/weui.wxss"