小程序
优势
- 用户粘性高
- 开发成本低
- 适配成本低
- 容易小规模试错,快速迭代(不需要用户特意升级)
结构层
- wxml
- wxss
- js
- json
项目初始化
- 删除logs文件夹
- 保留
Pages文件夹中的index.js的page({}) - 保留
Pages文件夹中的index.json的{} - 保留
app.json的page字段 - wxss样式删除
- wxml结构全删除
插件
- prettier
全局app.json
{
// 入口页面
"entryPagePath": "pages/index/index",
// 设置页面
"pages": ["pages/test/index", "pages/index/index"],
// 导航栏配置
"window": {
"navigationBarBackgroundColor": "#ff0",
"navigationBarTitleText": "Not friendly",
"navigationBarTextStyle": "black",
"enablePullDownRefresh": true
}
}
page.json
-
可以对单独页面进行独立配置
{ "navigationBarBackgroundColor": "#f40", "backgroundColor": "#ff0", "enablePullDownRefresh": true }
绑定属性
- 小程序开发不需要写
:绑定
// index.js
Page({
data: {
msg: "这是文字",
isLoading: true,
id:9
},
});
<!-- index.wxml -->
<!-- 正确写法 -->
<view id="{{id}}">{{msg}}</view>
<!-- 拼接写法 -->
<view id="item-{{id}}">{{msg}}</view>
<!-- 错误写法 -->
<view :id="item-{{id}}">{{msg}}</view>
显示隐藏
-
wx:if
-
hidden
-
与vue语法有所不同
-
hidden与v-show稍有区别,条件为真是不会显示的
<!-- 标签隐藏与显示 --> <view wx:if="{{isShow}}">wx:if显示隐藏</view> <view hidden="{{hidden}}">hidden显示隐藏</view>Page({ data: { isShow: true, hidden: false, }, });
判断语句
- wx:if
- wx:elif
- wx:else
Page({
data: {
day: 5,
},
});
<!-- 判断语句 -->
<view wx:if="{{day===1}}">星期一</view>
<view wx:elif="{{day===2}}">星期二</view>
<view wx:elif="{{day===3}}">星期三</view>
<view wx:else>星期四</view>
遍历
-
wx:for一定要配合插值使用(形参默认是item和index) -
wx:for-item,wx:for-index这两个语法可以更改形参名字,便于在嵌套for时区分内容 -
插值表达式前后要注意检查,不要加上空格或者其他字符,否则会被拼接成遍历字符串
<!-- for循环 --> <view wx:for="{{list}}">{{item}}--{{index}}</view> <!-- 更改形参名字 --> <view wx:for="{{objList}}" wx:for-item="value" wx:for-index="i">{{value.name}}--{{value.id}}</view> <!-- 嵌套场景 --> <view wx:for="{{objList}}" wx:for-item="value" wx:for-index="i"> <view wx:for="{{list}}">{{item}}--{{value.name}}</view> </view>Page({ data: { list: ["深圳", "广州", "潮汕"], objList: [ { id: 1, name: "小明" }, { id: 2, name: "莎拉" }, { id: 3, name: "小夫" }, ], }, }); -
index默认是键值对中的键,item是值<!-- item--值,index--键 --> <view wx:for="{{person}}">{{item}}--{{index}}</view>Page({ data: { person: { age: 12, name: "孙悟空", skill: "fly", }, }, });
添加key,优化就地更新策略
wx:key="值唯一的键名"- 作用:与vue一样,提高更新效率
<!-- 加key, 解决就地更新策略 -->
<!-- 纯数组 -->
<view wx:for="{{list}}" wx:key="*this">{{item}}</view>
<!-- 对象数组 -->
<view wx:for="{{objList}}" wx:key="id">{{item.name}}</view>
<!-- 纯对象 -->
<view wx:for="{{person}}" wx:key="*this">{{item}}</view>
事件
-
小程序没有@绑定事件语法
-
取而代之的是bind+时间名
- 例如bindTap, 点击事件
-
小程序也没有alert, document方法
-
方法定义在page里,不是methods里
<view bindtap="tapFn">点我</view>Page({ tapFn() { console.log("点击了我"); }, });
事件传递参数
-
利用自定义属性
data-xxx="xx" -
获取的时候,写
e.target.dataset.xxx<view bindtap="handleFn" data-name="100">test02</view>Page({ handleFn(e) { console.log(e.target.dataset.name); }, }); -
data-xxx="{{xx}}" -
输出的值是number
<view bindtap="handleFn" data-name="{{100}}">点我</view>
获取数据
-
语法:
this.data.xxx<view>{{msg}}</view> <view bindtap="changeFn">点我改变上面</view>data: { msg: "hello world", }, changeFn() { console.log(this.data.msg); },
更改数据
-
语法:
this.setData({xxx:xx})data: { msg: "hello world", }, changeFn() { console.log(this.data.msg); }, -
更改数组的方法(工作常用解构)
- 可以随意更改新数据在数组中的位置
pushFn() { // this.data.list.push("新水果"); const {list} = this.data. const newList = ["老板娘", ...this.data.list]; this.setData({ list: newList }); },
双向绑定model:value
model:value写在行内- 使用时需要加上空的bindinput事件才不会报错
样式
- 大部分样式可以使用
- 不支持通配符*, 可通过并集选择器
- 单位(vw, rpx)
- 一般不适用
rem - 100能除尽尽量用
vw - 除不尽100的大小,可以用
rpx
- 一般不适用
rpx- 微信小程序把屏幕分成750份
组件
view
view是一个块级元素- 可以代替
div来使用
- 可以代替
text
text标签只能套文本内容- 行内可以加上
user-select, 表示用户可以拖动文本
- 行内可以加上
图片
image- 是一个固定尺寸的容器
- 默认图片铺满整个容器
- 需要设置模式mode使图片不拉伸
- 有四个属性
- 默认
scaleToFill- 宽高拉满
- 场景:缩略图
aspectFit- 等比例缩放,可能会留白
- 查看详细图片
widthFix- 宽度固定,高度自适应
heightFix- 高度固定,宽度自适应
- 默认
轮播图
swiper轮播图- 嵌套
swiper-item - autoplay——自动播放
- interval——轮播时长
- indicator-dots——滚动小点
- circular——无缝衔接
- 嵌套
navigator
navigator跳转组件url属性——可以写需要跳转的页面open-type属性- switchTab
- 作用:可以允许跳转到tab页面
- 特点:清除掉历史记录,没有回退按钮
- redirect
- 作用: 不产生一条跳转的历史记录
- 注意:如不需要产生历史记录, 该页面中navigator使用redirect
- navigatorBack
- 作用:回退一步
- 特点:不需要写url,无效
- 场景:通常配置自定义导航栏、自定返回按钮
- reLaunch
- 作用:会清除掉所有的历史记录,重新打开某个页面
- 注意:不常用, 小程序希望尽量缓存页面
- switchTab
按钮
buttonopen-type属性- share 分享
- feedback 反馈
- contact 联系客服
获取用户地理位置
-
创建按钮
<button open-type="openSetting">打开设置</button> -
全局js
/** * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () { wx.getLocation({ success: (result) => { console.log(result); }, fail: (res) => { console.log(res); }, complete: (res) => {}, }); }, -
全局json
"permission": { "scope.userLocation": { "desc": "请求您的地理位置" } }
获取用户手机号码
-
注意:需要企业认证才可获取到用户手机号码,否则undefined
-
结构
<button open-type="getPhoneNumber" bindgetphonenumber="getPhone">获取用户手机号</button> -
js文件自定义函数
// 自定义函数 getPhone(e) { console.log("获取手机号---->", e.detail.code); },
富文本rich-text
-
标签
rich-text -
作用:后台返回html字符串时,可以用富文本
-
结构
<rich-text nodes="{{strHtml}}"></rich-text> -
data对象声明变量
data: { strHtml: "<h1 style='background-color: lime;'>hello</h1>", },
自定义组件
-
注意
- 相关文件应该放在独立组件文件夹中,否则样式会失效
- 大小写敏感(注册时,组件名大写开头)
- 不使用则不注册,否则报错
-
步骤
-
创建组件
- 根目录创建
components/xxx文件夹 - 右键
xxx文件夹,点击新建Component - 输入文件名,完成创建
- 根目录创建
-
在需要使用组件的页面json文件注册组件
"usingComponents": { "MyButton": "/components/myButton/myButton" } -
使用组件
<MyButton></MyButton>
组件通信
父传子
-
传数据——父组件中,通过组件的标签属性传值
-
接收数据——子组件,通过properties接收
-
步骤
-
父组件通过属性传值
<MyButton title="父传子"></MyButton> -
子组件通过properties接收父组件传过来的数据
properties: { title: { type: String, value: "默认值", }, },
-
子传父
-
步骤
-
子组件绑定事件
<button bindtap="btnToFa">{{title}}</button> -
触发子组件事件
methods: { btnToFa(){ // 传值 this.triggerEvent('btnToFa','hello') } }, -
父组件定义接收数据的方法
<MyButton title="父传子" bindbtnToFa="btnToFa"></MyButton> -
父组件通过绑定自定义事件
<MyButton title="父传子" bindbtnToFa="btnToFa"></MyButton>
-
-
生命周期
- 一堆会在特定时期触发的函数
- 触发时机
- 场景作用
应用生命周期
onlaunch
-
触发时机:初始化小程序时,全局只触发一次
-
使用场景:初始化数据,获取用户位置信息,获取用户信息
/** * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function () { },
onShow
-
触发时机:从后台切换到前台时或者第一次启动时
-
使用场景:常用来获取统计数据,例如时长,时段
-
注意:进入后台进程后,大概5分钟,会自动关掉
/** * 当小程序启动,或从后台进入前台显示,会触发 onShow */ onShow: function (options) { console.log("我切换回前台了"); },
onHide
-
触发时机:从前台切换到后台时或者第一次启动时
-
使用场景:常用来获取一些统计数据
/** * 当小程序从前台进入后台,会触发 onHide */ onHide: function () { console.log("我切换回后台了"); },
onError
-
触发时机:出现错误时
-
使用场景:配合后台接口,上报错误(埋点)
/** * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 */ onError: function (msg) { console.log(msg); },
onThemeChange
-
触发时机:小程序切换日间 || 夜间模式
-
使用场景:自动换色(跟随系统)
/** * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 */ onError: function (msg) { console.log(msg); },
页面生命周期
onLoad
-
触发时机:创建后自动执行
-
使用场景:获取数据、存数据到变量
/** * 生命周期函数--监听页面加载 */ onLoad(options) { wx.request({ url: "https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata", success: (res) => { this.setData({ list: res.data.message }); }, }); },
onShow, onHide
-
触发时机:后台-前台,前台-后台 || 进入页面-离开页面
-
使用场景:获取数据、存数据到变量
/** * 生命周期函数--监听页面显示 */ onShow() {}, /** * 生命周期函数--监听页面隐藏 */ onHide() {},
onReady
-
对应vue的mounted
-
触发时机:渲染完成
-
使用场景:
- 最先获取元素
- 开启定时器
/** * 生命周期函数--监听页面初次渲染完成 * mounted */ onReady() { console.log("页面初次渲染完成"); },
onUnload
-
对应vue的destroyed
-
触发时机:渲染完成
-
使用场景:
- 清除定时器
- 清除缓存
- navigator除了默认的跳转方式,不会写在页面。尽量缓存组件页面
- 非默认跳转,都会卸载页面
/** * 生命周期函数--监听页面卸载 */ onUnload() { console.log("页面卸载啦"); },
onPullDownRefresh
-
触发时机:下拉
-
使用场景:下拉刷新
/** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() {},
onReachBottom
-
触发时机:滚动到底部的时候
-
使用场景:上拉请求下一页数据
/** * 页面上拉触底事件的处理函数 */ onReachBottom() {},
onShareAppMessage
-
触发时机:用户点击右上角分享
-
使用场景:分享赠送福利
onShareAppMessage() {},
onShareTimeline
-
触发时机:用户点击右上角转发朋友圈
-
使用场景:转发朋友圈送福利
onShareTimeline() {},
onAddToFavorites
-
触发时机:右上角收藏
-
使用场景:收藏送福利
onPageScroll() {},
onPageScroll
-
触发时机:页面滚动触发事件的处理函数
-
使用场景:吸顶效果
onPageScroll() {},
onResize
-
触发时机:页面尺寸改变时触发
-
使用场景:用户设备横屏时
onResize() {},
组件生命周期
attached
-
对应created
-
触发时机:挂载后
-
使用场景:发请求,开定时器
lifetimes: { /** * 对应created * 触发时机:挂载后 * 场景:发请求,开定时器 */ attached() {}, },
detached
-
对应destroyed
-
触发时机:卸载时
-
使用场景:清除动作
lifetimes: { /** * 对应destroyed * 触发时机:卸载时 * 场景:清除动作 */ detached() {}, },