前言

对Vue开发有一定了解,对微信小程序比较感兴趣,想要理解其开发流程,这篇文章可以帮助你少踩一些坑,实现并发布自己的第一个微信小程序。
gh_933be55951e2_258 (1).jpg

准备工作

  1. 登陆微信公众平台-小程序:https://mp.weixin.qq.com/cgi-bin/wx,完成申请与注册,生成一个重要的AppID(小程序唯一身份证:开发→开发设置获取)。
  2. 安装小程序开发工具:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html,界面使用类其他编译器,点击上方编译可在模拟器查看效果,点击预览可用手机扫码查看效果,如图:Jietu20191120-150156.jpg
  3. 创建第一个小程序项目,填入AppID。选择云开发可使用云函数、云数据库、云存储功能,如图:18237192-dcfbec816161eb51.png
  4. 小程序详细开发文档:https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/(遇到问题一定要看文档!看文档!看文档!重要的事情说3遍!!!详细易懂,少走弯路)

一. 小程序代码构成

1)文件目录:

.
├── cloudfunctions # 云开发函数
│   ├── login //登陆文件夹
│   │     ├── index.js //登陆云函数
│   │     └──package.json //npm包依赖
│   └── movielist //获取电影列表文件夹
├── miniprogram #本地开发目录
│   ├── style //静态wxss文件
│   ├── fonts //字体图标文件
│   ├── images //图片
│   ├── components //存放公共组件库
│   ├── utils //全局js方法
│   │     └── common.wxs //js处理方法
│   ├── pages //各页面
│   │     ├── movie //电影列表
│   │     │     ├── movie.js
│   │     │     ├── movie.json
│   │     │     ├── movie.wxml
│   │     │     └── movie.wxss
│   │     └── detail //电影详情
│   │           ├── detail.js
│   │           ├── detail.json
│   │           ├── detail.wxml
│   │           └── detail.wxss
│   ├── app.js //全局注册小程序对象
│   ├── app.json //全局配置
│   ├── app.wxss //全局样式
│   └── package.json //npm配置文件
├── project.config.json #项目配置文件
└── README.md #README

2).json 后缀的 JSON 配置文件:

  • app.json全局配置小程序的页面路由,底部tab,顶部标题等。
  • page.json页面配置可以声明不同于全局的配置,只在该页面生效,还可引入组件。

pages字段控制当前所有页面路径,第一个默认为首页;
window字段控制窗口背景颜色,标题等;
tabBar控制分成几个tab页,list数组长度2~5,参数有图标、字体颜色、页面路由。

<!-- app.json -->
//全局配置文件
"pages": [
    "pages/movie/movie",//第一个默认为首页
    "pages/profile/profile",
    "pages/detail/detail"
  ],
  "window": {
    "backgroundColor": "#F6F6F6",//下拉背景颜色
    "backgroundTextStyle": "light",//下拉字体样式
    "navigationBarBackgroundColor": "#00B51D",//窗口头部背景色
    "navigationBarTitleText": "最新电影",//窗口头部文案
    "navigationBarTextStyle": "white"//窗口头部字体颜色
  },
  "tabBar": {
    "color": "#000000",//tab栏默认字体颜色
    "selectedColor": "#E54847",//tab栏选中字体颜色
    "list": [{
      "pagePath": "pages/movie/movie",//tab路径
      "text": "电影",//tab栏文案
      "iconPath": "images/film.png",//默认图标路径
      "selectedIconPath": "images/film-actived.png"//选中图标路径
    },{
      "pagePath": "pages/profile/profile",
      "text": "我的",
      "iconPath": "images/profile.png",
      "selectedIconPath": "images/profile-actived.png"
    }]
  },
<!-- detail.json -->
//子页面配置文件
{
  "usingComponents": {//注册vant-ui插件
    "van-button": "vant-weapp/button",//按钮组件
    "van-rate": "vant-weapp/rate",//评分组件
    "van-icon": "vant-weapp/icon"//图标组件
  },
  "navigationBarBackgroundColor": "#333",//子页面标题背景色
  "navigationBarTextStyle": "white",//子页面字体颜色
  "navigationBarTitleText": "电影详情",//子页面标题
  "backgroundColor": "#eee",//子页面下拉刷新背景色
  "backgroundTextStyle": "dark",//子页面下拉刷新字体色
  "enablePullDownRefresh": true//子页面下拉刷新
}

3).wxml 后缀的 WXML 模板文件:

主要控制页面结构,开发模式为MVVM可参考Vue,注意如下:

  1. div,span等标签换为了view,text;
  2. 微信提供了一些现成组件:轮播图、日历、进度条等等,也可使用UI库vant-weapp。
  3. 在wxml文件中不能使用js方法,需在小程序脚本语言wxs文件中(不允许引入js文件)定义好处理数据的函数,然后在wxml中引入可使用。
<!-- common.wxs -->
var filter = {
    arrJoin: function(value){ return value.join('/') },
    formatDate: function(value){
        var date = getDate(value) return date.getFullYear() + '年' + date.getMonth() + '月' + date.getDate() + '日'
} }
module.exports={ arrJoin: filter.arrJoin, formatDate: filter.formatDate }
<!-- movie.wxml -->
<wxs module="filter" src="../../utils/common.wxs"></wxs>
<view class="movie" wx:for="{{movieList}}" wx:key="{{index}} wx:for-item="detailList"">
  ...
  <!--调用wxs文件中的数组分割方法-->
  <view>类型:{{filter.arrJoin(detailList.genres)}}</view>
  <!--调用wxs文件中的时间格式化方法-->
  <text class="tag-text">{{filter.formatDate(detailList.created_at)}}</text>
  ...
  <!--使用按钮和评分组件-->
  <van-rate value="{{detailList.rating.average}}" size="12" void-color="#999" void-icon="star" />
  <van-button icon="like-o" type="primary" size="small">想看</van-button>
  ...
</view>

4).wxss 后缀的 WXSS 样式文件:

提供了新的尺寸单位rpx(可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素)。推荐使用iPhone6为设计稿,单位之间好换算,字体一般用px。

设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度)
iPhone5 1rpx = 0.42px 1px = 2.34rpx
iPhone6 1rpx = 0.5px 1px = 2rpx
iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx
/* pages/movie/movie.wxss */
@import '../../style/common.wxss'; /* 引入公共样式 */

.movie{
  height: 420rpx;
  display: flex;
  border-bottom: 1rpx solid #eee;
  padding: 20rpx;
  color: #666;
}
.mv-img{
  height: 100%;
  width: 300rpx;
  margin-right: 20rpx;
}
...

5).js 后缀的 JS 脚本逻辑文件:

注意事项:

  1. 点击事件不能在方法中直接传参数,需要data-id="id"定义,通过e.currentTarget.dataset.id获取;
  2. 给data中数据赋值时需this.setData({id: e.currentTarget.dataset.id}),获取值方式为this.data.id。
<!--movie.wxml-->
...
<view class="collect-item" bindtap="gotoDetail" data-movieid="{{item.id}}">
...
<!--movie.js-->
getMovie: function(){//获取电影列表,从云函数movielist获取
    wx.showLoading({//调用微信加载组件
      title: '加载中',
    })
    wx.cloud.callFunction({//请求云函数
      name: 'movielist',
      data: {
        start: this.data.movieList.length,
        count: 10
      }
    }).then(res=>{
      console.log(JSON.parse(res.result).subjects)
      this.setData({//将返回结果赋值给movieList
        movieList: this.data.movieList.concat(JSON.parse(res.result).subjects)//数组拼接
      })
      wx.hideLoading()//返回结果关闭加载
    }).catch(err=>{
      console.log(err)
      wx.hideLoading()//返回错误关闭加载
    })
  },
gotoDetail: function (e) {//跳转至新页面
  wx.navigateTo({ 
    url: `../detail/detail?movieid=${e.currentTarget.dataset.movieid}`, 
  }) 
},

二、使用npm安装第三方插件

  1. 右键点击项目在终端打开,执行npm init初始化package.json文件;
  2. 执行npm install XX --production;
  3. 勾选 详情->本地设置→使用npm模块;
  4. 点击工具→构建npm,即可在项目中使用;

三、微信原生API

可以方便的调起微信提供的能力,列举一些常用API:

  • wx.navagateTo:保留当前页面,跳转到除了tabbar的其他页面,最多打开5个页面,可返回上一页;
  • wx.redirectTo:关闭当前页面,跳转到除了tabbar的其他页面;
  • wx.switchTab:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面;
  • wx.showToast:显示消息提示框,可设置延时消失;
  • wx.showLoading:显示 loading 提示框。需主动调用 wx.hideLoading 才能关闭提示框;
  • wx.request:发起HTTP网络请求;
  • wx.chooseImage:从本地相册选择图片或使用相机拍照,视频/音频/文件同理;
  • wx.getLocation:获取当前的地理位置、速度;
  • wx.chooseLocation:打开地图选择位置,可获取目标经纬度和详细地址;
  • wx.getUserInfo:获取用户信息,用户昵称、性别、头像、国家城市、语言等;
  • wx.getWeRunData:获取用户过去30天微信运动步数;
  • wx.scanCode:调起客户端扫码界面进行扫码;
  • wx.makePhoneCall:拨打电话;

......

三、云开发

1)云数据库:

云开发提供了一个 JSON 数据库,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。支持导入导出。
云开发可视化面板

// 1. 获取数据库引用
// collection 方法获取一个集合的引用
const db = wx.cloud.database()

//2. 构造查询语句 
// get 方法会触发网络请求,往数据库取数据
// where 方法传入一个对象,数据库返回集合中字段等于指定值的 JSON 文档。API 也支持高级的查询条件(比如大于、小于、in 等)
db.collection('movie-collect').where({
   _openid: res.result.openid
   }).get().then(res=>{
   console.log(res)
 }).catch(err=>{
   console.log(err)
 })

// 3. 构造插入语句
// add 方法会触发网络请求,往数据库添加数据
db.collection('user').add({
   data: {
     name: 'ywbj',
     age: 20
   }
 }).then(res => {
   console.log(res)
 }).catch(err => {
   console.log(err)
 })
},

// 4. 构造更新语句
// update 方法会触发网络请求,往数据库更新数据(doc中为唯一id)
db.collection('user').doc('dc9a49695da03b0f023d6cfd2fa15012').update({
 data: {
   age: 18
 }
 }).then(res => {
   console.log(res)
 }).catch(err => {
   console.log(err)
 })
},

// 5. 构造删除语句
// delete 方法会触发网络请求,使数据库删除数据(注意:在小程序中只能删除单条数据,批量删除需在云函数中操作)
db.collection('user').where({
   name: 'ywbj'
 }).remove()
 .then(res => {
   console.log(res)
 }).catch(err => {
   console.log(err)
 })
},

2)云存储:

云开发提供了一块存储空间,提供了上传文件到云端、带权限管理的云端下载能力,开发者可以在小程序端和云函数端通过 API 使用云存储功能。在小程序端可以分别调用 wx.cloud.uploadFile 和 wx.cloud.downloadFile 完成上传和下载云文件操作。

//上传文件
wx.chooseImage({// 让用户选择一张图片,生成临时图片路径
  success: chooseResult => { // 将图片上传至云存储空间
      wx.cloud.uploadFile({ // 指定上传到的云路径
          cloudPath: 'my-photo.png', // 指定要上传的文件的小程序临时文件路径
          filePath: chooseResult.tempFilePaths[0],
          success: res => { 
            console.log('上传成功,返回文件ID', res.fileID) 
          },
      }) 
   }
})
//下载文件
wx.cloud.downloadFile({
  fileID: '', // 文件 ID
  success: res => { // 返回临时文件路径 console.log(res.tempFilePath) },
  fail: console.error
})

3)云函数:

云函数是一段运行在云端的代码,无需管理服务器,在开发工具内编写、一键上传部署即可运行后端代码。可将功能相同的函数封装并上传至云函数统一调用,另外使用云函数发送请求的好处,不受5个可信域名限制,无需备案。发请求需npm安装request-promise并引入:https://github.com/request/request-promise

<!--movielist/index.js-->// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
var rp = require('request-promise')
// 云函数入口函数,假设已有一个获取电影列表的接口
exports.main = async (event, context) => {
 return rp(`http://api.douban.com/v2/movie/in_theaters?apikey=0df993c66c0c636e29ecbb5344252a4a&start=${event.start}&count=${event.count}`)
 .then(res => {
 return res
 })
}
 
<!--movie.js-->
wx.cloud.callFunction({
 name: 'movielist',
 data: {
   start: this.data.movieList.length,
   count: 10
 }
 })

倒不了的dota
29 声望5 粉丝

积跬步,致千里