Python - 微信小程序(入门)

问题

  • 什么是微信小程序?

    微信小程序,小程序的一种,英文名 Wechat Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用 触手可及 的梦想,用户扫一扫或搜一下即可打开应用。

  • 为什么要做微信小程序?
    • 微信用户基数大,
    • 在微信上用我们的小程序会比较便捷。
  • 如何开发微信小程序?
    • 小程序:微信开发的语言(前段 HTML、CSS、JS、VUE)
      • 微信开发者工具
    • API:RESTful 接口(Python+Django+DRF 架构)

环境搭建

  • Python 环境

    • 虚拟环境
      1
      2
      Django==3.2.8
      djangorestframework==3.12.4
    • PyCharm
  • 小程序环境

    1. 微信公众平台申请一个小程序
    2. 保存自己的 AppID (小程序 ID)
    3. 下载开发者工具
    4. 安装并运行开发者工具,然后用微信扫码进入开发者工具
    5. 创建小程序
      创建小程序

尺寸单位

  • px:不推荐使用。
  • rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素。
  • 建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
  • 注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

小程序公共对象

  • app.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    App({

    /**
    * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
    */
    onLaunch: function () {

    },
    globalData:{
    userInfo: null,
    }
    })
  • 其他页面操作公共值
    1
    2
    3
    4
    5
    6
    7
    8
    var app = getApp();
    Page({
    data: {
    },
    onShow:function(){
    app.globalData
    }
    });
  • 注意
    修改 globalData 之后,其他页面以用的值不会自动变化,而是需要手动设置。

小程序的生命周期

  1. onLoad

    • 生命周期函数 -- 监听页面加载,第一次带开始会执行 生命周期回调 — 监听页面加载
    • 页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
  2. onShow

    • 生命周期函数 -- 监听页面显示 生命周期回调 — 监听页面显示
    • 页面显示 / 切入前台时触发。
  3. onReady

    • 生命周期函数 -- 监听页面初次渲染完成,第一次带开始会执行 生命周期回调 — 监听页面初次渲染完成
    • 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
    • 注意:对界面内容进行设置的 API 如 wx.setNavigationBarTitle,请在 onReady 之后进行。
  4. onHide

    • 生命周期函数 -- 监听页面隐藏 生命周期回调 — 监听页面隐藏
    • 页面隐藏 / 切入后台时触发。 如 navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。
  5. onUnload

    • 生命周期函数 -- 监听页面卸载 生命周期回调 — 监听页面卸载
    • 页面卸载时触发。如 redirectTonavigateBack 到其他页面时。
  6. onPullDownRefresh

    • 页面相关事件处理函数 -- 监听用户下拉动作 监听用户下拉动作
    • 监听用户下拉刷新事件。
      • 需要在 app.jsonwindow 选项中或页面配置中开启 enablePullDownRefresh
      • 可以通过 wx.startPullDownRefresh 触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
      • 当处理完数据刷新后,wx.stopPullDownRefresh 可以停止当前页面的下拉刷新。
  7. onReachBottom

    • 页面上拉触底事件的处理函数 页面上拉触底事件的处理函数
    • 监听用户上拉触底事件。
      • 可以在 app.jsonwindow 选项中或页面配置中设置触发距离 onReachBottomDistance
      • 在触发距离内滑动期间,本事件只会被触发一次。
  8. onShareAppMessage

    • 用户点击右上角分享 用户点击右上角转发
    • 监听用户点击页面内转发按钮(<button> 组件 open-type="share")或右上角菜单 “转发” 按钮的行为,并自定义转发内容。
    • 注意:只有定义了此事件处理函数,右上角菜单才会显示 “转发” 按钮
    • 此事件需要 return 一个 Object,用于自定义转发内容

全局 app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)

// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})

var userInfo = wx.getStorageSync('userInfo')
if (userInfo) {
this.globalData.userInfo = userInfo
}
},

globalData: {
userInfo: ''
},

initUserInfo: function (result, localInfo) {
var info = {
token: result.token,
phone: result.phone,
nickName: localInfo.nickName,
avatarUrl: localInfo.avatarUrl
}
// 1. 去公共的app.js中调用globalData,在里面赋值(在全局变量赋值)
this.globalData.userInfo = info // {phone:xxx, token:xxx}
// 2. 在本地的“cookie”中赋值
wx.setStorageSync('userInfo', info)
},

deleteUserInfo: function () {
this.globalData.userInfo = null;
wx.removeStorageSync('userInfo');
}
})

最先加载

页面传值

  • 父页面向子页面传值

    • 父页面

      1
      2
      3
      4
      5
      6
      7
      <!-- 方式一 -->
      <navigator url="/pages/redirect/redirect?id=666">跳转到新页面</navigator>

      <!-- 方式二 -->
      wx.navigateTo({
      url: '/pages/redirect/redirect?id=666',
      })
    • 子页面

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      // redirect.js
      Page({
      ......
      /**
      * 生命周期函数--监听页面加载
      */
      onLoad: function (options) {
      console.log(options);
      },
      })
  • 子页面向父页面传值

    • 子页面

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      Page({
      ......
      choseTapic: function (e) {
      console.log(e)
      var topicInfo = e.currentTarget.dataset.xxx;
      // 把这个值传递给父页面
      var pages = getCurrentPages();
      var prevpage = pages[pages.length - 2];
      // prevpage.setData({topicText: topicInfo.title})
      prevpage.setTopicData(topicInfo)
      wx.navigateBack({})
      },
      })

      注意:可以通过 data-xxx 可以给事件传值

腾讯云的对象存储

  • 简介

    • 第一阶段:文件服务器,将文件存储在某个服务器(目录结构的划分)。
      • 第二阶段:
        • 文件存储:将文件存储在某个服务器(目录结构的划分)。
        • 对象存储:存储优化和操作优化(不支持目录结构的划分)。
    • 第三阶段:云服务(阿里 / 腾讯 / 七牛 / 亚马逊)
      • 文件存储
        • 对象存储
  • 快速入门(腾讯云 COS)

    • 注册相关信息
    • 开发文档

修改 data 中的局部数据

  • progress.wxml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!--pages/progress/progress.wxml-->
    <view>======案例======</view>
    <view>单击按钮完成,将图片1的进度条更新为80%</view>
    <view wx:for="{{imageList}}">
    <view>{{item.title}}</view>
    <view class="progress-box">
    <progress percent="{{item.percent}}" active show-info />
    </view>
    </view>

    <button bindtap="changePercent">点击</button>
  • progress.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Page({
    data: {
    imageList: [
    { id: 1, title: '图片1', percent: 20 },
    { id: 2, title: '图片2', percent: 40 },
    { id: 3, title: '图片3', percent: 60 },
    ]
    },
    changePercent: function () {
    // 方式1
    /*
    var dataList = this.data.imageList;
    dataList[0].percent = 80;
    this.setData({
    imageList: dataList
    })
    */
    // 方式2(推荐)
    this.setData({
    ["imageList[0].percent"]: 80,
    ["imageList[1].percent"]: 90,
    ["imageList[2].title"]: "点我一下试试",
    })
    },
    )}

闭包

1
2
3
4
5
6
7
8
9
10
11
var dataList = ["apple", "banana", "peach"]
for (var i in dataList) {
(function (data) {
wx.request({
url: 'xxx',
success: function (res) {
console.log(data)
}
})
})(dataList[i])
}
  • 简介

    • flex 的概念最早是在 2009 年被提出,目的是提供一种更灵活的布局模型,使容器能通过改变里面项目的高宽、顺序,来对可用空间实现最佳的填充,方便适配不同大小的内容区域。
    • 一种非常方便的布局方式,在容器中记住 4 个样式即可。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      /* 规定使用flex布局 */
      display: flex;
      /* row:规定主轴方向为水平;column:规定主轴方向为垂直 */
      /* 让容器中的子元素按行排列 */
      flex-direction: row;
      /* 规定在主轴方向上如何展示:flex-start/center/space-around/space-between/flex-end */
      /* 让容器中的子元素在水平方向上平均排列 */
      justify-content: space-around;
      /* 规定在副轴方向上如何展示:flex-start/center/flex-end */
      align-items: center;
  • 示例 1 和 2

    • index.wxml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      <view>示例一</view>
      <view class="menu-1">
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      </view>

      <view>示例二</view>
      <view class="menu-2">
      <view class="item">
      <image src="/static/images/mn.jpg"></image>
      <text>精品</text>
      </view>
      <view class="item">
      <image src="/static/images/mn.jpg"></image>
      <text>精品</text>
      </view>
      <view class="item">
      <image src="/static/images/mn.jpg"></image>
      <text>精品</text>
      </view>
      <view class="item">
      <image src="/static/images/mn.jpg"></image>
      <text>精品</text>
      </view>
      </view>
    • index.wxss

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      /**index.wxss**/
      image {
      width: 100rpx;
      height: 100rpx;
      border-radius: 50rpx;
      }

      .menu-1 {
      display: flex;
      flex-direction: row;
      justify-content: space-around;
      }

      .menu-2 {
      /* 规定使用flex布局 */
      display: flex;
      /* row:规定主轴方向为水平;column:规定主轴方向为垂直 */
      /* 让容器中的子元素按行排列 */
      flex-direction: row;
      /* 规定在主轴方向上如何展示:flex-start/center/space-around/space-between/flex-end */
      /* 让容器中的子元素在水平方向上平均排列 */
      justify-content: space-around;
      /* 规定在副轴方向上如何展示:flex-start/center/flex-end */
      /* align-items: center; */
      }

      .menu-2 .item {
      display: flex;
      flex-direction: column;
      align-items: center;
      }
    • 效果图

      Flex布局

  • 示例 3

    • index.wxml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      <view>示例三</view>
      <view class="auction">
      <view class="item">
      <view class="title">第一场 拍卖龚名扬吃的东西</view>
      <view class="tips">
      <view class="status">2021-11-01</view>
      <view class="count">1111次围观</view>
      </view>
      <view class="big">
      <image src="/static/images/mn.jpg"></image>
      </view>
      <view class="small">
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      </view>
      </view>

      <view class="item">
      <view class="title">第二场 拍卖龚名扬吃的东西</view>
      <view class="tips">
      <view class="status">2021-11-01</view>
      <view class="count">1111次围观</view>
      </view>
      <view class="big">
      <image src="/static/images/mn.jpg"></image>
      </view>
      <view class="small">
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      <image src="/static/images/mn.jpg"></image>
      </view>
      </view>
      </view>
    • index.wxss

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      .auction .item {
      margin-bottom: 50rpx;
      }

      .auction .item .title {
      font-size: 50rpx;
      font-weight: 600;
      }

      .auction .item .tips {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      font-size: 30rpx;
      color: gray;
      }

      .auction .item .big {
      height: 400rpx;
      overflow: hidden;
      }

      .auction .item .big image {
      width: 100%;
      height: 100%;
      }

      .auction .item .small {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      }

      .auction .item .small image {
      height: 100rpx;
      width: 100rpx;
      padding-right: 20rpx;
      }
    • 效果图

      Flex布局