App实例
每个小程序都需要在app.js中调用App函数注册小程序示例;
- 在注册时,可以绑定对应的生命周期函数;
- 在生命周期函数中,执行对应的代码;
developers.weixin.qq.com/miniprogram…
注册App时,我们会做哪些操作?
- 1.判断小程序的进入场景;
- 2.监听生命周期函数,在生命周期中执行对应的业务逻辑,比如在某个生命周期函数中进行登录或者网络请求;
- 3.因为App()实例只有一个,并且是
全局共享的(单例对象),所以我们可以将一些共享数据放在这里;
小程序没有提供状态共享库(Vuex/Pinia)
App()中共享一些简单的数据还行,大的数据共享就不太行了,后续我们再详谈;
判断进入场景
小程序常见的打开场景:群聊会话中打开、小程序列表中打开、微信扫一扫打开、另一个小程序中打开:
developers.weixin.qq.com/miniprogram…
如何确定场景?
- 在
onLaunch和onShow生命周期回调函数中,会有options参数,其中这个参数有一个scene值:
// app.js
App({
// 生命周期函数
onLaunch(options){
// 生命周期回调——监听小程序初始化。
console.log(options);
},
// 生命周期回调——监听小程序启动或切前台。
onShow(options){
// 通过options判断小程序进入场景
console.log('onShow');
},
// 生命周期回调——监听小程序切后台。
onHide(){
console.log('onHide');
}
})
定义全局App的数据
存储全局数据的属性名是自定义的,但是最好做到见名知意的:
// pages/order/order.js
Page({
data: {
userInfo: {}
},
onLoad() {
// 获取共享的数据: App实例中数据
// 1.获取app实例对象
const app = getApp()
// 2.从app实例对象获取数据
const token = app.globalData.token
const userInfo = app.globalData.userInfo
console.log(token, userInfo);
// 3.拿到token目的发送网络请求
// 4.将数据展示到界面上面,如果不是setdata保存数据,则不是响应式的
this.setData({
userInfo:userInfo
})
//简写:this.setData({userInfo })
console.log(this.data.userInfo);
}
})
App({
// 作用二: 共享数据
// 数据不是响应式, 这里共享的数据通常是一些固定的数据
globalData: {
token: "",
userInfo: {}
},
})
生命周期函数
在生命周期函数中,完成应用程序启动后的初始化操作:
onLaunch:
- 比如登录操作
- 比如读取本地数据(类似于token,然后保存在全局,方便使用)
- 比如请求整个应用程序需要的数据
一登录,onLaunch中的数据就会被保存起来
//app.js
App({
onLaunch(options){
//1.从本地获取token/userInfo
const token = wx.getStoreageSync("token")
const userInfo = wx.getStorageSync("userInfo")
//2.进行登录操作(逻辑判断)
//将登陆成功的数据,保存到storeage中
//只有当没有数据的时候,才会来到这里,进行存储数据
if(!token || !userInfo){
wx.setStorageSync("token","kobeToken")
wx.setStorageSync("userInfo",{
//存储对象
nickname:"Kobe",
level:100
})
}
//3.将获取到的数据保存在globalData中
this.globalData.token = token
this.globalData.userInfo = userInfo
}
})
代码组件方式调整
pages中保存的页面不能有中文:
<!-- home首页 -->
<view class="pages">
<block wx:for="{{pages}}" wx:key="name">
<button
type="primary"
bindtap="onBtnClick"
data-item="{{item}}"
>
{{ item.name }}
</button>
</block>
</view>
// index.js
Page({
data: {
pages: [
{ name: "01_初体验", path: "/pages/01test/index" },
{ name: "02_页面配置", path: "pages/02_页面配置/index" }
]
},
onBtnClick(event) {
// 1.获取item
const item = event.target.dataset.item
// 2.跳转路径
wx.navigateTo({
url: item.path,
})
}
})
注册页面-Page函数
小程序中的每个页面,都有一个对应的js文件,其中调用Page函数注册页面实例:
- 在注册时,可以绑定初始化数据、生命周期回调、事件处理函数等;
developers.weixin.qq.com/miniprogram…
注册一个Page页面时,我们一般做:
- 1.在生命周期函数中,发送网络请求,从服务器中获取数据;
- 2.初始化一些数据,以方便被wxml引用展示;
- 3.监听wxml中的事件,绑定对应的事件函数;
- 4.其他一些监听(比如页面滚动、上拉刷新、下拉加载更多等)
developers.weixin.qq.com/miniprogram…
小程序开的2个线程,一个是:ViewThread(渲染页面),还有一个是:AppService Thread(执行js代码)的线程;
当我们创建一个页面时,会生成wxml、wxss、js、json文件,实际上4个页面会生成2个线程,ViewThread线程读取wxml、wxss文件,他会等待一会儿才会渲染,而AppServiceThread线程用来解析js、json文件;
ViewThread会等待AppserviceTHread进行onLoad、onShow初始化数据,并发送给ViewThread线程,这个时候ViewThread中有数据了,就会FirstRender第一次渲染,发送通知,AppserviceThread就会onReady,页面就渲染好了,当数据发生变化的时候,AppServiceThread又会sendData再次发送数据,然后ViewThread又会Rerender重新渲染,重复此步骤;如果用户把页面关闭,数据会发送到后台set to background,然后回调onHide,一旦打开后,又会set to foreground回到前台,然后回调onShow;
当页面切换的时候,就会执行onUnload生命周期,也就是销毁;
//index.js
onShow(){
}
onReady(){
}
onHide(){
}
onUnload(){
}
组件
Text文本组件
Text组件,类似于span标签
- 通过设置
user-select属性决定文本内容是否可以让用户选中; - 设置
decode:true可以解析特殊字码,比如>等;
button组件
button组件是一个块级元素,和HTML不同!!!
- mini属性:设置button大小,default是默认大小,size是小尺寸;
- type属性:primary绿色、default白色、warn红色;
- plain属性:设置按钮是否镂空,也就是背景色是透明;
- disabled:设置按钮是否禁用;
- loading:按钮前面有一个loading动画
- hover-class:指定按钮按下去后的样式类,当
hover-class='none'时,没有点击效果
按钮的open-type
- contact:
open-type=contact会跳转到客服会话,跳转到微信客服会话; - 现在想要拿到用户信息,必须通过触发
bindgetuserinfo,通过wx.getUserProfile才能拿到用户信息;
返回的是一个Promise
<button size="mini" type="primary" bindgetuserinfo="getUserInfo">
Page({
//绑定函数调用:
getUserInfo(event){
//调用API,获取用户信息
wx.getUserProfile({
desc:'desc',//必传的
}).then(res)=>{
console.log(res)
}
}
})
获取用户手机号,绑定bindgetphonenumber:如果是个人,是不可以获取手机号的,除非是企业级
<button size="mini" type="primary" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
手机号码
</button>
Page({
getPhoneNumber(event){
}
})
View组件解析
View组件类似于HTML中的div
View也有hover-class属性,hover-starat-time、hover-stay-time属性:
<view bindtap='onViewClick' hover-class="active"></view>
Image组件的使用
developers.weixin.qq.com/miniprogram…
/可以表示根目录,image元素默认宽高是:320*240,并且是一个行内块级(HTML中是行内替换元素)所以不自己设置一下样式,会存在问题;
//index.wxml
<image src = '/assets/zznh.png'/>
<image src = '网络图片的地址'/>
图片中非常重要的属性:mode
- top:裁剪模式,不缩放图片,只显示图片顶部
- bottom:裁剪模式,不缩放图片,只显示图片底部
- top right:裁剪模式,不缩放图片,只显示右上角
- scaleToFill:缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
- aspectFill:缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
- aspectFit:缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。但是左右两边可能会存在空白
- widthFix:缩放模式,宽度不变,高度自动变化,保持原图宽高比不变;(宽度为320的情况下,高度自适配,常用)
- heightFix:高度是240,宽度自适配(用得不多)
大多数情况下,这些方式我们都不常用,最常用的是widthFix
<image src ='...' mode="top"/>
<image src ='...' mode="bottom"/>
<image src ='...' mode="top right"/>
<image src ='...' mode="scaleToFill"/>
<image src ='...' mode="aspect"/>
选择本地图片,通过一个API:wx.chooseMedia
//index.wxss
<button bindtap='onChooseImage'>选择图片</button>
<image src="{{chooseImageUrl}}/">
//index.js
Page({
data:{
chooseImageUrl:""
}
onChooseImage(){
wx.chooseMedia({
//选择手机中的图片
mediaType:"image",
}).then(res=>{
cosnt imagePath=res.tempFiles[0].tempFilePath
this.setData({chooseImageUrl:imagePath})
})
}
})
developers.weixin.qq.com/miniprogram…
scroll-view
上下滚动(y轴滚动,设置scroll-y)
//index.wxml
<scroll-view class="container scroll-x" scroll-y enable-flex>
<block wx:for="{{viewColors}}" wx:key="*this">
<view class="item">{{item}}</view>
</block>
</scroll-view>
//index.wxss
.container{
background-color:orange;
height:
}
.item{
width:100px;
height:100px;
}
如果想要flex布局生效,还需要在scroll-view元素中开启
.scroll-x{
display:flex;
}
scroll-view滚动监听
<scroll-view
bindscrolltoupper="onScrollToUpper"
bindscrolltolower="onScrollToLower"
bindscroll="onScroll"
>
</scroll-view>
Page({
onScrollToUpper(){
console.log('滚动到最顶部/左边')
},
onScrollToLower(){
console.log('滚动到最底部/右边')
},
onScroll(event){
console.log('scrollView发生滚动',event)
event.scrollLeft //已经滚动的值
event.scrollHeight //已经滚动的值
event.scrollWidth //可以滚动的距离
}
})
组件共同属性和input组件的双向绑定
input默认是没有背景的,直接就是一个输入框
<input type="text" model:value="{{双向绑定}}"/>
//index.wxss
input{
width:200px;
height:30px;
border:1px solid orange;
}