注册微信小程序获取APPID 创建项目时选用APPID

目录认识

小程序文件结构与传统web对比
| 传统web | 微信小程序 |
|---|
| HTML | WXML |
| CSS | WXSS |
| Javascript | Javascript |
| 配置:无 | JSON |
新建文件夹
app.json下 pages输入文件名会自动创建

app.json认识

TabBar底部导航
字段解释
pagePath:跳转的路径 text:名字 描述 iconpath:未选中时的图标路径 selectedIconPath:选中时的图标路径
|
app.json list最少2个
"tabBar": { "list": [{ "pagePath": "pages/index/index", "text": "首页", "iconPath": "icon/_home.webp", "selectedIconPath": "icon/home.webp" },{ "pagePath": "pages/demo1/demo1", "text": "图片", "iconPath": "icon/_img.webp", "selectedIconPath": "icon/img.webp" },{ "pagePath": "pages/video/video", "text": "视频", "iconPath": "icon/_videocamera.webp", "selectedIconPath": "icon/videocamera.webp" },{ "pagePath": "pages/logs/logs", "text": "日志", "iconPath": "icon/_search.webp", "selectedIconPath": "icon/search.webp" } ] },
|

view组件
容器 div = view 具有块级元素特点
<view style="width: 100%;height: 200px;background-color: antiquewhite;"> <text class="d1">数据包</text> <image style="width: 750rpx;" src="/images/11.webp" /> </view>
|
text组件
文本 span = text 具有行级元素特点
<text class="d1">数据包</text>
|
图片引入
图片 img = image 具有行内块级元素特点
image不设置宽高时,有默认宽高 image可以只写组件头,不写组件尾(单标签形式)。应在组件头用"/"关闭。
背景图片在行内样式时可以加载本地图片,写到wxss中只能加载网络图片
<image style="width: 750rpx;" src="/images/11.webp" />
|
rpx自适应
750rpx就是全屏
可以在组件头中写行内样式,也可在wxss中写样式(自动引入)
rpx: 自适应屏幕宽度尺寸。规定屏幕宽为750份,每份为1rpx。
在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,1rpx = 0.5px = 1物理像素
flex布局
- 任何容器都可以指定为Flex布局,任何子组件都可以设置宽高
- 父组件
设置成弹性盒子:display: flex; 指定主轴方向:flex-direction: column; 指定是否换行:flex-wrap:wrap; 指定在主轴对齐方式:justify-content:space-between|space-around; 指定在交叉轴对齐方式:align-items:center;
|
子组件
flex:定义了项目的缩放比例
修改每个界面的顶部名字
"navigationBarTitleText": "列表"
|

自定义头部
"navigationStyle": "custom"
|

数据绑定
<view>{{message}}</view>
<text>{{age}}</text>
<text>{{student.stname}}</text>
<text>{{isture}}</text>
|
数据
data: { message:'你好', age:10, student:{ id:10, stname:'李四', address:'湖南湘潭', height:'180cm' }, isture:true, }
|
运算
<view hidden="{{age==11 ? true:false}}">你可以看见嘛</view> <view>{{a+b+c}}</view> <view>{{'helo'+5}}</view> <view>{{8%5==0 ? '偶数':'奇数'}}</view>
|
for循环
<view> <text wx:for="{{number}}" wx:key="*this">{{index}}:{{item}}</text> </view>
<view> <text wx:for="{{number}}" wx:key="*this" wx:for-item="obj" wx:for-index="i">{{i}}:{{obj}}</text> </view>
<view> <view wx:for="{{grop}}" wx:key="*this" wx:for-item="obj" wx:for-index="i"> <view wx:for="{{obj}}" wx:key="*this" wx:for-item="enum">{{enum}}</view> </view> </view>
<view wx:for="{{student}}" wx:key="id"> {{item}}--{{index}} </view>
<view wx:for="{{cf}}" wx:key="*this"> {{item.id}}--{{item.name}} </view>
|
数据
data: { message:'你好', age:10, student:{ id:10, stname:'李四', address:'湖南湘潭', height:'180cm' }, isture:true, a:1, b:2, c:3, number:[1,2,34,34,45,55,76,6887], grop:[ [1,24,5,6,78,98], [1,2,3,4,5,6,7] ], cf:[ {id:10,name:'李四'}, {id:11,name:'李四2'}, {id:12,name:'李四3'} ] }
|
多选框是否勾选
<checkbox checked="{{ture}}"></checkbox>
|
隐藏显示
//hidden true/false <view hidden="{{age==11 ? true:false}}">你可以看见嘛</view>
|
block
<block wx:for="{{number}}" wx:key="*this"> {{item}} </block>
|
条件判断
<text wx:if="{{week==1}}">星期一学Java</text> <text wx:elif="{{week==2}}">星期二学MK</text> <text wx:elif="{{week==3}}">星期三学前端</text> <text wx:elif="{{week==4}}">星期四学MK</text> //else <text wx:else>看剧</text>
|
事件绑定
点击事件
<button bindtap="dj">点击事件</button>
|
文本框输入事件
<input bindinput="sr" placeholder="测试输入"/>
|
文本框改变事件
取值传值
点击按钮时取值
<!-- 绑定事件 带参数 传值data-自定义名字 --> <button bindtap="dj" data-number="5">点击事件</button>
dj:function(e){ console.log(e); console.log('点击成功'); console.log(e.currentTarget.dataset.number); }
dj(){ }
|
取出文本框输入的值
<!-- 输入了内容就会调bindinput 输入后触发 --> <input bindinput="sr" placeholder="测试输入"/>
sr(e){ console.log('输入框'); console.log(e); console.log(e.detail.value); this.setData({info:e.detail.value}) console.log(this.data.info); },
|
给data定义的属性赋值
jsjg(e){ console.log(this.data.js); console.log(this.data.js2); let res=parseInt(this.data.js)+parseInt(this.data.js2); console.log(res); this.setData({he:res}); }
|
获取data中的属性值
this.data.info
this.data.属性名
|
获取全局APP实例
app.js下定义的全局数据

获取全局值 任意界面
const app=getApp(); console.log(app.globalData.url);
|
下拉刷新
app.json
"enablePullDownRefresh": true 开启 "backgroundTextStyle":"dark", "backgroundColor": "#efefef" 背景颜色
|

设置头部的颜色
"navigationBarBackgroundColor": "#f2a0a1",
|

授权获取用户信息
点击事件获取
//getUserProfile是方法名 <button bindtap="getUserProfile">授权用户</button>
|
js
wx.getUserProfile({ desc: '展示用户信息', success: (res) => { console.log(res) this.setData({ userInfo: res.userInfo }) } })
|

缓存的使用
设置缓存
wx.setStorageSync('test', app.globalData.url);
|
得到缓存
let hu=wx.getStorageSync('test'); console.log(hu);
|
删除一个缓存
wx.removeStorage({ key: 'test', });
|
删除全部缓存
JS中跳转到某个界面
普通界面
url里面写路径 wx.navigateTo({ url: '/pages/detail/detail', })
|
tabbar界面
wx.switchTab({ url:'/pages/user/index', })
|
hover-class轻触
轻触样式 <view class="d1" hover-class="vietap"> hello view </view>
|
text 复制
<view> 无法复制 <text user-select="{{true}}" decode="{{true}}">可以复制</text> </view>
|
image
常用 mode=“widthFix”
<image style="display: block;" mode="top left" src="https://sls-study-cloud-1301165591.cos.ap-guangzhou.myqcloud.com/Blog/article/njde.webp" ></image>
|
swiper轮播图
<swiper indicator-color="#7700FF" indicator-active-color="#1AFF00FF" autoplay="{{true}}" indicator-dots="{{true}}" interval="1000" circular="{{true}}"> <swiper-item> <image mode="widthFix" src="https://sls-study-cloud-1301165591.cos.ap-guangzhou.myqcloud.com/music/img/1.webp"></image> </swiper-item> <swiper-item> <image mode="widthFix" src="https://sls-study-cloud-1301165591.cos.ap-guangzhou.myqcloud.com/music/img/10.webp"></image> </swiper-item> <swiper-item> <image mode="widthFix" src="https://sls-study-cloud-1301165591.cos.ap-guangzhou.myqcloud.com/music/img/11.webp"></image> </swiper-item> </swiper>
|
导航标签使用a标签
跳转后从储存取数据需要在onshow生命周期中使用
传值
<navigator url="/pages/goods_detail/index?goodsid={{item.goods_id}}"> </navigator>
跳到的页面JS接收
/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { //获取传过来的值商品ID console.log(options.goodsid); this.getgoodsinfo(options.goodsid); },
|
默认使用
<navigator url="/pages/day4/day4">视频navgator</navigator>
|
重定向模式
<navigator url="/pages/day4/day4" open-type="redirect">redirect</navigator>
|
跳到TabBar页面
<navigator url="/pages/video/video" open-type="switchTab">switchTab</navigator>
|
TabBar和普通都可以跳
<navigator url="/pages/day4/day4" open-type="reLaunch">reLaunch</navigator>
|
rich-text富文本标签
<rich-text nodes="<h1>你好</h1>"></rich-text>
|
icon标签
<icon type="success"></icon> <icon type="success_no_circle"></icon> <icon type="info"></icon> <icon type="warn"></icon> <icon type="waiting"></icon> <icon type="cancel"></icon> <icon type="download"></icon> <icon type="search"></icon> <icon type="clear"></icon>
|

size可以跳转大小 <button type="warn" bindtap="grcli">绿色</button> <button type="default" bindtap="recli">红色</button> <button type="primary" bindtap="whcli">白色</button>
|
加载框
wx.showLoading({ title: 'title', })
wx.hideLoading();
|

消息提示框
wx.showToast({ title: 'title', })
|

模态窗口
wx.showModal({ title: '提示', content: '这是一个模态弹窗', success (res) { if (res.confirm) { console.log('用户点击确定') } else if (res.cancel) { console.log('用户点击取消') } } })
|

导入样式
@import '../../style/common.wxss';
|
使用less
vscode安装插件

编辑配置

"less.compile": { "outExt": ".wxss" },
|
写less保存后直接变成wxss
分享
<button open-type="share">分享</button>
|
打开客服
<button open-type="contact">打开客服</button>
|
单选框
单选框 <radio-group bindchange="rachange"> <radio value="回家" checked="{{true}}">回家</radio><radio value="上学">上学</radio> <text>你选择的是:{{beh}}</text> </radio-group>
js
rachange(e){ this.setData({ beh:e.detail.value }) console.log(this.data.beh); },
|
多选框
<checkbox-group bindchange="getsg"> <checkbox wx:for="{{fruit}}" wx:key="*this" value="{{item}}">{{item}}</checkbox> <view>选中的水果:{{sg}}</view> </checkbox-group>
js getsg(e){ console.log(e); this.setData({ sg:e.detail.value }) }
|
组件
创建组件
创建components–>News–>新建Component

js文件夹分析
properties: {
},
data:{ },
methods: {
}
|
注册组件
在需要使用这个组件的页面的json文件中配置组件
如我在day5中使用
{ "usingComponents": { "Tabs": "/components/Tabs/Tabs" } }
|

使用组件
在改界面的wxml中使用 tabs是注册组件中的名字
组件父传子传值
界面 navlist是父组件的data里面的参数
day5.wxml
<Tabs nalis="{{navlist}}"></Tabs>
|
页面的js中data属性值
day5.js
navlist:[ { id:1, name:'首页', isselect:true },{ id:2, name:'列表', isselect:false },{ id:3, name:'我的', isselect:false } ]
|
组件中获取父组件传的值
Tabs.js
组件js中
properties: {
nalis:Array, nalis:{ type:Array, value:'' } },
|
获取properties的值
组件子传父
子组件
this.triggerEvent('idchange',{id});
|
父组件
//bindidchange是子组件的触发事件 <Tabs nalis="{{navlist}}" bindidchange="idchange"></Tabs>
|
组件插槽
子组件
<view class="tabs_context"> <slot></slot> </view>
|
父组件 组件标签中间放内容 插槽就会有内容
<Tabs nalis="{{navlist}}" bindidchange="idchange"> <block wx:if="{{navlist[0].isselect}}">首页</block> <block wx:if="{{navlist[1].isselect}}">列表</block> <block wx:if="{{navlist[2].isselect}}">我的</block> </Tabs>
|
生命周期
应用生命周期
app.js
onLaunch(初始化) onShow(刚加载) onHide(放到后台或者离开该界面) onError(出现错误的时候执行 错误级) onPageNotFound(页面没有找到)
|
页面的生命周期
xxx.js
onLoad(监听页面加载) onReady(监听页面初次渲染完成) onShow(监听页面显示) onHide(监听页面隐藏) onUnload(监听页面卸载) onPullDownRefresh(监听用户下拉动作) onReachBottom(页面上拉触底事件的处理函数) onShareAppMessage(用户点击右上角分享) onPageScroll(页面滚动触发) onResize(尺寸变换时触发) 注:屏幕旋转是
|
屏幕旋转
单个界面旋转 界面.json
"pageOrientation": "auto"
|
整个程序旋转 app.json
"pageOrientation": "auto"
|
发送请求
微信提供的
wx.request({ url:'https://service-qze5ckvg-1301165591.gz.apigw.tencentcs.com /release/test', success(res){ console.log(res.data); }, fail(err){ console.log(err); } })
|
promise封装请求
util.js
const request=(params)=>{ return new Promise((resolve,reject)=>{ wx.request({ ...params, success(res){ resolve(res.data); }, fail(err){ reject(err); } }) }); }
module.exports = { request }
|
使用中导入
import {request} from '../../utils/util'
|
使用
request({url:'https://autumnfish.cn/api/joke/list',data:{ num:10 }}).then((res)=>{ console.log(res); })
|
await使用
async asyqq() { let res = await request({ url: 'https://autumnfish.cn/api/joke/list', data: { num: 10 } }); console.log(res); }
|
请求时显示加载图标封装请求
let ajatime=0;
const request=(params)=>{ ajatime++; wx.showLoading({ title:'加载中...', mask:true }); return new Promise((resolve, reject)=>{ wx.request({ ...params, success(res){ resolve(res.data); }, fail(err){ reject(err); }, complete:()=>{ ajatime--; if(ajatime===0){ wx.hideLoading(); } } }) }) };
|
微信登入
微信登入官方提供 可以通过获取用户权限 和 登入的code去后台获取token
wx.login({ success(res){ console.log(res); } })
|
图片预览
console.log(this.stgoods.pics); let imgarr=this.stgoods.pics.map((v)=>v.pics_big_url); wx.previewImage({ current:e.currentTarget.dataset.pic, urls:imgarr })
|
返回上一个界面
wx.navigateBack({ delta: 1, })
|
上传图片到云存储
下载文件
https://github.com/tencentyun/cos-wx-sdk-v5/blob/master/demo/lib/cos-wx-sdk-v5.js
引入文件(下载的文件放在util文件夹下面 在util.js下引入文件)
var COS = require('cos-wx-sdk-v5.js');
|
封装方法
保存秘钥
var cos = new COS({ SecretId: 'xxxxxxxxxxxxxxxx', SecretKey: 'xxxxxxxxxx', });
|
上传方法
let Bucket='sls-study-cloud-1301165591'
let Region='ap-guangzhou'
const cosupimg=(filename,filePath)=>{ return new Promise((resolve,reject)=>{ cos.postObject({ Bucket: Bucket, Region: Region, Key: 'applet of WeChat/shop/' + filename, FilePath: filePath, }, function (err, data) { if(data!=null){ resolve(data); }else{ reject(err); } }); }) }
|
删除文件
const decosimg=(filename)=>{ return new Promise((resolve, reject)=>{ cos.deleteObject({ Bucket: Bucket, Region: Region, Key: 'applet of WeChat/shop/' + filename, }, function(err, data) { if(data!=null){ resolve(data); }else{ reject(err); } }); }); }
|
使用
图片示例

upimg(){ let that =this wx.chooseImage({ success(res){ that.setData({ imgarr:[...that.data.imgarr,...res.tempFilePaths] }) } }) },
prvimg(e){ wx.previewImage({ current:this.data.imgarr[e.detail.index], urls:this.data.imgarr }) },
handtext(e){ this.setData({ feebtext:e.detail.value }); }, async feebsubmit() { let chooseImage = this.data.imgarr; let feebtext = this.data.feebtext; if (!feebtext.trim()) { wx.showToast({ title: '反馈的内容不能为空!', icon: 'none', mask: true }); return; }; wx.showLoading({ title: '正在上传...', mask: true }); if (chooseImage.length != 0) { for (const item of chooseImage) { const i = chooseImage.indexOf(item); let filename = item.substr(item.lastIndexOf('/') + 1); let res = await cosupimg(filename, item); console.log(res); if(i===chooseImage.length-1 && res.statusCode===200){ wx.hideLoading(); wx.showToast({ title:'提交成功', icon:'success', mask:true }) this.setData({ imgarr:[], feebtext:'' }); setTimeout(()=>{ wx.navigateBack({ delta:1 }); },2000); setTimeout(()=>{ wx.navigateBack({ delta:1, mask:true }); },1100); } } }else{ wx.showToast({ title:'提交成功!', icon:'success', mask:true }); wx.navigateBack({ delta:1 }) } },
|
轮播图的高度计算
高度:750rpx * 图片高度/图片宽度
图片宽度为100% mode:widthfix
|

iphone底部安全区适配
调用wx.getSystemInfo,获得手机型号(res.model),并存储为全局变量
App({ onLaunch: function () { let _self = this; wx.getSystemInfo({ success: (res) => { let modelmes = res.model; if (modelmes.search("iPhone X") != -1) { _self.globalData.isIphoneX = true; } }, }); }, globalData: { userInfo: {}, }, });
|
在所需页面的js文件的onLoad函数内从全局变量里面拿出来第一步存储的手机型号值,这里设置为
isIphoneX:
const app = getApp();
Page({ onLoad: function(options){ let isIphoneX = app.globalData.isIphoneX; this.setData({ isIphoneX: isIphoneX }) } })
|
给页面添加一个最底部的盒子,或者给整个页面套一个最外层的盒子(底部间距为68rpx)
<view class="detail" style="height: {{isIphoneX ? 'calc(100% - 68rpx)' : '100%'}}"> ...内容 </view>
|
此处需要注意
App.wxss 的Page高度需要设置,同时detail页面的也需要设置溢出滚动,这样才能保证页面正常滚动
Page{ height: 100%; }
.detail{ overflow: scroll; }
|
小程序刷新当前页
网上很多刷新当前页的做法是
this.onLoad();
this.onShow();
|
如果只是为了清除数据刷新页面,恢复初始值的话,可以将data中的数据抽离,然后重新setData即可
let obj = {username: "xxx"}
Page({ data: JSON.parse(JSON.stringify(obj)), fn(){ this.setData(obj); } })
|