微信小程序3天课程学习的第2天笔记
浏览器的生命周期函数:
jQuery的$(document).ready(function(){})将会先一步执行
window.onload = function(){} 所有加载完了,最后才执行
输出结果如下:
微信小程序的生命周期函数:
/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { console.log('1. onload') }, /** * 生命周期函数--监听页面显示 */ onShow: function () { console.log('2. onShow') }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { console.log('3. onReady') }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { console.log('4. onReachBottom') }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { console.log('5. onPullDownRefresh') }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { console.log('6. onShareAppMessage') }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { console.log('7. onHide') }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { console.log('8. onUnload') }
如图所示:
我们可以通过onShow(options){ }的参数options知道,用户是通过什么方式打开的小程序
如图所示: (我咋没有重现???)
各场景值如下:
数据绑定
在js后缀文件中定义ViewModel,
data: {
msg: "hello beyond",
isChecked: true
}
在wxml文件中, 直接使用{{ msg }}
<input type="radio" checked="{{isChecked}}" />
注意: 1. 引号和大括号间不能有空格
2. 不能直接写checked="isChecked", 那样么转成字符串(永远为true)
而为要mustache语法,这样才是真正在计算ViewModel
发送网络请求: 使用wx.request({})
关于小程序中网络相关API的说明
网络API列表:
API | 说明 |
---|---|
wx.request | 发起网络请求 |
wx.uploadFile | 上传文件 |
wx.downloadFile | 下载文件 |
wx.connectSocket | 创建 WebSocket 连接 |
wx.onSocketOpen | 监听 WebSocket 打开 |
wx.onSocketError | 监听 WebSocket 错误 |
wx.sendSocketMessage | 发送 WebSocket 消息 |
wx.onSocketMessage | 接受 WebSocket 消息 |
wx.closeSocket | 关闭 WebSocket 连接 |
wx.onSocketClose | 监听 WebSocket 关闭 |
在小程序中使用网络相关的 API 时,需要注意下列问题,请开发者提前了解。
1. 服务器域名配置
每个微信小程序需要事先设置一个通讯域名,小程序可以跟指定的域名与进行网络通信。
包括普通 HTTPS 请求(request
)、上传文件(uploadFile
)、下载文件(downloadFile
) 和 WebSocket 通信(connectSocket
)
配置流程
服务器域名请在 小程序后台-设置-开发设置-服务器域名
中进行配置,配置时需要注意:
- 域名只支持
https
(request
、uploadFile
、downloadFile
) 和wss
(connectSocket
) 协议; - 域名不能使用 IP 地址或 localhost
- 域名必须经过 ICP 备案;
- 出于安全考虑,
api.weixin.qq.com
不能被配置为服务器域名,相关API也不能在小程序内调用。开发者应将 appsecret 保存到后台服务器中,通过服务器使用 appsecret 获取 accesstoken,并调用相关 API。 - 对于每个接口,分别可以配置最多 20 个域名
添加将要请求的合法的服务器域名
HTTPS 证书
小程序必须使用 HTTPS 请求。小程序内会对服务器域名使用的 HTTPS 证书进行校验,如果校验失败,则请求不能成功发起。
由于系统限制,不同平台对于证书要求的严格程度不同。
为了保证小程序的兼容性,建议开发者按照最高标准进行证书配置,并使用相关工具检查现有证书是否符合要求。
对证书要求如下:
- HTTPS 证书必须有效。证书必须被系统信任,部署SSL证书的网站域名必须与证书颁发的域名一致,证书必须在有效期内;
iOS
不支持自签名证书;iOS
下证书必须满足苹果 App Transport Security (ATS) 的要求;- TLS 必须支持 1.2 及以上版本。部分旧
Android
机型还未支持 TLS 1.2,请确保 HTTPS 服务器的 TLS 版本支持1.2及以下版本; - 部分 CA 可能不被操作系统信任,请开发者在选择证书时注意小程序和各系统的相关通告。
- Chrome 56/57 内核对 WoSign、StartCom 证书限制周知
跳过域名校验
在微信开发者工具中,可以临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书
选项,跳过服务器域名的校验。
此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
在服务器域名配置成功后,建议开发者关闭此选项进行开发,并在各平台下进行测试,以确认服务器域名配置正确。
如果手机上出现 “打开调试模式可以发出请求,关闭调试模式无法发出请求” 的现象,请确认是否跳过了域名校验,并确认服务器域名和证书配置是否正确。
2. 关于请求
- 默认超时时间和最大超时时间都是 60s
request
、uploadFile
、downloadFile
的最大并发限制是 10 个- 网络请求的
referer
header 不可设置。其格式固定为https://servicewechat.com/{appid}/{version}/page-frame.html
,其中{appid}
为小程序的 appid,{version}
为小程序的版本号,版本号为0
表示为开发版、体验版以及审核版本,版本号为devtools
表示为开发者工具,其余为正式版本。 - 小程序进入后台运行后(非置顶聊天),如果 5s 内网络请求没有结束,会回调错误信息
fail interrupted
;在回到前台之前,网络请求接口调用都会无法调用。
3. 关于服务器返回
返回值编码
- 建议服务器返回值使用 UTF-8 编码。对于非 UTF-8 编码,小程序会尝试进行转换,但是会有转换失败的可能。
- 小程序会自动对 BOM 头进行过滤。
回调
- 只要成功接收到服务器返回,无论statusCode是多少,都会进入success回调。请开发者根据业务逻辑对返回值进行判断。
wx.request(OBJECT)
发起网络请求。使用前请先阅读上面的说明。
OBJECT参数说明:
参数名 | 类型 | 必填 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|---|
url | String | 是 | 开发者服务器接口地址 | ||
data | Object/String/ArrayBuffer | 否 | 请求的参数 | ||
header | Object | 否 | 设置请求的 header,header 中不能设置 Referer。 | ||
method | String | 否 | GET | (需大写)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT | |
dataType | String | 否 | json | 如果设为json,会尝试对返回的数据做一次 JSON.parse | |
responseType | String | 否 | text | 设置响应的数据类型。合法值:text、arraybuffer | 1.7.0 |
success | Function | 否 | 收到开发者服务成功返回的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success返回参数说明:
参数 | 类型 | 说明 | 最低版本 |
---|---|---|---|
data | Object/String/ArrayBuffer | 开发者服务器返回的数据 | |
statusCode | Number | 开发者服务器返回的 HTTP 状态码 | |
header | Object | 开发者服务器返回的 HTTP Response Header | 1.2.0 |
data 数据说明:
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。
转换规则如下:
- 对于
GET
方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...) - 对于
POST
方法且header['content-type']
为application/json
的数据,会对数据进行 JSON 序列化 - 对于
POST
方法且header['content-type']
为application/x-www-form-urlencoded
的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)
示例代码:
wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
girlName: '面码' ,
age: 15
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
console.log(res.data)
}
})
返回值:
基础库 1.4.0 开始支持,低版本需做兼容处理
返回一个 requestTask
对象,
通过 requestTask
,可中断请求任务。
requestTask 对象的方法列表:
方法 | 参数 | 说明 | 最低版本 |
---|---|---|---|
abort | 中断请求任务 | 1.4.0 |
示例代码:
const requestTask = wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
girlName: '面码' ,
girlAge:
15
},
header: {
'content-type': 'application/json'
},
success: function(res) {
console.log(res.data)
}
})
requestTask.abort() // 取消请求任务
Bug & Tip
tip
: content-type 默认为 'application/json';bug
: 开发者工具0.10.102800
版本,header
的content-type
设置异常;
示例代码如下:
/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.testRequest() }, testRequest(){ console.log('开始请求') wx.request({ url: 'https://locally.uieee.com/slides', header: {}, // 必须大写 method: "GET", dataType: "json", success: function(response){ console.log(response) }, }) }
输出结果如下:
在IDE右上角-->详情菜单--->勾选不校验域名合法性之后
输入结果如下:
当请求回来数据后,在success方法中可以使用箭头函数(因为箭头函数内部的this是其父作用域的this)
或者,先在外部 使用一个that 接收一下this, 然后在success的block内部使用that
必须使用this.setData({ arr: response.data }})方法,进行赋值,这样才能更新数据与视图(MVVM)
示例代码如下:
//index.js //获取应用实例 const app = getApp() Page({ data: { // 驱动视图的ViewModel数据 headImgArr: [] }, //事件处理函数 onLoad: function () { console.log() // wx.navigateTo({ // url: '../anime/anime', // }) this.testRequest() }, testRequest() { console.log('开始请求') wx.request({ url: 'https://locally.uieee.com/slides', header: {}, // 必须大写 method: "GET", dataType: "json", // 不用箭头函数的话, 也可以先用that 接收一下 this // 然后在success的回调内部使用that也是一样的 // const that = this success: (response) => { console.log(response) this.setData({ headImgArr: response.data }) }, }) } })
然后就可以在index.wxml中使用驱动视图的数据ViewModel了
如下所示:
<!--index.wxml--> <view class='class_view_carousel'> <!-- 就像checked属性一样 后面的 {{true}}也可以不写 --> <swiper indicator-dots='{{ true }}' autoplay='{{ true }}' interval='2500' duration='500' circular='{{ true }}'> <swiper-item> <!-- <image src='/img/menma.jpg'></image> --> <image src='{{headImgArr[0].image}}'></image> </swiper-item> <swiper-item> <!-- <image src='/img/tiger.jpg'></image> --> <image src='{{headImgArr[1].image}}'></image> </swiper-item> </swiper> </view>
效果如下:
列表渲染可以简写成循环的形式:
列表渲染
wx:for
在组件上使用 wx:for
控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的 下标变量名默认为 index
,数组当前项的变量名默认为 item
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [{
message: 'hello ',
}, {
message: 'beyond'
}]
}
})
使用 wx:for-item
可以指定数组当前元素的变量名,
使用 wx:for-index
可以指定数组当前下标的变量名:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="girl">
{{idx}}: {{girl.name}}
</view>
wx:for
也可以嵌套,下边是一个九九乘法表
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
block wx:for
类似 block wx:if
,也可以将 wx:for
用在<block/>
标签上,以渲染一个包含多节点的结构块。
例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,
并且希望列表中的项目保持自己的特征和状态(如 <input/>
中的输入内容,<switch/>
的选中状态),
需要使用 wx:key
来指定列表中项目的唯一的标识符。
wx:key
的值以两种形式提供(推荐使用 *this )
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字
*this
代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,
而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key
,会报一个 warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
示例代码:
在开发者工具中预览效果
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
<button bindtap="switch"> Switch </button>
<button bindtap="addToFront"> Add to the front </button>
<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
<button bindtap="addNumberToFront"> Add to the front </button>
Page({
data: {
objectArray: [
{id: 5, unique: 'unique_5'},
{id: 4, unique: 'unique_4'},
{id: 3, unique: 'unique_3'},
{id: 2, unique: 'unique_2'},
{id: 1, unique: 'unique_1'},
{id: 0, unique: 'unique_0'},
],
numberArray: [1, 2, 3, 4]
},
switch: function(e) {
const length = this.data.objectArray.length
for (let i = 0; i < length; ++i) {
const x = Math.floor(Math.random() * length)
const y = Math.floor(Math.random() * length)
const temp = this.data.objectArray[x]
this.data.objectArray[x] = this.data.objectArray[y]
this.data.objectArray[y] = temp
}
this.setData({
objectArray: this.data.objectArray
})
},
addToFront: function(e) {
const length = this.data.objectArray.length
this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)
this.setData({
objectArray: this.data.objectArray
})
},
addNumberToFront: function(e){
this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray)
this.setData({
numberArray: this.data.numberArray
})
}
})
注意:
当 wx:for
的值为字符串时,会将字符串解析成字符串数组
<view wx:for="array">
{{item}}
</view>
等同于
<view wx:for="{{['a','r','r','a','y']}}">
{{item}}
</view>
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
等同于
<view wx:for="{{[1,2,3] + ' '}}" >
{{item}}
</view>
示例代码如下: (注意: wx:key="*this")
<view wx:key="*this" class='class_item' wx:for="{{englishArr}}" wx:for-index="index" wx:for-item="english"> <image id="{{english.id + '_' + english.title}}" bindtap="showDetailFunction" class='class_img' src='/imgs/{{english.id<501?1:english.id<1001?2:english.id<1501?3:english.id<2001?4:5}}/{{english.id}}.png' mode="widthFix"> </image> </view>
效果如下:
又比如在onLoad方法中请求数据:
视图中的循环代码如下:
运行效果如下:
接下来请求列表的数据:
如果列表页面, 标题太长的话, 需要让其在固定的宽度内,多出的部分用省略号表示:
四句核心代码:
1. 限制宽度 width: 380rpx;
2. 超出宽度部分隐藏 overflow: hidden;
3. 不折行(貌似可以不写) white-space: nowrap;
4. 设置省略号 text-overflow: ellipsis;
绑定ViewModel的代码如下:
其中小星星的数据80%, 这个80直接使用从网络接口获取的列表中的数据
效果如下:
重要内容:
每一个页面在onLoad时,可以传递一些初始化参数给onLoad(options)方法
比如:
输出结果如下:
因此, 我们在首页index.wxml中,就可以通过参数传递初始化数据了
这样一来, 进入不同的子页面,在其onLoad方法中,就可以拿到不同的初始化数据了
例如:
再比如:
从首页跳转到englishlist页面时,
传递初始化参数给englishlist页面的onLoad方法
在跳转的目标页面englishlist的onLoad方法中,输出结果如下:
播放背景音乐(虽然已经弃用,但是很好用):
// 播放音频asdf wx.playBackgroundAudio({ dataUrl: 'http://cn18x.com/music/start.mp3', title: '', coverImgUrl: '' })
小程序的生命周期问题:
个文档中,有一部分专门描述楼主的问题的:
https://mp.weixin.qq.com/debug/wxadoc/dev/framework/app-service/app.html
onShow Function 生命周期函数--监听小程序显示 当小程序启动,或从后台进入前台显示,会触发 onShow
onHide Function 生命周期函数--监听小程序隐藏 当小程序从前台进入后台,会触发 onHide
前台、后台定义: 当用户点击左上角关闭,或者按了设备 Home 键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。
只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。
我截取了一篇文章关于生命周期部分的描述:楼主有兴趣可以看看本站其他关于生命周期的文章:
一个page的生命周期从onLoad开始,整个生命周期内onLoad、onReady、onUnload这三个事件仅执行一次,
而onHide和onShow在每次页面隐藏和显示时都会触发。
当用户手动触发左上角的退出箭头时,小程序仅触发app.onHide,
下次进入小程序时会触发app.onShow以及当前page.onShow。
仅当小程序在后台运行超过一定时间未被唤起、
或者用户手动在小程序的控制栏里点击退出程序、或者小程序内存占用过大被关闭时,
小程序被销毁,会触发app.onUnload事件。
1、前台、后台定义:
当用户点击左上角关闭,或者按了设备Home 键离开微信,小程序并没有直接销毁,而是进入了后台;
当再次进入微信或再次打开小程序,又会从后台进入前台,
只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。
2、App() 必须在 app.js 中注册,且不能注册多个。
不要在定义于 App() 内的函数中调用 getApp() ,使用 this 即可拿到 app 实例。
不要在 onLaunch 的时候调用 getCurrentPage(),此时 page 还没有生成。
通过 getApp() 获取实例之后,不要私自调用生命周期函数。
在onLoad方法中,根据参数options中传递过来的文本,
动态设定导航栏的的标题
代码如下:
核心代码:
url="/pages/shopList/shopList?category='{{item.id}}'&title={{item.name}}"
核心代码:
wx.setNavigationBarTitle({
title: options.title
})
wx.setTopBarText(OBJECT)
基础库 1.4.3 开始支持,低版本需做兼容处理
动态设置置顶栏文字内容,只有当前小程序被置顶时能生效,
如果当前小程序没有被置顶,也能调用成功,但是不会立即生效,
只有在用户将这个小程序置顶后才换上设置的文字内容。
注意:调用成功后,需间隔 5s 才能再次调用此接口,
如果在 5s 内再次调用此接口,会回调 fail,errMsg:"setTopBarText: fail invoke too frequently"
OBJECT参数说明:
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
text | String | 是 | 置顶栏文字内容 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码:
wx.setTopBarText({
text: 'hello, world!'
})
wx.setNavigationBarTitle(OBJECT)
动态设置当前页面的标题。
OBJECT参数说明:
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
title | String | 是 | 页面标题 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码:
wx.setNavigationBarTitle({
title: '动漫列表'
})
wx.showNavigationBarLoading()
在当前页面 显示导航条加载动画。
wx.hideNavigationBarLoading()
隐藏导航条加载动画。
使用纯css实现一个加载中的效果
(推荐一个: https://github.com/ConnorAtherton/loaders.css )
代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> .loadmore { color: #888; font-size:30px; line-height: 100px; text-align: center; } /* 图标 */ .loadmore.loading::before { content: ''; width: 40px; height: 40px; /*background-color: blue;*/ margin-top: -10px; margin-right: 10px; display: inline-block; vertical-align: middle; animation: loading 1s steps(12) infinite; background: transparent url(data:image/png;base64,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) no-repeat; background-size: 100%; } /* 定义动画 */ @keyframes loading { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } } </style> </head> <body> <div class="loadmore loading"> 加载中... </div> </body> </html>
效果如下:
移植到小程序的公共样式文件中,
代码如下:
/* ============================== */ .class_loadmore { color: #888; font-size:16px; line-height: 100rpx; text-align: center; } /* 图标 */ .class_loadmore.class_loading::before { content: ''; width: 40rpx; height: 40rpx; /*background-color: blue;*/ margin-top: -10rpx; margin-right: 10rpx; display: inline-block; vertical-align: middle; animation: loading 1s steps(12) infinite; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAK1UlEQVR4Xu1be5CcRRHv/nbvNvE0gI8YQpLL7U5PDqKAUAhIlSAqKiIiaPFSUFMIFq8QRCmgQngZBJRHKQRQwQJBfKECiuADfAKlPIxBbmZ2NyERMEEwCcbkdu9rq89vt7777tv9vn1kE6uY/3ZnprvnNz09Pd39IWyDNjIy8kZEvA4RD2bmPkR8MJfLLZozZ85zvRYHe81w7dq1r12/fv0TAKDCvJm5RETDiFjppUw9B8A5dxIz39RgkQuI6Jv/VwBYa3PMvGulUnl6/vz5o0nCW2uvBoCFceOY+Uat9SlJNLrZ35EGGGOOQ8TrAWAHANgMALeMjo4ubAaEtVbGf7YBALdqrT+VtMByuTxcrVavAYDp2Wz2yKGhoZVJcxr1tw2Ac04M2C8AIErjDiI6vhHDTgFg5oxz7pmQDfk1ER3ccwCMMfch4qENdvJArfVv4vo6BcAYcyYiyu6PN2Z+Smu9Z88BsNb+AQD2b8D4aaXU7og4Fu3vBIBVq1bttGXLllWI+LoQ3Y4MZ9tHwFp7OQB8oQnypxHR17oJgHPuBmauG0lmfpKI9kJE7rkGrFy5cudKpVIGgFwD5i/39/cXBgcHXw73t6sB1trdAOCvYZvDzPtprR9td/Eyr20NkMnW2iUAcGEjAZj5Oq31md0AwBjzMCK+M3T279RaH9fJ4rsBgPgAZUTcuYEgY4g4rJRytf52NMAYcxQifj/EY0tfX9/Q3Llzn9+mAAhz59wxzHxnEy14UGt9SLsAiKMFAAYA5oR4XEhEF3e6+I41oCaAMeZRRHx7I4E8zzusUCjcFxyblhwh59z5zHxpSPWfR8QhItqy1QAwxuQR8Rj8X3sin8/fj4h+I4bGmD0R8fEmNsUppXaTh44x5gJEvKQBrS8S0fm1vsDQyvF5TWj80UT03W4sPlYDrLX7M7MYnL4QkxXMvKCZxbXWfgMAPt1IMEQ8Vin1HefcAcz8uwbjDiKih0PH5TYA+Hho9x/TWu/byuJLpdLg2NiYgDoDEReF7VEjAJYDwFsaMPl2QGRttN9a+yZmLkaclPCw64noVPnDGHOHABLqFO26gIiWho7Vvoj4SGgMM/NeWusn0wDwwgsvDGzcuPE8ADg7dFWvJqKwLZl4DQaTXmnGgJk3ep53caFQuAYRq+GxxphzEPGKuPnMfJnW+gLpY2Z0zi1g5ncj4suZTGZZPp//S3ietVaexeGH0c1E9JmkxQe0j2fmK2JuJ0NE88I0JvkB1tp/Ba+7JF4WAE4Kq6xEd6y1TyHiruHJAlp/f/+8Vq4ta+3tADD+qJL5iFggonXNhHLO7S1PagDYO2bcJgA4NCxv7BEwxlyKiHVDlIQCM/8AERcS0RoZWy6X51YqlbtCt4Ici6OVUn9OohXuL5VK88bGxh5g5qzneQuUUvc3ml8ul2dUKpWliHhinCGWa7q/v//suA2I9QSdc5/zfX8JIg6kFFpiAUuUUqJ2claxWCy+w/f9l7TWf0tJo+VhK1as6O/r65PgyuI4WeWlCAAnNzPeDV1hQbVarV4WnMNULjMzX6m1/nzLK2ljgrX2cGa+GhHzMdP/AQDnKaVuSXooJS6sVCrtMTY2Jq+6A1LIuUkpNS3uGZxibqohzrnpzCzXY927rE1kZgnJXTtt2rSLZsyY8e80BBMBqBFxzn3E9/2rGiBe55XNZncaGhoSQ7pVmrX2RwDw4Rji9zDzQq11qRXGqQEQonLmcrncGb7vy5kLByXqOBERtSJAq2OttT8DgPeHdv2ZTCZzWqFQ+GWrtGJvgTRExOlBxIuZWe5lL5gjL7+PKqVkh7Zas9bOZ+bvIeIMZl4iQZdOjlxLGhBdVbFYfKvv+0cxszhE96b10rYaOm0Q7giANvhtd1NeBUD8/w0bNogXdQQAzG5hi8ThWe553llKqV+1MG+7GiqPkmuYeULcrkUJfUR8b69BEEMMADcDwI4tylu/sbLZ7FVorV0NALPaJFKbdjsRfaJDGi1NT4o/pCT2uADwbIuqH0f7NiI6ISXTrgwzxtwaPH46oVcUAJqGttNQR8QjlVJ3pxnbrTFBnuDrTbJTSazceNhPRgVxupMikdckAuNGEABu0FovSxq8vfa/eg1urzvTK7k61oBisUi+7+8yderU5bNmzfpnrwTvFp+2AQjiBNcCwIEiDDO/goiHENEfuyVcHJ3Vq1e/fvPmzacDQD6bzS4dGhqSYom2W8sABJEiydRIDmDCfGYe0VoPty1NionW2h8DwOHBUKk/WOZ53vmFQmF9iumThqQGoFwuT6lWq4uY+byEWOH0pOhtO4LW5sSl4Zj5JURcrJRa1urTOBUAQQL0yhQe4/rR0dHpaarF2gXBWnsQAIjPMckFZuZnEPGUaOi7Ga+mAEic3fd9CTgkpqMkHpfJZI6sJUHbXWCaeVJpmslkLokEZOpTmfnubDZ7Vj6fX5VELxYAa628DaQERgoQErWEme/NZDKLCoWCJEt61iQ6BACSCIkL2Er2+MsDAwOXzZw5U5IisW3S4pxzs5lZkhjy2kpqKzzPOzMajyuXyztWKhUJW71HDCMAnNhqKcuaNWvesGnTJgnLFzzPk5zD7xsJY639GAB8Je6IMvNziHiuUur2uBB5XGpM3vbvSlj5OmZeTEQ3xaXNrbU/j4St102ZMmVw9uzZ/0lCtNZvrZUUuCxMrtiK53n7N8suiZGuVCqSmzw3kk6vkXwkm80eGy2qjANA1GVqnKC1uLvv+5cMDw9vjBtjrf0QAPwk2ud5ng4fkWKxeKjv++cAQAkRl0bT1saYxxBxnxodZk6VGpfjGyRGw9nnGpmHiGjC5k4CwBgjyc3dowtg5h8CwDnN4u4xVZzjZJj5RSKS/Px43WCpVHpztVp9FhH7g/6XcrmcCleUOedOlyKrsBzyelNK3ZVGi4wxYrhvRMQ9QuOXE9GEtcVpwH4AICo8LRDuKc/zTm12BmsMolWctf8R8XSl1Fdrv51zH2Dmn0YWN+FJLZlm55wY1cGQFrRUHsPMnnNOUuxiSyR/eQwRhWsO4i18sVjcwff9PT3P25TP5/+UlF8TARtUcUqXlMfIdwD1qlHn3BFyVYUBYObjtdZ3hP+LGydled0qkBJeiVdcGnWTMcaYaxHxjJiz/8FCoTBht9MCILSstQ/V3hsB7a6VyHUNAOecEi8MADIRAB4govdFQWkRgEkVogDQtCI97aZ1DQBjzD2IeFiE8aQiyZANSHUEQrZF0tyfjByZjstkuwKAtVaew6Km0VYviupEA4JjIE6ZfBRRL5eTQmmt9dta2e24sR3ZgKAgSQqYRU3rTWp6crncYLRQul0NCEBYDAAXhfmIViilvtUJCB0BYIw5GRHjAqJnE5G4prGtFRtQIxB8myRO08wQ0XUDAwNzm/n6SeC0DYDsvrX27zGlaKuUUtTs87d2AJCFOOdOYOboji8lIqkHbKu1DUBQgRn3sdIRRCRRm4atXQCCoyAlufWzL48drfUuba2+Ez8gqNBaGdGAh4lIAhZNW4cAiKdajzsy82+11vXvCJJ4R/vb1gAhVCwW9/F9X94I8gB5lJkPmzdv3otJQnQCQKAFUnIrH2pIcuagTkrxOgIgaaHdNILt8kqat00AkBo/AJhgJ2rV5EkCd7t/mwAwMjKyCyLKlTb+HA7aXkQkH1X3tG0TAIJzLJWeX5JviiScRURS1t7z9l/p/GnjEIIGeQAAAABJRU5ErkJggg==) no-repeat; background-size: 100%; } /* 定义动画 */ @keyframes loading { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } }
<!-- 加载更多 --> <view class="class_loadmore class_loading"> 加载中... </view>
效果如下:
小程序上传:
如果是第二次提交审核通过后,
再进行发布的时候,会有如下提示:
未完待续,下一章节,つづく