适合后端宝宝体质的微信小程序入门手册

147 阅读10分钟

前言

最近要教会公司后端写微信小程序,所以萌生了写一篇入门手册教给后端宝宝们食用的想法,接下来我们来从几个方面入手。

image.png

什么是微信小程序

微信小程序是运行在微信中的web程序,代码是部署在微信云服务器上的。

优势

  • 无需下载安装,无需注册,用完即走,不会过多地占用手机内存
  • 小程序可以跨平台(苹果或安卓系统)运行,其开发门槛和成本比APP开发要低
  • 打开速度比H5(HTML5)要快,接近于原生App的体验
  • 安卓手机可以直接添加小程序至手机桌面,打开方式和App一样方便
  • 可以借用微信的用户群体,方便营销推广。

劣势

  • 小程序目前无法直接分享至朋友圈,只能分享给微信好友或微信群
  • 小程序的二维码不支持长按识别,只能通过微信扫一扫才能打开
  • 小程序没有push功能,不能给用户推送消息和个人相关的通知消息
  • 小程序没有用户体系,用户不需要注册,因此用户用完即走,很难形成用户体系

怎么开发一款小程序

我的理解是开发小程序要分为4大步骤:注册、信息完善、开发小程序、审核和发布小程序

  1. 注册:在微信公众平台注册小程序,完成注册后可以同步进行信息完善和开发,注意APPID,这个要配置在小程序开发工具中,记得保存下来。
  2. 信息完善:在注册完小程序后填写小程序基本信息,包括名称、头像、介绍及服务范围等。
  3. 开发小程序:工欲善其事必先利其器,先配置开发者工具,在进行小程序开发。
  4. 审核和发布小程序:完成小程序开发后,提交代码至微信团队审核,审核通过后即可发布

开发小程序工具配置

注册成功后,可登录,然后获取 APPID

image.png

image.png

小程序开发必须要在专门的开发者工具进行开发,开发者工具下载地址 下载完成之后新建小程序,输入项目名称、目录、AppID等,还可以选择微信提供的一些模板,快速生成一个功能相对齐全的小程序。

image.png 这里有两种开发模式,一种是云服务,我的理解是调用远程代码库的函数和存储实现一个小程序,另外一种不使用云服务,则是本地编写代码实现自己的小程序。

如下是现有项目进行改造,则在右上角的详情中修改成申请下来的APPID

image.png

配置完成后,即可进行开发,整个工具的分布如下 image.png

小程序调试工具介绍

小程序的调试工具类似浏览器的调试工具,分为以下几个功能模块:

  • Wxml:页面结构和结构对应的 wxss 属性
  • Console:控制台,输出提示信息
  • Sources:当前项目的脚本文件
  • Network:观察和显示requestsocket的请求情况
  • Perfomance:性能分析
  • Memory:内存
  • AppData:当前小程序的具体数据
  • Storage:显示当前项目使用wx.setStorage或者wx.setStorageSync存储的数据
  • Security: 安全性
  • Sensor:模拟地理位置和模拟移动设备表现,用于调试重力感应 API
  • Mock:模拟接口
  • Audits:体验评分检测
  • Vulnerability:发现并修复小程序内的接口安全漏洞,提升小程序安全性 image.png

小程序框架介绍

微信团队为小程序提供的框架命名为 MINA 应用框架 ,通过封装微信客户端提供的文件系统、网络通信、任务管理、数据安全等基础功能,对上层提供一整套Javascript API,让开发者能够方便的使用微信提供的各种功能与能力。

小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。

由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS 脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由Native进行转发。

屏幕截图 2024-06-20 220555.png

MINA框架支持mvvm模式,vue、React、Angular也是mvvm模式的支持者。 MVVM的核心是ViewModel层,负责转换Model层中的数据对象来让数据更容易管理和使用,向上与View视图层进行双向数据绑定,向下与Model层通过接口请求进行数据交互,起承上启下的作用

屏幕截图 2024-06-20 220821.png

小程序文件介绍

小程序框架提供了自己的视图层描述语言 WXML 和 WXSS,以及 JavaScript,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。

image.png 注意pages页面(小程序的每一个页面)由4个文件组成:

  • js: 页面逻辑,相当于控制层,也包括部分数据
  • wxml:页面结构展示,相当于视图层(view)
  • json:页面配置,配置一些页面展示的数据,充当部分的模型
  • wxss:页面样式表

小程序页面生命周期

  • onLoad:页面创建时执行
  • onShow:页面出现在前台时执行
  • onReady:页面首次渲染完毕时执行
  • onHide: 页面从前台变为后台时执行
  • onUnload: 页面销毁时执行
  • onPullDownRefresh: 触发下拉刷新时执行
  • onReachBottom: 页面触底时执行
  • onShareAppMessage: 页面被用户分享时执行
  • onPageScroll: 页面滚动时执行
  • onResize: 页面尺寸变化时执行
  • onTabItemTap:tab 点击时执行
Page({
    data: {
        name:'木子呀'
    }, 
    onLoad() {
        console.log('页面创建时执行');
    },
    onShow() {
        console.log('页面出现在前台时执行');
    },
    onReady() {
        console.log('页面首次渲染完毕时执行');
    },
    onHide() {
        console.log('页面从前台变为后台时执行,也就是隐藏时执行');
    },
    onUnload() {
        console.log('页面销毁时执行');
    },
    onPullDownRefresh() {
        console.log('触发下拉刷新时执行');
    },
    onReachBottom() {
        console.log('页面触底时执行');
    },
    onShareAppMessage() {
        console.log('页面被用户分享时执行');
    },
    onPageScroll() {
        console.log('页面滚动时执行');
    },
    onResize() {
        console.log('页面尺寸变化时执行');
    },
    onTabItemTap() {
        console.log('tab 点击时执行');
    },
    //这样定义的不会是mvvm响应的参数
    no_mvvm_params:{
        id:'00001'
    },
    
    getList(){
         console.log('自定义事件,比如获取后台数据');
    },
    //...可以根据需求实现很多自定义事件。
})

小程序应用生命周期

  • onLaunch:监听小程序初始化
  • onShow:监听小程序启动或切前台
  • onHide:监听小程序切后台
  • onError: 错误监听函数
  • onPageNotFound: 页面不存在监听函数
App({
    data: {
        name:'木子呀'
    }, 
    onLaunch() {
        console.log('监听小程序初始化');
    },
    onShow() {
        console.log('监听小程序启动或切前台');
    },
    onHide() {
        console.log('监听小程序切后台');
    },
    onError() {
        console.log('错误监听函数');
    },
    onPageNotFound() {
        console.log('页面不存在监听函数');
    },
})

全局配置 app.json

app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。普通快速启动项目里边的 app.json 配置

{
  //路由
  "pages": [
    "pages/home/index",
  ],
  //授权
  "permission": {
    "scope.userLocation": {
      "desc": "需要获取您的地理位置,请确认授权"
    },
  },
  //导航栏配置
  "window": {
    "navigationBarBackgroundColor": "#ffffff",
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "小程序"
    "backgroundTextStyle":"light"
  },
  //超时时间
  "networkTimeout": {
    "request": 75000
  },
  //底部tabBar
  "tabBar": { 
      "list": [ 
          { "pagePath": "pages/index/index", //跳转的路径 
            "text": "首页", //名称 
            "iconPath": "./tabs/tab_home_nor@3x.png", // 图标 
            "selectedIconPath": "./tabs/tab_home_fill@3x.png" //选中的图标
          },
          { 
            "pagePath": "pages/user/index", 
            "text": "我的", 
            "iconPath": "./tabs/tab_my_nor@3x.png", 
            "selectedIconPath": "./tabs/tab_my_fill@3x.png" 
          } 
      ] 
  }
}

window导航栏配置

image.png

tabBar配置

image.png

小程序语法

  1. set参数
Page({
    data: {
        name:'木子呀'
    },
    setparams(){
        this.setData({
          name:'木子'
          //names是在data中声明的参数
        })    
    }
})

2.数据绑定

Page({
    data: {
        name:'木子呀'
    },
})

index.wxml
<view> {{ name }} </view>

3.组件属性

Page({
    data: {
        name:'木子呀',
        key:'001'
    },
})

index.wxml
<view key={{key}}> {{ name }} </view>

4.bool 类型

 <!--不要直接写 checked="false",其计算结果是一个字符串-->
<checkbox checked="{{false}}"> </checkbox>

5.运算

Page({
    data: {
        name:'木子呀'
        age:10,
        age_two:8
    },
})

index.wxml
 <!--三元运算-->
<view hidden="{{name === '木子呀' ? true : false}}"> Hidden </view>
 <!--算数运算-->
 <view> {{age + age_two}} </view>
 <!--逻辑判断-->
 <view wx:if="{{age > 5}}"> </view>
  <!--字符串运算-->
 <view> {{'hello' + name}} </view>

6.循环和if判断

Page({
    data: {
        array:[{message:'aaa'}]
    },
})

index.wxml
 <!--key可以提高渲染性能,但必须是唯一的,如果可变的列表涉及增删不能用index-->
 <!--循环体内会默认抛出index和item-->
<view wx:for="{{array}}" wx:key="{{item.message}}"> {{index}}: {{item.message}} </view>

7.标签和事件以及参数传递

框架设计的一套标签语言,结合基础组件事件系统,可以构建出页面的结构。

<!--视图容器-->
<view>这里是试图内容</view>
<!--文本-->
<text>这里面是文本</text>
<!--image图片-->
<image src="../../img.jpg"></image>
<!--输入框-->
<input value="{{name}}"></input>
<!--button按钮-->
<button></button>
<!--textarea长文本输入框-->
<textarea></textarea>
<!--picker下拉框-->
<picker></picker>
<!--通过bind指令实现事件绑定-->
<!--点击事件-->
<view bindtap='click'>这里是试图内容</view>
<!--输入事件-->
<view bindinput='click'>这里是试图内容</view>
<!--手指触摸动作开始-->
<view bindtouchstart='click'>这里是试图内容</view>
<!--手指触摸后移动-->
<view bindtouchmove='click'>这里是试图内容</view>
<!--绑定事件时不能带参数 不能带括号 ------以下为错误写法 -->
<view bindtap='click(100)'>这里是试图内容</view>
<!--绑定事件时传递参数 ------以下为正确写法 -->
<view bindtap='click' data-name='{{name}}'>这里是试图内容</view>

js
click(e){
    //拿到的参数
    console.log(e.target.dataset.name);
},

样式文件wxss

样式语言,具有css大部分的特性,wxsscss基础上做了一些扩充和修改。

新增尺寸单位rpx,可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

image.png

子组件配置,以及触发父子组件事件

payPage.wxml
<view>
<payAccount id="childPayAccount"  bindpayAccount="payAccount" ></payAccount>
<view bindtap="handerClickChild">点我调用子组件<view>
<view>

payPage.json
{
  "usingComponents": {
    "payAccount":"/components/payAccount/payAccount",
  }
}

payPage.js
//父组件声明的方法
payAccount(e){
    console.log( e.detail);
}
//父组件调用子组件
handerClickChild(e){
    //通过id获取子组件
    const child = this.selectComponent("#childPayAccount")
    //父组件调用子组件
    child.childMethod()
}


<!--子组件-->
payAccount.wxml
<view bindtap="handerClick">payAccount子组件<view>

payAccount.js
//子组件调用父组件
handerClick(){
    this.triggerEvent("payAccount",'点击了执行emit');
}
//子组件的方法
childMethod(){
    console.log('调用子组件的方法');
}

小程序路由跳转的几种方式以及传参

//保留当前页面,跳转到应用内的某个页面 
wx.navigateTo({ url: '/pages/detail/detail?id=1' })

//关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
wx.redirectTo({ url: `/pages/detail/detail`, })

//跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面(不可以携带参数)
wx.switchTab({ url: `/pages/detail/detail`, })

//关闭当前页面, delta值为1 ,表示跳转上一页,2表示跳两级 ,可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层.
wx.navigateBack({ delta:1 })

//关闭所有页面,打开到应用内的某个页面
wx.reLaunch({ url: '/pages/detail/detail' })


//跳转路由传参
let name = '木子'
wx.navigateTo({
  url: '/pages/demo/demo?name='+name
})

demo.js
onLoad(data) {
    console.log(data.name);
},

小程序获取授权

通过微信官方提供的api可以获取用户的信息,在获取之前需要用户授权。

// 获取用户信息授权
wx.getUserProfile({
    desc: '用于完善会员资料', // 必填,声明获取用户个人信息后的用途
    success: (res) => {
        console.log(res.userInfo);
        // 处理用户信息
    },
    fail: (err) => {
        console.log('用户信息授权失败', err);
    }
});

// 获取手机号码授权
wx.getPhoneNumber({
    success: (res) => {
        // 获取解密后的手机号
        const decryptedData = wx.decryptData(res.encryptedData, res.iv);
        console.log(decryptedData.phoneNumber);
        // 处理手机号
    },
    fail: (err) => {
        console.log('手机号码授权失败', err);
    }
});

小程序登录

参考小程序登录方案官方答案,登录流程如下 image.png

小程序发布

开发过程中,我们可以通过微信开发者工具的『预览』和『真机调试』功能进行调试。 没问题后通过微信开发者工具的『上传』按钮进行代码上传。

image.png

image.png

image.png

上传成功后会出现上传成功的提示,还会出现如下的代码质量提示

image.png

有时还会出现如下上传失败的提示

image.png

image.png

这时就需要进行分包优化,参考这里,分包优化后重新进行上传。

上传成功后,登录『微信公众平台』查看『版本管理』,就可以看到我们刚才上传的版本代码

image.png