今天是一年一度的1024程序员节,祝大家节日快乐。前面半年我一直在研究Python和Linux相关技术,最近有需要写微信小程序的需求,为此花点时间学了下,很容易就上手了,大家不防一试。
一、day01微信小程序
1. 问题
-
什么是微信小程序
- 移动互联网时代,手机 - 手机软件,在手机中安装很多软件 - 腾讯和阿里(只安装自己不用别人) - 腾讯:微信 + N小程序 - 阿里:支付宝 + N小程序
-
为什么要做小程序?
微信用户基数大 在微信上用我们小程序比较便捷
-
如何开发小程序?
- 小程序:学习微信开发的语言(前段html、css、js、vue.js)
- 微信开发者工具
- API: restful接口(Python + flask + flask_restful)
- Pycharm
- 小程序:学习微信开发的语言(前段html、css、js、vue.js)
2. 环境的搭建
2.1 Python环境
- 虚拟环境
- flask
- flask_restful
- Pycharm
2.2 小程序环境
2.2.1 申请一个微信公众平台
2.2.2 保存自己的appid
appid:wxff2dd22b6fb5a253
2.2.3 下载开发者工具
2.2.4 创建项目
3. 开发小程序
3.1 全局配置
{
"pages": [
"pages/index/index",
"pages/logs/index"
],
"window": {
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "PDF转换器",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light",
"enablePullDownRefresh": false
},
"tabBar": {
"selectedColor": "#CD5C5C",
"list": [{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/tabbar/[email protected]",
"selectedIconPath": "static/tabbar/[email protected]"
}, {
"pagePath": "pages/logs/index",
"text": "日志",
"iconPath": "static/tabbar/[email protected]",
"selectedIconPath": "static/tabbar/[email protected]"
}]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true
}
3.2 组件
3.2.1 text
编写文本信息,类似于span
3.2.2 view
容器,类似于div标签
3.2.3 image
图片
3.3 样式
3.3.1
- px
- rpx,750rpx
4. flex布局
一种非常方便的布局方式。
在容器中记住4个样式即可。
display: flex; flex布局
flex-direction: column; 规定主轴水平方向:row/column
justify-content: space-around; 在主轴方向如何展示:flex-start/flex-end/center/space-around/space-between/space-evenly
align-items: flex-end; 在副轴方向如何展示: flex-start/center/space-around/space-between/space-evenly
5. 实战
二、day02微信小程序
内容回顾
- 环境搭建
- 全局配置
- pages
- window
- tabbar
- 页面
- json
- js
- wxml
- wxss
- flex布局
- display:flex
- flex-direction: row、column
- justify-content
- align-item
- 小程序开发
- 标签(组件)
- text
- view
- image
- 样式
- rpx 默认750rpx
- 标签(组件)
今日概要
- 指令
- api
- 页面
今日内容
1. 跳转
1.1 标签绑定点击事件
<view bindtap="clickMe" data-nid="123" data-name="harry">点我跳转</view>
Page({
/**
* 点击绑定的时间
*/
clickMe(e) {
var nid = e.currentTarget.dataset.nid
// String *harry = e.currentTarget.dataset.name
console.log(nid)
// 跳转
wx.navigateTo({
url: '/pages/redirect/redirect?id='+nid,
})
}
)}
1.2 页面跳转
// 跳转
wx.navigateTo({
url: '/pages/redirect/redirect?id='+nid,
})
跳转到的界面如果想要接收参数,可以在onload方法中接收
Page({
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log(options.id)
},
)}
注意事项:只能跳转到非tabbar的界面
1.3 通过标签跳转
<navigator url="/pages/redirect/redirect?id=666">跳转到新界面</navigator>
2. 数据绑定
2.1 基本显示
-
wxml
<view> 当前头像: <image src="{ {avatarUrl}}" style="height: 200rpx; width: 200rpx;"></image> </view> <view>当前用户名:{ {name}}</view> <view bindtap="getUserName">获取当前用户</view>
-
展示数据
/** * 页面的初始数据 */ data: { message: "你好呀,哈哈", name: "", avatarUrl: "/static/222.png" },
2.2 数据更新
changeData() {
// 获取数据
console.log(this.data.message)
// 修改数据 错误的方式,这样只能改后端
// this.data.message = "222"
// 修改数据
this.setData({
message: "嗨,你好呀"})
},
3. 获取用户信息
方式一
- wxml
<view bindtap="getUserName">获取当前用户</view>
- js
getUserName() {
var that = this
console.log('获取当前用户信息')
// 调用微信的接口, 获取用户信息
wx.getUserInfo({
success: function(res) {
// 调用成功后触发
var userInfo = res.userInfo
var nickName = userInfo.nickName
var avatarUrl = userInfo.avatarUrl
var gender = userInfo.gender //性别 0:未知、1:男、2:女
var province = userInfo.province
var city = userInfo.city
var country = userInfo.country
console.log('success', avatarUrl)
that.setData({
name: nickName,
avatarUrl: avatarUrl
})
},
fail:function(res){
// 调用失败后触发
console.log('fail', res)
}
})
},
方式二
- wxml
<button open-type="getUserInfo" bindgetuserinfo="fetchInfo">获取信息button</button>
- js
// pages/login/login.js
Page({
/**
* 页面的初始数据
*/
data: {
name: "",
avatarUrl: "/static/222.png"
},
fetchInfo:function() {
var that = this
console.log('获取当前用户信息')
// 调用微信的接口, 获取用户信息
wx.getUserInfo({
success: function(res) {
// 调用成功后触发
var userInfo = res.userInfo
var nickName = userInfo.nickName
var avatarUrl = userInfo.avatarUrl
var gender = userInfo.gender //性别 0:未知、1:男、2:女
var province = userInfo.province
var city = userInfo.city
var country = userInfo.country
console.log('success', avatarUrl)
that.setData({
name: nickName,
avatarUrl: avatarUrl
})
},
fail:function(res){
// 调用失败后触发
console.log('fail', res)
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
注意事项:
-
想要获取用户信息,必须经过用户授权(button)
-
已授权
-
不授权,通过调用wx.opensettings
// 打开配置,手动授权 wx.openSetting({})
4. 获取用户的位置信息
getLocalPath:function() {
var that = this
wx.chooseLocation({
success:function(res){
console.log(res)
that.setData({
localpath: res.address
})
}
})
},
app.json
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将被展示在小程序"
}
},
"requiredPrivateInfos": [
"getLocation"
]
5. for指令
<!--pages/goods/goods.wxml-->
<text>商品列表</text>
<view>----------------------------</view>
<view>
<view wx:for="{
{dataList}}">{
{index}}-{
{item}}</view>
<!-- index 和 item别名 -->
<!-- <view wx:for="{
{dataList}}" wx:for-index="idx" wx:for-item="itemName">{
{idx}}-{
{itemName}}</view> -->
</view>
<view>----------------------------</view>
<view>
{
{userInfo.name}}
{
{userInfo.age}}
</view>
<view>----------------------------</view>
<view>
<view wx:for="{
{userInfo}}">{
{index}}:{
{item}}</view>
</view>
js
/**
* 页面的初始数据
*/
data: {
dataList: ["小明", "harry", "小花"],
userInfo: {
name: "harry",
age: 18
}
},
6. 获取图片
-
wxml
<text bindtap="uploadImage">请上传图片</text> <view class="container"> <image wx:for="{ {imageList}}" src="{ {item}}"></image> </view>
-
js
uploadImage:function(){ var that = this wx.chooseImage({ count: 6, sizeType: ["original", "compressed"], sourceType: ["album","camera"], success: (res) => { console.log(res) // 默认图片 + 新选择图片 that.setData({ imageList: that.data.imageList.concat(res.tempFilePaths) }) }, fail: (res) => { console.log(res) }, complete: (res) => { console.log(res) }, }) },
注意:图片目前只是上传到内存。
总结
-
标签(组件)
- text
- view
- image
- navigator,跳转到其他页面(非tabbar页面)
- button
-
时间
-
bindtap
<view bindtap="func"></view> <view bindtap="func" data-xx="123"></view>
func:function(e){ e.currentTarget.dataset }
-
-
api
- navigateTo
wx.navigateTo({ url: '/pages/redirect/redirect?id='+nid, })
- openSetting
wx.openSetting()
- getUserInfo
wx.getUserInfo({ success: function(res) { } })
- chooseLocation
wx.chooseLocation({ success:function(res){ } })
- chooseImage
wx.chooseImage({ count: 6, sizeType: ["original", "compressed"], sourceType: ["album","camera"], success: (res) => { } })
-
数据绑定
-
for指令
注意:setData + that
作业
1.拍卖详细页面
-
拍卖列表页面通过for循环+后端数据展示信息
-
点击拍卖列表中的某项拍卖时,需要将自己的id传递给拍卖详细页面
2.发布消息的页面
- 上传图片
- 选择位置
<textarea></textarea>
三、day03微信小程序
今日概要
- 小程序
- 后端api
今日详情
1. 数据绑定
- 基本绑定
- for循环
双向绑定
2.用户登录
day04微信小程序
今日概要
- 用户登录、注册
- 发布心情
- 图片上传
- 查看心情
- 查看心情详情
今日详情
1. 用户登录
1.1 发送短信
1.2 登录
-
小程序公共对象
-
App.js
App({ /** * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () { var userInfo = wx.getStorageSync('userInfo') if (userInfo){ this.globalData.userInfo = userInfo } }, globalData:{ userInfo: null }, initUserInfo:function(res, localUser){ console.log(localUser.nickName) var info = { token: res.token, phone: res.phone, nickName: localUser.nickName, avatarUrl: localUser.avatarUrl } console.log(info) // 获取公共app, 赋值, 全局变量赋值 this.globalData.userInfo = info // {phone:xxx, token:xxx} // 在本地存储值 wx.setStorageSync('userInfo', info) }, delUserInfo:function(){ this.globalData.userInfo = null wx.removeStorageSync('userInfo') } })
- 其他页面
var app = getApp() Page({ /** * 页面的初始数据 */ data: { userInfo:null }, /** * 生命周期函数--监听页面显示(每次都执行) */ onShow() { this.setData({ userInfo: app.globalData.userInfo }) }, /** * 用户注销 */ onClickLogout:function(){ app.globalData.userInfo = null wx.removeStorageSync('userInfo') this.setData({ userInfo:null }) } })
注意:修改globalData之后, 其他页面已用的值不会自动变化,而是需要手动设置。
-
-
本地存储
wx.getStorageSync('userInfo') wx.setStorageSync('userInfo', info) wx.removeStorageSync('userInfo')
-
页面调用栈
var pages = getCurrentPages() prevPage = pages[pages.length-2]
-
跳回上一个页面
wx.navigateBack({ })
-
小程序页面的生命周期
- onLoad(一次)
- onShow(只要展示这个界面,就会自动加载)
- onReady(一次)
- onUnload(卸载, 小程序关闭时)
- onHide(当小程序从前台进入后台,会触发 onHide, A界面跳转到B界面, A执行onHide)
- onShow(当小程序启动,或从后台进入前台显示,会触发 onShow)
- onError(当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息)
- onPullDownRefresh(下拉刷新)
- onReachBottom(上拉加载)
- onShareAppMessage(用户点击右上角分享)
-
全局app.js
App({ /** * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () { var userInfo = wx.getStorageSync('userInfo') if (userInfo){ this.globalData.userInfo = userInfo } }, globalData:{ userInfo: null } })
-
wx:if指令
day05功能卡法
今日概要
- 页面传值
- 临时秘钥上传文件
今日详细
1. 页面传值
1.1 父页面向子页面传值
父页面:
/pages/xx/xxx?id=1
子页面:
onLoad:function(){
}
1.2 子页面向父页面传值
子页面:
/**
* 选择话题事件
*/
chooseTopic:function(e){
var topicInfo = e.currentTarget.dataset.xx
var pages = getCurrentPages()
var prevPage = pages[pages.length-2]
// prevPage.setData({ topicText: topicInfo.title })
prevPage.setTopicData(topicInfo)
// 把这个值传给父界面
wx.navigateBack({
})
},
注意:data-xx可以给事件传值
作业:
1.发布状态
1.打开图片进行本地预览
2.将本地图片上传到云
3.输入文字 & 选择相应信息
4.发布:
必须上传完毕之后, 才允许点击发布按钮
1.1组件:进度条
<progress percent="{
{precent1}}" ></progress>
<progress percent="{
{precent2}}" activeColor="#DC143C"></progress>
1.2 修改data中的局部数据
/**
* 页面的初始数据
*/
data: {
imageList:[
{
id:1, title:'pic1', precent: 20 },
{
id:2, title:'pic2', precent: 40 },
{
id:3, title:'pic3', precent: 60 }
],
precent1:20,
precent2:50
},
/**
* 修改百分比
*/
changePercent:function(){
var num = 2
this.setData({
["imageList[0].precent"]:80,
["imageList[" + num + "].precent"]:90,
["imageList[3].title"]:"哈哈哈"
})
},
<view wx:for="{
{imageList}}">
<view>{
{item.title}}</view>
<progress percent="{
{item.precent}}" ></progress>
</view>
<button bindtap="changePercent">更新</button>
1.3 闭包
/**
* 闭包
*/
bibaoAction:function(){
// 闭包1
var dataList = [11, 2, 45]
for (var i in dataList) {
function v1(data){
wx.request({
url: 'xx',
success:function(res){
console.log(i)
}
})
}
v1(dataList[i])
}
// 闭包2
for (var i in dataList) {
(function(data){
wx.request({
url: 'xx',
success:function(res){
console.log(i)
}
})
})(dataList[i])
}
},
2.列表查看
全局配置下拉刷新, app.json
"window": {
"enablePullDownRefresh": True
},
局部下拉刷新, xxx.json
{
"usingComponents": {
},
"enablePullDownRefresh": true
}
2.1 瀑布流
-
方式1:自己构造
<view style="width:50%"> </view> <view style="width:50%"> </view>
-
方式2:设置样式css
<!--pages/news2/news2.wxml--> <view class="container"> <view class="item"> <image mode="widthFix" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2F%2Fpic%2F5%2F8d%2F5f31a37412.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664420148&t=2d54b8c73bb16e55720d4219ac4013d8"></image> </view> <view class="item"> <image mode="widthFix" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp6.itc.cn%2Fimages01%2F20200731%2Feafbff9ae5e94f939ab41097518a23c1.jpeg&refer=http%3A%2F%2Fp6.itc.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664420148&t=878daea64d40ea5f0dd900121dd635ae"></image> </view> </view>
/* pages/news2/news2.wxss */ .container{ -moz-column-count: 2; /* 分为两列 */ -webkit-column-count: 2; column-count: 2; -moz-column-gap: 20rpx; -webkit-column-gap: 20rpx; columns-gap: 20rpx } .container .item{ break-inside: avoid-column; -webkit-column-break-inside: avoid; } .container .item .image{ width: 100%; display: block; }