微信小程序学习笔记(6) -- 本地生活项目

本地生活项目

项目效果图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

外观和标签栏的配置

window

用于设置小程序的状态栏、导航条、标题、窗口背景色。

属性类型默认值描述最低版本
navigationBarBackgroundColorHexColor#000000导航栏背景颜色,如 #000000
navigationBarTextStylestringwhite导航栏标题颜色,仅支持 black / white
navigationBarTitleTextstring导航栏标题文字内容
navigationStylestringdefault导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮。参见注 2。微信客户端 6.6.0
backgroundColorHexColor#ffffff窗口的背景色
backgroundTextStylestringdark下拉 loading 的样式,仅支持 dark / light
backgroundColorTopstring#ffffff顶部窗口的背景色,仅 iOS 支持微信客户端 6.5.16
backgroundColorBottomstring#ffffff底部窗口的背景色,仅 iOS 支持微信客户端 6.5.16
enablePullDownRefreshbooleanfalse是否开启全局的下拉刷新。 详见 Page.onPullDownRefresh
onReachBottomDistancenumber50页面上拉触底事件触发时距页面底部距离,单位为 px。 详见 Page.onReachBottom
pageOrientationstringportrait屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化2.4.0 (auto) / 2.5.0 (landsca

tabBar

如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

属性类型必填默认值描述最低版本
colorHexColortab 上的文字默认颜色,仅支持十六进制颜色
selectedColorHexColortab 上的文字选中时的颜色,仅支持十六进制颜色
backgroundColorHexColortab 的背景色,仅支持十六进制颜色
borderStylestringblacktabbar 上边框的颜色, 仅支持 black / white
listArraytab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab
positionstringbottomtabBar 的位置,仅支持 bottom / top
custombooleanfalse自定义 tabBar,见详情2.5.0

其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:

属性类型必填说明
pagePathstring页面路径,必须在 pages 中先定义
textstringtab 上按钮文字
iconPathstring图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。
selectedIconPathstring选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。

目标

建3个tab的tabBar
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

具体代码:

核心代码:

app.json

{
  "pages":[
    "pages/index/index",
    "pages/message/message",
    "pages/profile/profile"
  ],
  "window":{
    "navigationBarBackgroundColor": "#3a4891",
    "navigationBarTextStyle":"white",
    "navigationBarTitleText": "本地生活",
    "backgroundColor": "#bcc0c9",
    "backgroundTextStyle":"light",
    "enablePullDownRefresh": false
  },
  "tabBar":{
    "list":[
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "assets/home.png",
        "selectedIconPath":"assets/home-active.png"
      },
      {
        "pagePath": "pages/message/message",
        "text": "消息",
        "iconPath": "assets/message.png",
        "selectedIconPath":"assets/message-active.png"
      },
      {
        "pagePath": "pages/profile/profile",
        "text": "我的",
        "iconPath": "assets/profile.png",
        "selectedIconPath":"assets/profile-active.png"
      }
    ]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}
<!--index.wxml-->
<view class="container">
  首页
</view>
<!--pages/message/message.wxml-->
<text>pages/message/message.wxml</text>
<!--pages/profile/profile.wxml-->
<text>pages/profile/profile.wxml</text>

公共样式

设置tabBar的样式:

在这里插入图片描述

在这里插入图片描述

app.json全部代码

{
  "pages":[
    "pages/index/index",
    "pages/message/message",
    "pages/profile/profile"
  ],
  "window":{
    "navigationBarBackgroundColor": "#3a4891",
    "navigationBarTextStyle":"white",
    "navigationBarTitleText": "本地生活",
    "backgroundColor": "#bcc0c9",
    "backgroundTextStyle":"light",
    "enablePullDownRefresh": false
  },
  "tabBar":{
     "color": "#999",
     "selectedColor": "#444",
     "backgroundColor": "#fff",
     "borderStyle": "black",
    "list":[
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "assets/home.png",
        "selectedIconPath":"assets/home-active.png"
      },
      {
        "pagePath": "pages/message/message",
        "text": "消息",
        "iconPath": "assets/message.png",
        "selectedIconPath":"assets/message-active.png"
      },
      {
        "pagePath": "pages/profile/profile",
        "text": "我的",
        "iconPath": "assets/profile.png",
        "selectedIconPath":"assets/profile-active.png"
      }
    ]
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}

首页布局

知识点

image

基础库 1.0.0 开始支持,低版本需做兼容处理

图片。支持 JPG、PNG、SVG、WEBP、GIF 等格式,2.3.0 起支持云文件ID。

属性类型默认值必填说明最低版本
srcstring图片资源地址1.0.0
modestringscaleToFill图片裁剪、缩放的模式1.0.0
webpbooleanfalse默认不解析 webP 格式,只支持网络资源2.9.0
lazy-loadbooleanfalse图片懒加载,在即将进入一定范围(上下三屏)时才开始加载1.5.0
show-menu-by-longpressbooleanfalse开启长按图片显示识别小程序码菜单2.7.0
binderroreventhandle当错误发生时触发,event.detail = {errMsg}1.0.0
bindloadeventhandle当图片载入完毕时触发,event.detail = {height, width}1.0.0

mode 的合法值

说明最低版本
scaleToFill缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
aspectFit缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
aspectFill缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
widthFix缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
heightFix缩放模式,高度不变,宽度自动变化,保持原图宽高比不变2.10.3
top裁剪模式,不缩放图片,只显示图片的顶部区域
bottom裁剪模式,不缩放图片,只显示图片的底部区域
center裁剪模式,不缩放图片,只显示图片的中间区域
left裁剪模式,不缩放图片,只显示图片的左边区域
right裁剪模式,不缩放图片,只显示图片的右边区域
top left裁剪模式,不缩放图片,只显示图片的左上边区域
top right裁剪模式,不缩放图片,只显示图片的右上边区域
bottom left裁剪模式,不缩放图片,只显示图片的左下边区域
bottom right裁剪模式,不缩放图片,只显示图片的右下边区域

目标

在这里插入图片描述

代码

<!--index.wxml-->
<swiper class="slides">
  <swiper-item>
      <image src="/assets/banner/banner-01.png" mode="aspectFill"></image>
  </swiper-item>
    <swiper-item>
      <image src="/assets/banner/banner-02.png" mode="aspectFill"></image>
  </swiper-item>
</swiper>

<view class="grids">
   <view class="item">
      <image src="/assets/grid/grid-01.png" />
      <text>美食</text>
   </view>
   <view class="item">
      <image src="/assets/grid/grid-02.png" />
      <text>美食</text>
   </view>
   <view class="item">
      <image src="/assets/grid/grid-03.png" />
      <text>美食</text>
   </view>
   <view class="item">
       <image src="/assets/grid/grid-04.png" />
      <text>美食</text>
   </view>
   <view class="item">
       <image src="/assets/grid/grid-05.png" />
      <text>美食</text>
   </view>
   <view class="item">
       <image src="/assets/grid/grid-06.png" />
      <text>美食</text>
   </view>
   <view class="item">
      <image src="/assets/grid/grid-07.png" />
      <text>美食</text>
   </view>
   <view class="item">
       <image src="/assets/grid/grid-08.png" />
      <text>美食</text>
   </view>
   <view class="item">
       <image src="/assets/grid/grid-09.png" />
      <text>美食</text>
   </view>
</view>

<view class="links">
   <image src="/assets/link-01.png"></image>
   <image src="/assets/link-02.png"></image>
</view>

/**index.wxss**/
.slides {
  height: 380rpx;
}
.slides image{
  width: 100%;
  height: 100%;
}
.grids{
   display: flex;
   flex-wrap: wrap;   
   background-color: #fff;
   border-left: 1rpx solid #eee;
   border-bottom: 1rpx solid #eee;
   color: #888;
}
.grids .item{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 33.333333%;
  height: 250rpx;
  border-right: 1rpx solid #eee;
  border-top: 1rpx solid #eee;
  box-sizing: border-box;
}
.grids .item image{
  width: 70rpx;
  height: 70rpx;
}
.grids .item text{
  margin-top: 20rpx;
  color: #888;
  font-size: 28rpx;
}
.links{
  display: flex;
}
.links image{
    height: 200rpx;
}

效果:

在这里插入图片描述

小程序中发送HTTP请求

如果是测试环境:

在详情中设置

在这里插入图片描述

如果是正式环境

1.请求的地址必须在管理后台添加白名单

2.域名必须备案,服务端必须采用HTTPS

//index.js
//获取应用实例
const app = getApp()

Page({
 
  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
      wx.request({
        //这里的地址没有跨域的概念
        url: 'https://api.douban.com/v2/movie/coming_soon',
        header: {
          'Content-Type': 'json'
        },
        success: function(res){
            console.log(res)
        }
        //发送异步请求 不再是 WEB 那套 ajax
        //2.没有跨域
        //3.请求的地址必须在管理后台添加白名单
        //4.域名必须备案,服务端必须采用HTTPS
      })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

首页数据加载及数据绑定

封装http请求:

在utils的文件夹下:新建fetch.js

module.exports = (url, data) => {
   return new Promise((resolve, reject) => {
    wx.request({
      url: `https://locally.uieee.com/${url}`,
      success: resolve,
      fail: reject
    })
   })
}

index.js导入fetch,并使用

//index.js
//获取应用实例
const app = getApp()
const fetch = require('../../utils/fetch')
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
     slides: [],
     categories: []
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    
      wx.request({
        //这里的地址没有跨域的概念
        url: 'https://api.douban.com/v2/movie/coming_soon',
        header: {
          'Content-Type': 'json'
        },
        success: function(res){
            console.log(res)
        }
        //发送异步请求 不再是 WEB 那套 ajax
        //2.没有跨域
        //3.请求的地址必须在管理后台添加白名单
        //4.域名必须备案,服务端必须采用HTTPS
      })

      // wx.request({
      //   url: 'https://locally.uieee.com/slides',
      //   success: res => {
      //     this.setData({slides: res.data});
      //   }
      // })

      fetch('slides').then(res => {
        this.setData({ slides: res.data})
      })

      // wx.request({
      //   url: 'https://locally.uieee.com/categories',
      //   success: res => {
      //      this.setData({ categories : res.data })
      //   }
      // })

      
      fetch('slides').then(res => {
        this.setData({ categories: res.data})
      })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

页面间跳转

注意点:

  • tab页跳转到另一个tab页,需要使用navigator的open-type=“switchTab”

    例如:

    <view class="grids">  
       <navigator class="item" url="/pages/message/message" open-type="switchTab">
          <image src="/assets/grid/grid-02.png" />
          <text>美食</text>
       </navigator>
    </view>
    

在这里插入图片描述

在这里插入图片描述

  • 普通跳转 ,注意修改navigator的高宽百分比,不然会空白

在这里插入图片描述

添加了navigator

在这里插入图片描述

列表页分类信息加载

在这里插入图片描述

注意点, 设置分类导航栏的名字的顺序,一定在onReady函数执行完之后。

list.js

 
 /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(2)
    console.log(options)
    //这里不能确定一定是在 onReady过后执行
    fetch(`categories/${options.cat}`).then(res => {
       console.log(res.data)
       //设置导航条
      //  wx.setNavigationBarTitle({
      //    title: res.data.name
      //  })
       this.setData({ category: res.data})
    })
  },

onReady: function () {
      console.log(1)
      if(this.data.category.name){
        wx.setNavigationBarTitle({
          title: res.data.name
        })
      }     
  },

第一页的商铺信息的加载

关键代码:

优化封装的fetch.js,让其可以携带参数

module.exports = (url, data) => {
   return new Promise((resolve, reject) => {
    wx.request({
      url: `https://locally.uieee.com/${url}`,
      data: data,
      success: resolve,
      fail: reject
    })
   })
}

正确使用promise.2个请求,有前后顺序的正确写法:

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(2)
    console.log(options)
    //这里不能确定一定是在 onReady过后执行
    fetch(`categories/${options.cat}`).then(res => {
       console.log(res.data)
       //设置导航条
      //  wx.setNavigationBarTitle({
      //    title: res.data.name
      //  })
       this.setData({ category: res.data})
      
         //加载完分类信息过后再去加载商铺信息
        return  fetch(`categories/${this.data.category.id}shops`,{_page;1,_limit: 10}) 
    })
    .then(res => {
       this.setData({ shops: res.data })
    })

  
  },

上拉加载更多onReachBottom

https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/page.html
在这里插入图片描述

list.json

值越小,越迟钝,看具体需求

{
  "onReachBottomDistance": 20
}

在这里插入图片描述
list.js

// pages/list/list.js
const fetch = require('../../utils/fetch')

Page({

  /**
   * 页面的初始数据
   */
  data: {
    //当前加载的分类
    category:{},
    //子分类下的全部店铺
    shops: [],
    pageIndex:0,
    pageSize:20,
    hasMore: true
  },

  loadMore(){
    if(!this.data.hasMore) return;
    //从data中取出 pageIndex 和 pageSize
    let { pageIndex, pageSize } = this.data
    const params = {_page: ++pageIndex, _limit: pageSize}
    fetch(`categories/${this.data.category.id}/shops`, params) 
    .then(res => {
      const totalCount = parseInt(res.header['X-Total-Count'])
      const hasMore = pageIndex * pageSize < totalCount
        const shops = this.data.shops.concat(res.data)
        this.setData({ shops, pageIndex, hasMore})
     })
  }

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(2)
    console.log(options)
    //这里不能确定一定是在 onReady过后执行
    fetch(`categories/${options.cat}`).then(res => {
       console.log(res.data)
       //设置导航条
      //  wx.setNavigationBarTitle({
      //    title: res.data.name
      //  })
       this.setData({ category: res.data})
      
         //加载完分类信息过后再去加载商铺信息
        this.loadMore();
    })
    

  
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
      console.log(1)
      if(this.data.category.name){
        wx.setNavigationBarTitle({
          title: res.data.name
        })
      }     
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
       //需要判断是否正在加载,否则会有多次触发问题
      console.log('到底了,别啦了');
      this.loadMore();
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

下拉刷新

启动下拉刷新

在这里插入图片描述

list.json

{
  "enablePullDownRefresh": true,
  "onReachBottomDistance": 20
}

停止下拉刷新

https://developers.weixin.qq.com/miniprogram/dev/api/ui/pull-down-refresh/wx.stopPullDownRefresh.html

wx.stopPullDownRefresh(Object object)

// pages/list/list.js
const fetch = require('../../utils/fetch')

Page({

  /**
   * 页面的初始数据
   */
  data: {
    //当前加载的分类
    category:{},
    //子分类下的全部店铺
    shops: [],
    pageIndex:0,
    pageSize:20,
    hasMore: true
  },

  loadMore(){
    if(!this.data.hasMore) return;
    //从data中取出 pageIndex 和 pageSize
    let { pageIndex, pageSize } = this.data
    const params = {_page: ++pageIndex, _limit: pageSize}
    return fetch(`categories/${this.data.category.id}/shops`, params) 
    .then(res => {
      const totalCount = parseInt(res.header['X-Total-Count'])
      const hasMore = pageIndex * pageSize < totalCount
        const shops = this.data.shops.concat(res.data)
        this.setData({ shops, pageIndex, hasMore})
     })
  }

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log(2)
    console.log(options)
    //这里不能确定一定是在 onReady过后执行
    fetch(`categories/${options.cat}`).then(res => {
       console.log(res.data)
       //设置导航条
      //  wx.setNavigationBarTitle({
      //    title: res.data.name
      //  })
       this.setData({ category: res.data})
      
         //加载完分类信息过后再去加载商铺信息
        this.loadMore();
    })
    

  
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
      console.log(1)
      if(this.data.category.name){
        wx.setNavigationBarTitle({
          title: res.data.name
        })
      }     
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
      //重新加载
      this.setData({shops:[],pageIndex:0, hasMore:false});
      this.loadMore()
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
       //需要判断是否正在加载,否则会有多次触发问题
      console.log('到底了,别啦了');
      this.loadMore().then(() => wx.stopPullDownRefresh());
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

详细页:

注意点:

使用wxs行内脚本设置过滤器。但是不支持es6

在这里插入图片描述
预览图片

在这里插入图片描述
在这里插入图片描述
效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G96kqQ69-1593272623869)(本地生活项目.assets/1593266711073.png)]

源码地址:

感谢大神: https://github.com/zce/weapp-locally


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怒放de生命2010

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值