前言
本篇文章记录了学习微信小程序时遇到的一些问题和知识点,学习材料是coderwhy老师的视频。
本地开发环境设定与修改
微信开发者工具将个人对工具做的所有配置都写入到了project.config.json
文件中,当更换电脑或重装时,只需要载入同一个项目的代码包,开发者工具就自动会帮开发者恢复到当时开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。
需要注意project.config.json
和 project.private.config.json
两个文件的区别,private
是个人的配置且优先级更高,以下来源于微信开发文档:
- 项目根目录中的
project.config.json
和 project.private.config.json
文件可以对项目进行配置,
project.private.config.json
中的相同设置优先级高于 project.config.json
- 可以在
project.config.json
文件中配置公共的配置,在 project.private.config.json
配置个人的配置,可以将 project.private.config.json
写到 .gitignore
避免版本管理的冲突。
project.private.config.json
中有的字段,开发者工具内的设置修改会优先覆盖 project.private.config.json
的内容。如在 project.private.config.json
有 appid
字段,那么在 详情 - 基本信息 中修改了 appid,会写到 project.private.config.json
中,不会覆盖掉 project.config.json
的 appid
字段的内容
- 开发阶段相关的设置修改优先同步到
project.private.config.json
中,但与最终编译产物有关的设置无法在 project.private.config.json
中生效,界面上的改动也不会同步到 project.private.config.json
文件中。详见 表格是否允许私有设置。
当需要更换版本、修改本地调试的设置时,打开开发工具右上角的详情,修改本地设置即可。

页面下拉刷新与上拉加载
针对单个页面(page)实现下拉刷新和上拉加载,需要用到onPullDownRefresh
和onReachBottom
两个函数,对需要实现的页面配置page.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
| Page({ data: { avatarURL: "", listCount: 30 },
onPullDownRefresh() { console.log("用户进行下拉刷新~");
setTimeout(() => { this.setData({ listCount: 30 })
wx.stopPullDownRefresh({ success: (res) => { console.log("成功停止了下拉刷新", res); }, fail: (err) => { console.log("失败停止了下拉刷新", err); } }) }, 1000) },
onReachBottom() { console.log("onReachBottom"); this.setData({ listCount: this.data.listCount + 30 }) } })
|
1 2 3 4 5
| <view class="list"> <block wx:for="{{listCount}}" wx:key="*this"> <view>列表数据:{{ item }}</view> </block> </view>
|



小程序进入场景(场景值)
场景值用来描述用户进入小程序的路径。通俗地说,就是你从哪找到这个小程序的,小程序可以获取到这个值,针对不同的业务场景(场景值),进行相应的处理,以实现更为细致的业务逻辑。相关操作在项目根目录下的app.js
中进行,使用onLaunch、onShow
函数或者wx.getLaunchOptionSync
获取。
个人感觉就像是两个不认识的人——用户A、小程序C,他们都认识小程序B,有一天用户A收到小程序B的推荐认识了小程序C,小程序C为了和用户A相处的更加自然,从小程序B处获取用户A的相关信息。
全局共享数据
通过配置根目录的app.js
设置全局的数据globalData
,在页面中使用getApp()
获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Page({ data: { userInfo: {} },
onLoad() { const app = getApp()
const token = app.globalData.token const userInfo = app.globalData.userInfo console.log(token, userInfo);
this.setData({ userInfo }) console.log(this.data.userInfo); } })
|
登录基本逻辑(app.js)
App
框架接口示例代码,由于登录过程比较复杂,这里只做简单说明。
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
| App({ globalData: { token: "", userInfo: {} }, onLaunch (options) { const token = wx.getStorageSync("token") const userInfo = wx.getStorageSync("userInfo")
if (!token || !userInfo) { console.log("登录操作"); wx.setStorageSync("token", "kobetoken") wx.setStorageSync("userInfo", { nickname: "kobe", level: 100 }) }
this.globalData.token = token this.globalData.userInfo = userInfo
}, onShow (options) { }, onHide () { }, onError (msg) { console.log(msg) } })
|
按钮跳转处理逻辑
在首页使用wx:for="{{pages}}"
的方式将各个子页面的跳转以按钮的形式呈现出来,方便查看各知识点。
data-xx
的使用,后续的传参必须是存在的、可使用的值,xx
是个人自定义的名字。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <view class="pages"> <block wx:for="{{pages}}" wx:key="name"> <button type="primary" bindtap="onBtnClick" data-item="{{item}}" > {{ item.name }} </button> </block> </view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Page({ data: { pages: [ { name: "01_初体验", path: "/pages/01test/index" }, { name: "02_页面配置", path: "pages/02_页面配置/index" } ] }, onBtnClick(event) { const item = event.target.dataset.item
wx.navigateTo({ url: item.path, }) } })
|
path
中不能使用中文,不能使用中文,不能使用中文!以/
开头指明路径从根目录开始!

注册加载页面(page)
不要把开发工具固定在任务栏,会造成启动调试器不成功
单个页面(page)的js
文件用于发送网络请求、获取数据、同时定义本地固定的数据、绑定页面产生事件的回调函数和刷新滚动操作。onLoad
函数在页面加载时发送请求。
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| Page({ data: { banners: [], recommends: [],
counter: 100,
btns: ["red", "blue", "green", "orange"] }, onLoad() { console.log("onLoad");
wx.request({ url: "", success: (res) => { const data = res.data.data const banners = data.banner.list const recommends = data.recommend.list this.setData({ banners, recommends }) } }) },
onBtn1Click() { console.log("onBtn1Click"); }, onBtnClick(event) { console.log("btn click:", event.target.dataset.color); },
onPullDownRefresh() { console.log("onPullDownRefresh"); }, onReachBottom() { console.log("onReachBottom"); }, onPageScroll(event) { console.log("onPageScroll:", event); },
onShow() { console.log("onShow"); }, onReady() { console.log("onReady"); }, onHide() { console.log("onHide"); }, onUnload() { console.log("onUnload"); } })
|

1 2 3 4 5 6 7 8 9 10
| <view class="banner"> <swiper circular autoplay indicator-dots="{{true}}"> <block wx:for="{{banners}}" wx:key="acm"> <swiper-item> <image mode="widthFix" src="{{item.image}}"></image> </swiper-item> </block> </swiper> </view>
|
常用组件
text
文本组件。其中的user-select
参数控制文本是否可选;decode
参数控制是否解码,如表示空格的 
、&ensp
、&emsp
;selectable
参数控制可选的方案现已废弃。
1 2 3 4
| <text>Hello World</text> <text user-select>{{ message }}</text> <text user-select="{{true}}">{{ message }}</text> <text decode>></text>
|

与element
组件类似,提供了各种参数控制按钮的样式和功能。其中type
参数控制按钮的样式,size
参数控制按钮的大小,在开发过程中会经常性地使用open-type
参数,满足信息获取的需求。这里需要掌握getUserInfo
的处理方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo" size="mini" type="primary" > 用户信息1 </button>
<button size="mini" type="primary" bindtap="getUserInfo">用户信息2</button>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Page({ data: {}, getUserInfo(event) { wx.getUserProfile({ desc: 'desc', }).then(res => { console.log(res); }) }, })
|
wx.getUserInfo
接口已被回收,换成wx.getUserProfile
获取用户个人信息。


view
较为简单,同样可以绑定点击事件。
1
| <view bindtap="onViewClick" hover-class="active">我是view组件</view>
|
1 2 3 4 5 6 7
| Page({ ..., onViewClick() { console.log("onViewClick"); }, ... })
|
image
mode
作为参数控制,图片裁剪、缩放的模式。常用的有:scaleToFill
无脑拉伸图片使其铺满元素;aspectFit
保持纵横比例缩放图片,较为完整;widthFix
宽度不变,高度按原图宽高比自动变化,推荐。
1 2 3
| <image src="https://vip2.loli.io/2023/01/25/AxZqRfM1h4TjG2B.png" mode="aspectFit"/> <image src="https://vip2.loli.io/2023/01/25/AxZqRfM1h4TjG2B.png" mode="widthFix"/> <image src="https://vip2.loli.io/2023/01/25/AxZqRfM1h4TjG2B.png" mode="heightFix"/>
|
图片可以和按钮结合,将用户本地的图片展示出来
1 2
| <button bindtap="onChooseImage">选择图片</button> <image class="img" src="{{chooseImageUrl}}" mode="widthFix"/>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Page({ data: { chooseImageUrl: "", }, ..., onChooseImage() { wx.chooseMedia({ mediaType: "image" }).then(res => { const imagePath = res.tempFiles[0].tempFilePath this.setData({ chooseImageUrl: imagePath }) }) }, ... })
|
视图容器,规定某个固定高度或宽度的盒子,是通过左右滑动的方式查看内容还是通过上下滑动的方式查看内容。需要注意在对应的wxss
文件规定flex
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
| <scroll-view class="container" scroll-y> <block wx:for="{{viewColors}}" wx:key="*this"> <view class="item" style="background: {{item}};">{{item}}</view> </block> </scroll-view>
<scroll-view class="container scroll-x" scroll-x enable-flex > <block wx:for="{{viewColors}}" wx:key="*this"> <view class="item" style="background: {{item}};">{{item}}</view> </block> </scroll-view>
<scroll-view class="container scroll-x" scroll-x enable-flex bindscrolltoupper="onScrollToUpper" bindscrolltolower="onScrollToLower" bindscroll="onScroll" > <block wx:for="{{viewColors}}" wx:key="*this"> <view class="item" style="background: {{item}};">{{item}}</view> </block> </scroll-view>
|


注意和vue的v-bind
双向绑定的区别。
1
| <input type="text" model:value="{{message}}"/>
|
1 2 3 4 5 6
| Page({ data: { message: "Hello, World" } })
|

页面样式
微信小程序的界面样式写法有三种:行内样式、页面样式、全局样式。优先级依次是 行内样式 > 页面样式 > 全局样式。这些都和css
类似,不再赘述。

1 2 3 4 5 6 7 8 9
|
<view class="title">learn wxss title</view>
<view class="message">learn wxss message</view>
<view style="color: blue;">inline style</view>
|
1 2 3 4 5 6 7 8 9 10 11
| .message { color: green; }
.title { font-size: 30px; font-weight: 700; color: red; }
|
需要注意的是小程序的页面尺寸单位rpx
(区别于css
的rem
)。为了页面根据屏幕宽度进行自适应,规定屏幕宽为 750rpx,如在 iPhone6 上,屏幕宽度为 375 px,共有750个物理像素,则 750 rpx = 375 px = 750 物理像素,1rpx = 0.5px = 1物理像素。
