本文主要是介绍2023.8.21--微信小程序uni-app,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
微信小程序
day1
微信小程序开发
下载微信开发者工具
注册小程序账号
-
注册小程序账号
-
填写信息
-
获取小程序的 AppID
搭建开发环境
认识小程序
小程序的页面布局
- 小程序组件(标签)
- view 定义块级区块⇒ 相当于 html 中的 div 标签
- text 定义行内区块⇒ 相当于html中的 span 标签
- 样式选择器
- 类选择器
- 标签选择器
- 后代选择器
- 组成页面的4种文件类型
.wxml
页面结构和内容.wxss
页面样式.js
逻辑处理.json
配置文件
小程序的基本逻辑处理
- 注册页面:
Page函数
- 数据处理:
data
选项 , 初始化页面数据this.setData
方法 , 更新页面数据
- 事件处理:
bind:事件名称=事件回调
小程序的页面路径的配置
- app.json 全局配置
- pages 页面路径列表
- 小程序组件
- navigator 跳转页面(相当于 html 中的 a 标签)
- 如何配置小程序的页面路径?
- app.json文件
- 在Pages下新建demo文件夹,在输入Page文件名称,自动生成4个文件,文件路径也自动生成
"pages": ["pages/index/index","pages/logs/logs","pages/demo/index"],
- 如何配小程序的启动页面(首页)?
-
改变顺序 , 默认第一个就是启动页
-
entryPagePath 启动页面的路径(首页)
// 启动页面的路径(首页)"entryPagePath": "pages/logs/logs",
小程序的配置 – window(窗口的表现)⇒ app.json
- 配置下拉刷新
enablePullDownRefresh
是否启用下拉刷新backgroundTextStyle
下拉loading状态的样式
- 配置导航栏
navigationBarTitleText
导航栏标题navigationBarTextStyle
导航栏标题文字颜色navigationBarBackgroundColor
导航标背景颜色navigationStyle
自定义导航栏
"window": {"enablePullDownRefresh": true,//是否启用下拉刷新"backgroundTextStyle": "dark",//下拉loading状态的样式"navigationBarTitleText": "我的第一个小程序",//导航栏标题"navigationBarTextStyle": "white",//导航栏标题文字颜色"navigationBarBackgroundColor": "#f60",//导航标背景颜色"navigationStyle": "default"//自定义导航栏}
小程序的配置 – tabBar(tab栏)(2-5个)⇒ app.json
list
:配置 tab 栏列表
text
: 配置 tab 的文字pagePath
: 配置 tab的页面路径iconPath
&selectedIconPath
:配置 tab 对应的图标
color
&selectedColor
:配置 tab 文字的颜色backgroundColor
:配置 tab 栏的背景颜色borderStyle
:配置 tab 栏边框样式
"tabBar": {"color": "#f60","selectedColor": "#f60","backgroundColor": "#ccc","borderStyle": "black","list": [{"pagePath": "pages/index/index","text": "首页","iconPath": "static/tabbar/home-default.png","selectedIconPath": "static/tabbar/home-active.png"},{"pagePath": "pages/logs/logs","text": "我的","iconPath": "static/tabbar/logs-default.png","selectedIconPath": "static/tabbar/logs-active.png"},{"pagePath": "pages/demo/index","text": "首页","iconPath": "static/tabbar/face-default.png","selectedIconPath": "static/tabbar/face-active.png"}]}
小程序的配置 – 页面配置(页面的 .json 文件)⇒ 如pages/demo/index.json
- 与 window 对应的配置参数:
enablePullDownRefresh
是否启用下拉刷新navigationBarTitleText
导航栏标题文字navigationStyle
自定义导航栏- …省略其它
- 页面独有的配置参数
disableScroll
禁止页面滚动
- 全局配置项和页面自己的配置项冲突了,以页面自己的配置项为准
{"enablePullDownRefresh": true,//启用下拉刷新"navigationBarTitleText": "我的",//导航栏标题文字"navigationStyle": "default",//自定义导航栏"disableScroll": false//可以滚动
}
小程序的长度单位:rpx
移动端适配 ⇒ 等不缩放
- 特点:
- 小程序的屏幕宽度均为 750rpx
- 根据屏幕宽度自动换算成 px 长度
- 应用实践:
- 建议设计稿宽度以 750px 做为基准
- 设计稿中元素的尺寸即为小程序代码中 rpx 的尺寸
.box{width: 750rpx;height: 400rpx;line-height: 400rpx;text-align: center;background-color: #f5a11c;
}
小程序组件
- 小程序导航组件
- 小程序图片组件
- 小程序轮播图组件
- 小程序表单组件
- 小程序区域滚动组件
小程序常用组件:navigator
- url:页面路径
- 支持相对和绝对路径
- 路径为空时会报错
hover-class
:点击态的样式
none
禁用点击效果
open-type
:跳转方式
- switchTab 跳转到 tabBar 页面
- 底部导航栏的跳转,一般要跳转到底部导航栏,不可以跳转,配置open-type:switchTab 才可以跳转
//inde.wxml
<navigator url="/pages/index/index" hover-class="nav-hover" open-type="switchTab">跳转到首页页面</navigator>
<navigator url="/pages/demo/index" open-type="switchTab" hover-class="none" >跳转到我的页面</navigator>
<navigator url="/pages/logs/logs" open-type="switchTab">跳转到日志页面</navigator>
//index.wxss
.nav-hover{color: #f5a11c;background-color: chartreuse;font-size: xx-large;
}
小程序常用组件:image
- 占位容器:
- image 组件是一个有默认大小(320 x 240px)的“盒子”
- mode缩放模式:
scaleToFill
不保证缩放比,图片拉伸填满容器⇒ 默认拉伸(不考虑宽高比)aspectFit
保证缩放比,使图片的长边显示出来(留白)aspectFill
保证缩放比,使图片的短边显示出来(长边溢出并裁剪长边,短边拉伸屏幕⇒ 放大)
- 使用原则
- 指定“容器”的大小,根据设计稿设置 image 的宽高尺寸
- 图片铺满容器,设置
aspectFill
缩放模式
//index.wxml
<image class="image" src="/static/uploads/goods_1.jpg" mode="aspectFill"/>
小程序常用组件:swiper
- 组件结构
swiper
:滑块容器,只能嵌套swiper-item
组件swiper
默认高度150px
swiper-item
:滑块单元,可以嵌套任何内容,如image
- 组件属性
indicator-dots
是否显示面板指示点autoplay
是否自动切换circular
是否衔接滑动
//inde.wxml
<!-- swiper轮播 -->
<swiper class="banana" indicator-dots autoplay circular><swiper-item ><image class="img-item" src="/static/uploads/slide_1.jpg" /></swiper-item><swiper-item ><image class="img-item" src="/static/uploads/slide_2.jpg" /></swiper-item><swiper-item ><image class="img-item" src="/static/uploads/slide_3.jpg" /></swiper-item>
</swiper>
//index.wxss
.banana {height: 320rpx;
}
.img-item{width: 750rpx;height: 320rpx;
}
小程序常用组件:表单相关
- 输入框:
input
password
密码类型、placeholder
占位文字
- 单选框:
radio-group
和radio
value
指定表单数据、checked
选中状态
- 复选框:
checked-group
和checkbox
value
指定表单数据、checked
选中状态
- 选择框:
picker
mode
选择类型,region
省市县、date
日期
//index.wxml
<!--pages/demo/index.wxml-->
<text>pages/demo/index.wxml</text>
<!-- 提前准备好的布局结构代码 -->
<view class="register"><view class="legend">信息登记:</view><view class="form-field"><label for="">姓名:</label><view class="field"><input type="text" password placeholder="请输入姓名"/></view></view><view class="form-field"><label for="">性别:</label><view class="field"><radio-group bindchange=""><radio value="0"checked />男<radio value="1"/>女</radio-group></view></view><view class="form-field"><label for="">爱好:</label><view class="field"><checkbox-group bindchange=""><checkbox value="0" checked />唱<checkbox value="1"/>跳<checkbox value="2"/>rap</checkbox-group></view></view><view class="form-field"><label for="">籍贯:</label><view class="field"><picker mode="region" > 请选择籍贯</picker></view></view><view class="form-field"><label for="">生日:</label><view class="field"><picker mode="date"> 请选择生日日期 </picker></view></view>
</view>
小程序常用组件:scroll-view
- 组件结构:
scroll-view
内嵌套可任意内容,要求必须有溢出- 垂直滚动时必须要指定高度
- 组件属性:
scroll-x
允许水平方向滚动scroll-y
允许垂直方向滚动refresher-enable
启用下拉刷新交互
//index.wxml
<!--pages/scroll-view/index.wxml-->
<text>pages/scroll-view/index.wxml</text>
<!-- 提前准备好的布局结构代码 -->
<!-- 搜索框 -->
<view class="search-bar"><input type="text" placeholder="输入搜索关键字" />
</view>
<!-- 页面主体 -->
<view class="page-body" ><scroll-view class="aside" scroll-y><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view></scroll-view><scroll-view class="content" scroll-y refresher-enabled><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view><view class="item"></view></scroll-view>
</view>
//index.wxss
/* pages/scroll-view/index.wxss */
/* 提前准备的样式代码 */
page {background-color: #f2f2f2;
}
.search-bar {padding: 20rpx 30rpx;background-color:#fff;
}
.search-bar input {padding: 14rpx 20rpx 10rpx 40rpx;border: 1rpx solid #eee;border-radius: 70rpx;font-size: 28rpx;color: #333;
}
.page-body {height: 700rpx;display: flex;margin-top: 20rpx;
}
.page-body .aside {width: 200rpx;padding: 20rpx;background-color: #fff;
}
.page-body .aside .item {height: 60rpx;margin-bottom: 20rpx;border-radius: 10rpx;background-color: #eee
}
.page-body .aside .active {background-color: pink;
}
.page-body .content {flex: 1;padding: 20rpx;margin-left: 20rpx;background-color: #fff;
}
.page-body .content .item {float: left;width: 215rpx;height: 215rpx;margin: 0 20rpx 20rpx 0;border-radius: 10rpx;background-color: #eee;
}
.page-body .content .item:nth-child(even) {margin-right: 0;
}
小程序样式
- 全局样式
- 静态资源(图片)
- 字体图标
小程序的样式
- 全局样式
- app.wxss
view {color:chartreuse;
}
- 静态资源
- .wxss 中只能使用网络路径或 base64,比如背景图
.box{width: 750rpx;height: 400rpx;line-height: 400rpx;text-align: center;/* background-color: #f5a11c; */background-image: url(https://ts1.cn.mm.bing.net/th/id/R-C.15e970cd0765096178a6da16993cfbb1?rik=IT5KfevidZcTig&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1210%2f22%2fc0%2f14558824_1350879506501.jpg&ehk=X9ro%2fg%2fGTmsglVrbV%2bmy8c3wsAvcHseqcEhsf80RMWA%3d&risl=&pid=ImgRaw&r=0);background-size: cover;
}
- 字体图标
- iconfont 字体平台生成字体
- @import 导入字体对应的样式文件
- 根据类名引用不同的字体图标
//iconfont.wxss
@font-face {font-family: "iconfont"; /* Project id 4071059 */src: url('//at.alicdn.com/t/c/font_4071059_1ror2rb6gdw.woff2?t=1684230396072') format('woff2'),url('//at.alicdn.com/t/c/font_4071059_1ror2rb6gdw.woff?t=1684230396072') format('woff'),url('//at.alicdn.com/t/c/font_4071059_1ror2rb6gdw.ttf?t=1684230396072') format('truetype');
}.iconfont {font-family: "iconfont" !important;font-size: 16px;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}.icon-guanbi_24:before {content: "\e611";
}.icon-sousuo_xian24:before {content: "\e612";
}.icon-pinglun_xian24:before {content: "\e613";
}
//app.wxss
@import "./iconfont.wxss";
//index.wxml
<view class="iconfont icon-sousuo_xian24"></view>
day2
导入小程序
-
选择代码目录
-
项目配置文件
appid
当前小程序的 AppIDprojectname
当前小程序的项目名称- 变更AppID(视情况而定,如果没有开发权限时需要变更成个人的 AppID)
小程序模板语法
- 数据绑定
- 列表渲染
- 条件渲染
小程序模板语法:数据绑定
模板语法 : 在页面中渲染数据时所用到的一系列语法叫做模板语法,对应到 Vue 中就是指令的概念
- 插值
{{ }}
语法:只要有需要访问变量的地方均要使用{{ }}
- 内容绑定
- 属性绑定
//index.js
Page({data: {isChecked:true}
})
//index.wxml
<switch checked="{{isChecked}}" bindchange="" />
- 简易双向绑定:
model:value
支持双向数据绑定- 仅
input
和textarea
组件支持
//index.js
Page({data: {msg:"hello"}
})
//index.wxml
<input type="text" model:value="{{msg}}" />
<view>{{msg}}</view>
小程序模板语法:条件渲染
- 控制属性:
wx:if
和wx:else
wx:if
表达式的值为真时渲染内容wx:else
紧跟在wx:if
之后,wx:if
表达式值为假时渲染
- 组件属性:
hidden
- 组件始终会被渲染,根据表达式的值显示/隐藏内容
[hidden] { display: none }
隐藏节点内容(不是删除节点)- v-show⇒ display:none
- hidden⇒ display:none
- 内容频繁显示/隐藏时推荐使用
hidden
//index.js
Page({data: {isShow:true,isHidden:true}
})
//index.wxml
<view wx:if="{{isShow}}">大师兄</view>
<view wx:else>二师兄</view>
<view hidden="{{!isHidden}}">正在加载...</view>
小程序模板语法:列表渲染
wk:for
:重复渲染组件内容
index
默认值,访问数组的索引值item
默认值,访问数组的单元值
//index.js
Page({data: {students: [{id: 1, name: '贺洋', age: 20, gender: '男', level: '菜鸟'},{id: 2, name: '唐刚', age: 18, gender: '女', level: '笨鸟'},{id: 3, name: '常超', age: 20, gender: '女', level: '老鸟'}]}
})
//index.wxml
<!-- 列表渲染 -->
<view class="students"><view class="item"><text>序号</text><text>姓名</text><text>年龄</text><text>性别</text><text>级别</text></view><view class="item" wx:for="{{ students }}" wx:key="id"><text>{{ index+1 }}</text><text>{{ item.name }}</text><text>{{ item.age }}</text><text>{{ item.gender }}</text><text>{{ item.level }}</text></view>
</view>
wx:key
列表项唯一标识符
- 数组单元为对象时,只写属性名
- 数组单元为简单类型时,推荐使用
* this
//index.js
Page({data: {history: ['苹果', '华为', 'OPPO', '三星']}
})
//index.wxml
<!-- 简单数组 -->
<view class="history"><text wx:for="{{history}}" wx:key="*this">{{ item }}</text>
</view>
- 自定义访问变量:一般在
wx:for
嵌套时使用
wx:for-index
自定义访问数组索引值的变量wx:for-item
自定义访问数组单元值的变量
小程序内置API:网络请求 wx.request
- 基本用法
//index.js
wx.request({url: '这里是接口的地址',method: '这里是请求的方法',data: '请求时提交的数据',header: {/* 请求头信息 */},success: () => {/* 成功的回调 */},fail: () => {/* 失败的回调 */},complete: () => {/* 成功或失败的回调 */}
})
- 功能步骤:
- 监听按钮的点击事件
- 调用
wx.request
- 列表数据渲染
- 配置合法域名:
- 开发环境设置不校验合法域名
- 在管理后台配置,必须为
https
协议 - 多个域名间使用分号分隔
- 开发小技巧:
- 添加编译模式
//index.js
Page({/*** 页面的初始数据*/data: {books:[]},getBooks(){wx.request({url: 'https://hmajax.itheima.net/api/books',method:'GET',data: {creator: 'zhangsan'},success:(res)=>{console.log(res.data.data)this.setData({books:res.data.data})},fail:()=>{console.log('请求失败')},complete:()=>{console.log('请求完成')}})}
})
//index.wxml
<button class="button" size="mini" type="primary" bind:tap="getBooks">查询书单</button>
<view class="books"><view class="item"><text>序号</text><text>名称</text><text>作者</text><text>出版社</text><text>操作</text></view><view class="item" wx:for="{{books}}" wx:key="id"><text>{{ index+1 }}</text><text>{{ item.bookname }}</text><text>{{ item.author }}</text><text>{{ item.publisher }}</text><text>删除</text></view>
</view>
小程序内置API:界面交互
wx.showLoading
显示 loading 提示框 ⇒ 获取请求之前
title
文字提示内容mask
是否显示透明蒙层,防止触摸穿透
wx.hideLoading
隐藏loading
提示框
wx.showToast
消息提示框(轻提示)title
文字提示内容mask
是否显示透明蒙层,防止触摸穿透duration
提示框持续的时长icon
更改图标,none
不使用图标
//index.wxml
<button class="button" size="mini" type="primary" bind:tap="getBooks">查询书单</button>
<view class="books"><view class="item"><text>序号</text><text>名称</text><text>作者</text><text>出版社</text><text>操作</text></view><view class="item" wx:for="{{books}}" wx:key="id"><text>{{ index+1 }}</text><text>{{ item.bookname }}</text><text>{{ item.author }}</text><text>{{ item.publisher }}</text><text>删除</text></view>
</view>
//index.js
getBooks(){wx.showLoading({title: '正在加载',mask:true}),wx.request({url: 'https://hmajax.itheima.net/api/books',method:'GET',data: {creator: 'zhangsan'},success:(res)=>{console.log(res.data.data)this.setData({books:res.data.data})wx.showToast({title: '查询书单成功!',mask:true,duration:5000,//默认1500(1.5秒)icon:"success"})},fail:()=>{console.log('请求失败')},complete:()=>{console.log('请求完成')// 取消加载wx.hideLoading()}})}
小程序内置API:本地存储
wx.setStorageSync
存储数据wx.getStorageSync
读取数据wx.removeStorageSync
删除数据wx.clearStorageSync
清空数据
sync
:同步async
:异步
// pages/interface/index.js
// 1. 监听按钮
// 2. 发请求
// 3. 渲染列表
Page({/*** 页面的初始数据*/data: {books:[] },// 存数据saveData(){wx.setStorageSync('books', ['三国演义','水浒传'])},// 取数据getData(){const res = wx.getStorageSync('books')console.log(res)},// 删数据delData(){wx.removeStorage({key: 'books',})},// 清空数据clearData(){wx.clearStorage()} })
<!--pages/interface/index.wxml-->
<!-- 本地存储 -->
<view class="storage"><button size="mini" type="primary" bind:tap="saveData">存数据</button><button size="mini" type="primary" bind:tap="getData">读数据</button><button size="mini" type="primary" bind:tap="delData">删数据</button><button size="mini" type="primary" bind:tap="clearData">清数据</button>
</view>
小程序内置API:API 的特征
- 同步 API:同步方式读取 API 执行结果
API
的名称以Sync
为后缀
- 异步 API:回调函数读取 API 执行结果
- 支持
success
、fail
、complete
回调函数
Promise
:部分 API 支持(查看文档)
- 配合
async/await
wx.chooseMedia
wx.chooseMedia
调起摄像头拍照或读取相册内容,该 API 既支持回调方式获取结果,也支持Promise
方式返回结果
// pages/interface/index.js
Page({/*** 页面的初始数据*/data: { imgPath:''},
// 选取照片async chooseImg(){const res = await wx.chooseMedia()console.log(res)this.setData({imgPath:res.tempFiles[0].tempFilePath})// wx.chooseMedia()// .then(res=>{// console.log(res.tempFiles[0].tempFilePath)// this.setData({imgPath:res.tempFiles[0].tempFilePath})// console.log(this.data.imgPath)// })}
})
<!--pages/interface/index.wxml-->
<view><image src="{{imgPath}}" /><button type="primary" size="mini" bind:tap="chooseImg">上传图片</button>
</view>
小练习:搜索历史
- 双向数据绑定:获取搜索关键字
model:value
获取表单内容this.setData
记录到数组中
- 列表数据渲染:渲染搜索历史
wx:for
渲染搜索历史- 本地存储:持久化存储
wx.setStorageSync
wx.getStorageSync
// pages/interface/index.js
// 1. 监听按钮
// 2. 发请求
// 3. 渲染列表
Page({/*** 页面的初始数据*/data: {books:[],keywords:'',history:wx.getStorageSync('history') || []}, // 历史搜索doSearch(){console.log(this.data.keywords)const { history , keywords } = this.datahistory.unshift(keywords)console.log(history)this.setData({ history , keywords:'' })//todo:数据持久化wx.setStorageSync('history', history)}
})
<!--pages/interface/index.wxml-->
<!-- 搜索历史 -->
<view class="history"><view class="search-bar"><input type="text" model:value="{{ keywords }}" /><text class="label" bind:tap="doSearch">搜索</text></view><view class="title">历史搜索 <text class="icon-delete">x</text></view><view class="keywords"><navigator url="/pages/test/index" wx:for="{{ history }}" wx:key="*this">{{ item }}</navigator></view>
</view>
小程序事件处理:事件对象
- 事件对象:事件回调的第1个参数
ev.mark
ev.target.dataset
- 应用:
Tab
交互
- 确定点击
tab
的索引值 - 根据条件添加
active
类名
// pages/events/index.js
Page({/*** 页面的初始数据*/data: {activeIndex:0,isPulling:false},//点击高亮selectItem(ev){// console.log(ev)// console.log(ev.target.dataset)console.log(ev.mark.key)this.setData({ activeIndex:ev.mark.key })}
})
<!--pages/events/index.wxml-->
<!-- 页面主体 -->
<view class="page-body"><scroll-view scroll-y class="aside"><viewwx:for="{{6}}"wx:key="*this"class="item {{ index === activeIndex ? 'active' : ''}} "mark:key="{{ index }}"data-key=" {{ index }} "bind:tap="selectItem"></view></scroll-view></view>
小程序事件处理:组件事件
scroll-view
组件
bind:scrolltolower
滚动到底部时触发bind:refresherrefresh
执行下拉操作时触发refresher-triggered
变更下拉刷新状态(结束下拉刷新)
// pages/events/index.js
Page({/*** 页面的初始数据*/data: {isPulling:false},loadMore(){console.log('触底了,加载更多')// 请求接口,获取下一页数据},refreshPage(){console.log('下拉刷新')// 重新调接口,获取当前页面的数据,渲染页面// 需要将 isPulling重新设置为 falsesetTimeout(() => {this.setData({ isPulling: false })}, 2000);}
})
<!--pages/events/index.wxml--><scroll-viewscroll-yrefresher-enabledbind:scrolltolower="loadMore"bind:refresherrefresh="refreshPage"refresher-triggered="{{ isPulling }}"class="content" ></scroll-view>
- 表单组件
change
表单数据发生改变时触发(input
不支持)submit
表单提交时触发(指定form-type
)
- 上拉触底,加载更多
// pages/events/index.js
Page({ // 表单组件中的事件changeGender(ev){console.log(ev.detail.value)},selectHobby(ev) {console.log(ev.detail.value)},selectRegion(ev) {console.log(ev.detail)// ev.datail.value ==> '北京市-北京市-东城区'this.setData({ region:ev.detail.value.join('-') })},formSubmit(){console.log('表单提交了')}})
<!--pages/events/index.wxml-->
<!-- 用户信息 -->
<view class="register"><form bind:submit="formSubmit"><view class="form-field"><label for="">姓名:</label><view class="field"><input type="text" placeholder="请输入您的姓名" /></view></view><view class="form-field"><label for="">性别:</label><view class="field"><radio-group bind:change="changeGender"><radio value="男" checked />男<radio value="女" />女</radio-group></view></view><view class="form-field"><label for="">爱好:</label><view class="field"><checkbox-group bind:change="selectHobby"><checkbox value="写代码" checked />写代码<checkbox value="睡大觉" />睡大觉</checkbox-group></view></view><view class="form-field"><label for="">籍贯:</label><view class="field"><picker mode="region" bind:change="selectRegion">{{ region || '请选择籍贯'}}</picker></view></view><button size="mini" type="primary" form-type="submit">保存</button></form>
</view>
小程序生命周期:页面生命周期
onLoad
:初次加载
- 页面加载完成时会执行 1 次
- 常用于获取地址参数、发起网络请求等
onShow
:渲染页面被看到时 ⇒ 可以多次触发
- 页面处于可见状态时执行
- 常用于动态更新状态或数据
onHide
:页面看不到时 ⇒ 可以多次触发
- 页面处于不可见状态时执行
- 常用于销毁长时间运行的任务,如定时器
// pages/lifetimes/index.js
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {console.log('页面加载',options)},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {console.log('页面渲染')},/*** 生命周期函数--监听页面显示*/onShow() {console.log('页面处于显示状态')},/*** 生命周期函数--监听页面隐藏*/onHide() {console.log('页面处于隐藏状态')},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})
小程序生命周期:应用生命周期
onLaunch
- 小程序启动时会执行 1 次
- 常用于获取场景值或参数
onShow
⇒ 显示
- 小程序处于前台运行时执行
onHide
⇒ 隐藏
- 小程序处于后台运行时执行
// app.js
App({onLaunch(options){console.log('应用启动',options)},onShow(){console.log('应用处于前台--能被用户看到');},onHide(){console.log('应用处于后台--用户看不到');}
})
页面分享
- 有
onShareAppMessage(){}
这个函数就可以分享给好友(虚拟)
// pages/index/index.js
Pages({/*** 用户点击右上角分享*/onShareAppMessage() {}})
小练习:头像&昵称 ⇒ 知识总结:
- 微信昵称:
input
组件type
属性值设置为nickname
- 监听
blur
事件获取用户昵称(在开发者工具中需要blur
两次)
- 微信头像:
button
组件open-type
属性值设置为chooseAvatar
- 监听
chooseavatar
事件获取头像临时地址(只能在小程序中使用)
day3
分包加载
- 为什么分包?
- 使用分包
- 分包预加载
小程序分包加载(按需加载)
- 为什么进行分包加载?
- 小程序限制单个代码包体积不超过2M
- 分包可以优化小程序页面的加载速度
"packOptions": {"ignore": [{"value": "/static/uploads","type": "folder"}],"include": []}
- 启用/使用分包:
subPackages
app.json
root
分包所在的(根)目录pages
分包中包含的页面tabBar
的页面不允许分包- 所有包不超过20M
//app.json"subPackages": [{"root": "subpack_demo","pages": ["pages/demo/index"]},{"root": "subpack_user","pages":["pages/profile/index","pages/my/index"]}]
- 分包预加载:
preloadRule
- 页面路径做为
key
(属性) network
预加载的网络环境packages
需要预加载的包
//app.json"preloadRule": {"pages/framework/index":{"network": "all","packages": ["subpack_user"]}}
自定义组件
- 为什么分包?
- 使用分包
- 分包预加载
小程序自定义组件 - 基本语法
- 创建自定义组件
.json
文件中component: true
.js
中调用Component
函数
- 使用自定义组件
- 全局配置或页面配置
usingComponents
- 页面中以组件形式引入
- 局部注册
//pages/component/index.json
{"component": true,"usingComponents": {"navigation-bar" :"/components/navigation-bar/index"}
}
- 使用
//pages/component/index.wxml
<navigation-bar></navigation-bar>
- 全局注册
//app.json"usingComponents": {"navigation-bar":"./components/navigation-bar/index"}
- 在哪使用在哪写
//pages/component/index.wxml
<navigation-bar></navigation-bar>
小程序自定义组件 – 组件样式
- 样式隔离
.js
文件中传入options: { addGlobalClass: true }
// components/navigation-bar/index.js
Component({options:{addGlobalClass:true}
})
/* pages/component/index.wxss */
.navigation-bar{color: rgb(236, 247, 243);font-size: xxx-large;font-weight:bold;line-height: 300rpx;border: 10px solid rgb(206, 142, 236);
}
- 尽量不要使用标签、ID、属性选择器
- 样式修改以权重比较为主
- 外部样式类
.js
文件中传入externalClasses: [ xxx, yyy]
xxx、yyy
可以理解成“变量- 步骤
- 组件内部同意修改
// components/navigation-bar/index.js
Component({ externalClasses:['title-class']
})
<!--components/navigation-bar/index.wxml-->
<view ><view class="title-class">自定义导航栏</view>
</view>
- 外部修改
<!--pages/component/index.wxml--><navigation-bar title-class="title"></navigation-bar>
/* pages/component/index.wxss */
.title{width: 800rpx;height: 300rpx;text-align: center;line-height: 300rpx;background-color: rgb(238, 247, 160);color: rgb(247, 173, 231);font-size: xxx-large;font-weight:bold;border: 10px solid rgb(206, 142, 236);
}
小程序自定义组件 – <slot />
(插槽)
- 创建插槽:
- 默认情况只能 1 个
<slot />
.js
文件中传入options: { multipleSlots: true }
<slot name=“title”/>
为插槽命名
- 使用插槽
- 单个插槽:在组件中间填充内容
- 多个插槽:使用 slot 属性指定插槽位置
// components/navigation-bar/index.js
Component({options:{// 样式隔离(同意外部修改)addGlobalClass:true,// 开启多插槽multipleSlots:true},// 外部样式类externalClasses:['title-class']
})
<!--components/navigation-bar/index.wxml-->
<!-- <text>components/navigation-bar/index.wxml</text> -->
<view ><view class="title-class"><slot name="left"> </slot><slot> </slot><slot name="right"> </slot></view>
</view>
<!--pages/component/index.wxml-->
<navigation-bar title-class="title">
<text slot="left">返回</text>
自定义导航栏
<text slot="right">去注册</text>
</navigation-bar>
/* pages/component/index.wxss */
.title{width: 740rpx;height: 300rpx;text-align: center;line-height: 300rpx;background-color: rgb(238, 247, 160);color: rgb(204, 12, 162);font-size: x-large;font-weight:lighter;border: 3px solid rgb(255, 34, 126);
}
小程序自定义组件 – lifetimes
(生命周期)
created
:组件创建时触发
- 类似 Vue 中的
created
- 不能调用
this.setData
attached
:组件初始完毕时触发
- 类似于 Vue 中的
mounted
- 在
attached
中可以调用this.setData
修改data中的数据
- 应用示例:状态栏适配
wx.getSystemInfoSync()
// components/navigation-bar/index.js
Component({options:{// 样式隔离(同意外部修改)addGlobalClass:true,// 开启多插槽multipleSlots:true},// 外部样式类externalClasses:['title-class'],// 生命周期 data:{msg:'测试数据'},lifetimes:{// 可以理解为Vue里面的createdcreated(){console.log('组件创建完成')// this.setData({msg:'hello world'})},// 可以理解为Vue里面的mountedattached(){console.log('组件挂载完成');this.setData({msg:'hello world'})},detached(){console.log('组件卸载完成');}}
})
<!--components/navigation-bar/index.wxml-->
<!-- <text>components/navigation-bar/index.wxml</text> -->
<view ><view class="title-class"><slot name="left"> </slot><slot> </slot><slot name="right"> </slot><view>{{ msg }}</view></view>
</view>
小程序自定义组件 – 组件通信 – 父传子
- 自定义属性:
properties
父传子 - 应用示例:路由返回
wx.navigateBack()
- 子组件
// components/navigation-bar/index.js
Component({data:{//自定义导航适配statusBarHeight:0}, // 生命周期 lifetimes:{// 可以理解为Vue里面的mountedattached(){//自定义导航适配const info = wx.getSystemInfoSync()console.log(info.statusBarHeight)this.setData({ statusBarHeight : info.statusBarHeight })}},properties:{back:Boolean,delta:{type:Number,value:1}},methods:{goBack(){console.log('返回')wx.navigateBack()}}
})
<!--components/navigation-bar/index.wxml-->
<!-- 自定义导航适配 -->
<view class="navigation-bar" style="padding-top: {{ statusBarHeight }}px;">
<view class="navigation-bar-back" wx:if="{{ back }}" bind:tap="goBack"></view>
<view class="navigation-bar-title"><slot></slot>
</view>
</view>
/* components/navigation-bar/index.wxss */
.navigation-bar {left: 0;top: 0;z-index: 999;display: flex;align-items: center;height: 44px;background-color: #fff;
}.navigation-bar-title {flex: 1;text-align: center;font-size: 14px;
}.navigation-bar-back {position: absolute;left: 10px;width: 44rpx;height: 44rpx;background-image: url(https://lotjol.github.io/static-store/enjoy-plus/images/back-arrow.svg);background-repeat: no-repeat;
}
- 父组件
//subpack_user/pages/profile/index.json
{"usingComponents": {},"navigationStyle": "custom"
}
<!--subpack_user/pages/profile/index.wxml-->
<navigation-bar back>自定义导航栏</navigation-bar>
<text>subpack_user/pages/profile/index.wxml</text>
小程序自定义组件 – 组件通信 – 倒计时组件 – 子传父
- 应用示例:倒计时组件
- 外部样式类
<slot />
插槽- 自定义属性
- 生命周期
- 自定义事件:
bind:事件类型(自定义
子传父
this.triggerEvent(‘事件类型’, 参数)
子传父
- 子组件
// components/count-down/index.js
Component({/*** 组件的初始数据*/data: {timeStr: ''},/*** 组件的属性列表*/properties: {time:Number,format: {type: String,value:'ss秒' //10秒,9秒...}},/*** 组件的方法列表*/methods: {},lifetimes:{created(){},attached(){let { time ,format } = this.datathis.setData({ timeStr: format.replace('ss',time) })const timer = setInterval(()=>{this.setData({time: --time,timeStr: format.replace('ss',time)})// 停止倒计时的条件:0if(this.data.time <= 0){console.log('倒计时停止');clearInterval(timer)// 告诉父组件,我结束了this.triggerEvent('finish')}},1000)}}
})
<!--components/count-down/index.wxml-->
<view class="count-down">{{timeStr}}</view>
- 父组件
// pages/login/index.js
Page({/*** 页面的初始数据*/data: {isWaitingCode:false},// 发送验证码sendMsgCode(){this.setData({ isWaitingCode: true })},// 重置短信发送状态resetWaitingStatus(){this.setData({ isWaitingCode : false }) }
})
//pages/login/index.json注册组件
{"usingComponents": {"count-down":"/components/count-down/index"}
}
<!--pages/login/index.wxml-->
<view class="login"><view class="form-field"><input type="text" placeholder="请输入手机号" /><text wx:if="{{ !isWaitingCode }}" bind:tap="sendMsgCode" class="label">获取短信验证码</text><!-- 倒计时组件 --><count-down wx:else class="label" time="3" format="ss秒后重新发送" bind:finish="resetWaitingStatus"></count-down></view><view class="form-field"><input type="text" placeholder="请输入短信验证码" /></view><button>登录</button>
</view>
/* pages/login/index.wxss */
page {padding: 0;
}.login {margin: 20rpx 20rpx 0;padding: 30rpx 20rpx;border-radius: 10rpx;background-color: #fff;
}.login .form-field {display: flex;padding: 10rpx 0;border-bottom: 1rpx solid #eee;
}.login .label {padding-right: 20rpx;line-height: 80rpx;color: #5591AF;
}.login input {flex: 1;height: 54rpx;border: none;
}.login button {width: 100% !important;margin-top: 30rpx;color: #fff;background-color: #5591AF;
}
小程序自定义组件 – Vant 组件库
- 安装
Vant
组件库
npm i @vant/weapp -S --production
- 移除
style: “v2”
- 需要手动在
project.config.json
内添加如下配置
{..."setting": {..."packNpmManually": true,"packNpmRelationList": [{"packageJsonPath": "./package.json","miniprogramNpmDistDir": "./miniprogram/"}]}
}
-
npm
构建
-
Vant
组件演示
- 全局注册app.json
"usingComponents": {"navigation-bar":"./components/navigation-bar/index","van-button": "@vant/weapp/button/index"}
- 使用
<van-button type="default">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>
- 示例
van-button
van-field
van-cell-group
//app.json全局注册vant组件
{"usingComponents": {"van-button": "@vant/weapp/button/index","van-field": "@vant/weapp/field/index","van-cell": "@vant/weapp/cell/index","van-cell-group": "@vant/weapp/cell-group/index"}
}
// pages/component/index.js
Page({/*** 页面的初始数据*/data: {//手机号数据双向绑定value: ''}
})
<!--pages/component/index.wxml-->
<van-cell-group title="用户登录"><van-fieldvalue="{{ username }}"clearablelabel="手机号"placeholder="请输入手机号码"bind:click-icon="onClickIcon"/> <van-fieldvalue="{{ sms }}"centerclearablelabel="短信验证码"placeholder="请输入短信验证码"border="{{ false }}"use-button-slot><van-button slot="button" size="small" type="primary">发送验证码</van-button></van-field>
</van-cell-group>
框架接口
- 昵称和头像
- 应用实例
- 页面栈(页面实例)
小程序框架接口:应用实例(数据共享)
- 基本用法:
App
函数中定义属性和方法getApp
函数获取应用实例
- 应用示例:
onLaunch
中读取本地数据- 应用实例读取或更新数据
小程序框架接口:页面栈(页面实例)
- 基本用法:
getCurrentPages
获取当前页面栈(数组)wx.redirectTo
关闭当前页,再跳转到新页面wx.navigateTo
保留当前页,再跳转到新页面
// pages/framework/index.js
const app = getApp()
Page({gotRedirectPage(){wx.redirectTo({url: '/subpack_user/pages/profile/index'})},gotNavigatePage(){wx.navigateTo({url: '/subpack_user/pages/profile/index'})}
})
<!--pages/framework/index.wxml--><button type="primary" bind:tap="gotNavigatePage">去用户页面navigateTo</button><button type="primary" bind:tap="gotRedirectPage">去用户页面redirectTo(不能返回)</button>
- 页面实例:
data
页面初始数据setData
更新数据onShow
生命周期route
页面路径
- 报错
uni-app
uni-app
是一个使用Vue.js
开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。- 明天开始上 uniapp 课程,请大家提前下载工具:
HbuilderX:https://www.dcloud.io/hbuilderx.html
文档:
uniapp官方文档:https://uniapp.dcloud.net.cn/
黑马优购在线文档:https://applet-base-api-t.itheima.net/docs-uni-shop/index.htm
黑马优购接口文档:https://www.showdoc.com.cn/128719739414963/2513235043485226
day1
创建 uni-app 项目
-
通过 HBuilderX 创建
-
创建项目
-
目录结构
-
文件讲解
-
把项目运行到微信开发者工具
-
填写自己的微信小程序的 AppID:
-
在 HBuilderX 中,配置“微信开发者工具”的安装路径:
C:\Program Files (x86)\Tencent\微信web开发者工具
-
在微信开发者工具中,通过 设置 -> 安全设置 面板,开启“微信开发者工具”的服务端口:
-
先打开一个文件,点击运行
-
成功下载编译工具
停止运行, 重新点击运行⇒ 信任并运行 -
初次运行成功之后的项目效果:
配置tabBar
- 将 资料 目录下的 static 文件夹 拷贝一份,替换掉项目根目录中的 static 文件夹
- 直接覆盖过去,项目里运来的 static 不要删除!
- 新建tabBar文件夹
删除默认的 index 首页
- 在 HBuilderX 中,把 pages 目录下的 index首页文件夹 删除掉
- 同时,把 page.json 中记录的 index 首页 路径删除掉
显示效果
首页
- 微信小程序不支持axios
uni-request
⇒ 发请求- 配置网络请求
- 由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request() API 功能较为简单,不支持拦截器等全局定制的功能。因此,建议在 uni-app 项目中使用
@escook/request-miniprogram
第三方包发起网络数据请求。
封装器
封装器
这篇关于2023.8.21--微信小程序uni-app的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!