1.scroll-view 横向不滚动
2.js 中方法之间一定要加上 ','
3.scroll-view 两个方法bindscrolltoupper、bindscrolltolower 调用问题
4.下拉刷新是显示导航条动画和刷新动画
5.主动触发刷新操作
6.播放音频的方法
7.播放视频
8.网络请求
9.wx.api回调方法中使用 this.setData({}),提示this.setData is not a function
10.上传
11.同步、异步、保存、读取数据
12.当前位置、选择位置、查看某一个位置
13.显示tabbar
14.wx.reLaunch 和 wx.redirectTo
15.动画
16.page生命周期
17.app.json 配置项列表
18.页面正向传值
19.页面反向传值,主要使用的是getCurrentPages()
20.页面内部传值 (data-{key}="{value}")
21.页面内部传值另一种方法, 设置 id = {}
22.关于form bindsubmit 的传值
23.wx:for wx:if
24.wxs
25.自定义组件
26.自定义js文件
27.page调用自定义组件内部方法
28.setInterval、setTimeout
1.scroll-view 横向不滚动
/*
normal: 正常无变化(默认处理方式.文本自动处理换行.假如抵达容器边界内容会转到下一行;
pre: 保持HTML源代码的空格与换行,等同与pre标签;
nowrap: 强制文本在一行,除非遇到br换行标签;
*/
.scrollView {
width: 100%;
height: 200px;
background-color: blue;
margin-top: 20px;
overflow: hidden; // 设置1
white-space: nowrap;// 设置2
}
.subView {
width: 100%;
height: 200px;
background-color: yellow;
display: inline-block; // 设置3
}
2.js 中方法之间一定要加上 ','😢
onShareAppMessage: function () {
}, // 重中之重
upper: function (e){
console.log('scrolltoupper',e);
}
3.scroll-view 两个方法bindscrolltoupper、bindscrolltolower 调用问题
在默认或设置的 upper-threshold、lower-threshold 的范围内,慢慢的拖动scroll-view,upper和lower 会一直触发,所以不推荐使用这两个方法进行下拉刷新、上拉加载操作
<scroll-view class='scrollViewClass'
scroll-y
bindscrolltoupper='upper'
bindscrolltolower='lower'
>
4.下拉刷新是显示导航条动画和刷新动画
onPullDownRefresh: function (){
console.log('onPullDownRefresh')
wx.showNavigationBarLoading() // 显示导航条动画
//模拟加载
setTimeout(function () {
// complete
wx.hideNavigationBarLoading() //停止导航条动画
wx.stopPullDownRefresh() //停止下拉刷新
}, 1500);
},
"enablePullDownRefresh": true, // 允许刷新
"backgroundColor": "#f0145a", // 背景颜色,下拉时可以看见
"backgroundTextStyle": "dark", // 下拉背景字体、loading 图的样式,仅支持 dark/light,默认light不可见
5.主动触发刷新操作
wx.startPullDownRefresh({
success: function () {
console.log('startPullDownRefreshSuccess')
},
fail: function () {
}
})
6.播放音频的方法
- 带有界面的,使用 audio
<audio id='myaudio'
src='http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E06DCBDC9AB7C49FD713D632D313AC4858BACB8DDD29067D3C601481D36E62053BF8DFEAF74C0A5CCFADD6471160CAF3E6A&fromtag=46'
loop
controls poster='http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000'
name='此时此刻'
author='许巍' >
</audio>
onReady: function () {
// 创建上下文
this.audio = wx.createAudioContext('myaudio', this)
},
this.audio.play();
this.audio.pause();
this.audio.seek(14);
- 不带界面的,适合播放背景音乐(也可以使用wx.getBackgroundAudioManager())
const innerAudioContext = wx.createInnerAudioContext()
innerAudioContext.autoplay = true
innerAudioContext.src = 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E061FF02C31F716658E5C81F5594D561F2E88B854E81CAAB7806D5E4F103E55D33C16F3FAC506D1AB172DE8600B37E43FAD&fromtag=46'
innerAudioContext.onPlay(() => {
console.log('开始播放')
})
innerAudioContext.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
})
// 在其他的方法里面可以使用 this.innerAudioContext控制音频的播放状态
this.innerAudioContext = innerAudioContext;
// 在不需要播放的时候 destroy
// this.innerAudioContext. destroy();
this.innerAudioContext.play();
this.innerAudioContext.pause();
this.innerAudioContext.seek(14);
7.播放视频
<video id="myVideo"
src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400"
danmu-list="{{danmuList}}"
enable-danmu
danmu-btn
controls>
</video>
<view>
<input bindblur="bindInputBlur"/>
<button bindtap="bindSendDanmu">发送弹幕</button>
<button type='primary' bindtap='play'>开始</button>
<button type='primary' bindtap='pause'>暂停</button>
<button type='primary' bindtap='video50'>设置播放时间到14秒</button>
<button type='primary' bindtap='videoRate'>设置倍速</button>
</view>
data: {
inputValue: '',
danmuList: [
{
text: '第 1s 出现的弹幕',
color: '#ff0000',
time: 1
},
{
text: '第 3s 出现的弹幕',
color: '#ff00ff',
time: 3
}]
},
onReady: function () {
this.videoContext = wx.createVideoContext('myVideo', this)
},
bindInputBlur: function (e) {
this.inputValue = e.detail.value
},
// 发送弹幕
bindSendDanmu: function () {
this.videoContext.sendDanmu({
text: this.inputValue,
color: getRandomColor()
})
},
play: function () {
this.videoContext.play();
},
pause: function () {
this.videoContext.pause();
},
video50: function () {
this.videoContext.seek(50);
},
videoRate: function () {
this.videoContext.playbackRate(1.5);
},
8.网络请求
request: function (){
const requestTask = wx.request({
url: 'http://baobab.kaiyanapp.com/api/v1/feed',
data:{
'num': 1
},
header:{
'type': 'application/json'
},
method: 'POST',
success: function(result){
// 需根据返回的状态码自行判断是否请求成功 200、400、500、504等等
console.log('成功', result)
},
fail: function(error){
console.log('失败',error)
},
complete: function(){
console.log('完成')
}
});
// 中断请求任务
// requestTask.abort();
}
9.wx.api回调方法中使用 this.setData({}),提示this.setData is not a function
❗️方法体外部定义 var that = this;
❗️方法体内部使用that.setData({})
var that = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
that.setData({
tempFilePaths: res.tempFilePaths
});
console.log('成功', res)
}
})
10.上传
upload: function () {
var that = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
that.setData({
tempFilePaths: res.tempFilePaths
})
console.log('成功', res)
that.upload1(res.tempFilePaths[0])
}
})
},
upload1: function (filePath){
const uploadTask = wx.uploadFile({
url: 'http:...',
filePath: filePath,
name: 'image',
header: {
'type': 'multipart/form-data'
},
formData: {
'photo': '参数1',
'phoneNum': '参数2',
},
success: function (result) {
console.log('成功', result)
},
fail: function (error) {
console.log('失败', error)
},
complete: function (res) {
console.log('完成')
},
})
// 上传进度
uploadTask.onProgressUpdate((res)=>{
console.log('onProgressUpdate',res)
console.log('上传百分比:', res.progress+'%')
})
// uploadTask.abort() // 取消上传任务
}
11.同步、异步、保存、读取数据
wx.setStorage({
key: 'key1',
data: 'value1',
success: function(res) {
console.log('异步保存数据成功')
},
fail: function(res) {},
complete: function(res) {},
})
try{
wx.setStorageSync('key2', 'value2')
}catch(e){
}
console.log('同步保存数据成功')
wx.getStorage({
key: 'key1',
success: function(res) {
console.log('异步获取数据成功:',res)
},
fail: function(res) {},
complete: function(res) {},
})
var value = wx.getStorageSync('key2')
console.log('同步获取数据成功:',value)
12.当前位置、选择位置、查看某一个位置
// 当前位置(经纬度、速度、精度、高度)
wx.getLocation({
type: 'wsg84',
altitude: true,
success: function(res) {
console.log('获取当前位置成功',res)
},
fail: function(res) {},
complete: function(res) {},
})
// 选择位置,弹出地图界面(模糊搜索、拖动地图选择位置、当前位置附近的建筑)
wx.chooseLocation({
success: function(res) {
console.log('选择当前位置成功', res)
},
fail: function(res) {},
complete: function(res) {},
})
//使用微信内置地图查看位置
wx.openLocation({
latitude: 39.965985,
longitude: 116.289073,
scale: 12,
name: '火器营[地铁站]',
address: '北京市海淀区地铁10号线',
success: function(res) {},
fail: function(res) {},
complete: function(res) {},
})
13.显示tabbar
// 所有的页面都要在pages里面进行注册
"pages":[
"pages/index/index",
"pages/apiTest/apiTest"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#f0145a",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black"
},
"tabBar": {
"color": "#000000",
"selectedColor": "red",
"borderStyle": "black",
"backgroundColor": "white",
"list": [
{
"pagePath": "pages/index/index",
"text": "tab2",
"iconPath": "iconPath",
"selectedIconPath": "selectedIconPath"
},
{
"pagePath": "pages/apiTest/apiTest",
"text": "tab1",
"iconPath": "iconPath",
"selectedIconPath": "selectedIconPath"
}
]
}
14. wx.reLaunch 和 wx.redirectTo
❗️wx.reLaunch:关闭所有页面,打开到应用内的某个页面,无法返回
❗️wx.redirectTo:关闭当前页面,跳转到应用内的某个页面,可以返回
15.动画
<view class='view' animation='{{animation}}' bindlongpress='longTag'></view>
animal:function (){
// ❗️1.创建一个动画实例animation
/**
linear 动画从头到尾的速度是相同的
ease 动画以低速开始,然后加快,在结束前变慢
ease-in 动画以低速开始
ease-in-out 动画以低速开始和结束
ease-out 动画以低速结束
step-start 动画第一帧就跳至结束状态直到结束
step-end 动画一直保持开始状态,最后一帧跳到结束状态
*/
const animation = wx.createAnimation({
duration: 1000,
timingFunction: 'ease',
})
// ❗️2.调用实例的方法来描述动画
/**
* 样式
opacity value 透明度,参数范围 0~1
backgroundColor color 颜色值
width length 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
height length 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
top length 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
left length 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
bottom length 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
right length 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
*/
/**
* 旋转
rotate deg deg的范围-180~180,从原点顺时针旋转一个deg角度
rotateX deg deg的范围-180~180,在X轴旋转一个deg角度
rotateY deg deg的范围-180~180,在Y轴旋转一个deg角度
rotateZ deg deg的范围-180~180,在Z轴旋转一个deg角度
rotate3d (x,y,z,deg) 同transform-function rotate3d
*/
/**
* 缩放
scale sx,[sy] 一个参数时,表示在X轴、Y轴同时缩放sx倍数;两个参数时表示在X轴缩放sx倍数,在Y轴缩放sy倍数
scaleX sx 在X轴缩放sx倍数
scaleY sy 在Y轴缩放sy倍数
scaleZ sz 在Z轴缩放sy倍数
scale3d (sx,sy,sz) 在X轴缩放sx倍数,在Y轴缩放sy倍数,在Z轴缩放sz倍数
*/
/**
* 偏移
translate tx,[ty] 一个参数时,表示在X轴偏移tx,单位px;两个参数时,表示在X轴偏移tx,在Y轴偏移ty,单位px。
translateX tx 在X轴偏移tx,单位px
translateY ty 在Y轴偏移tx,单位px
translateZ tz 在Z轴偏移tx,单位px
translate3d (tx,ty,tz) 在X轴偏移tx,在Y轴偏移ty,在Z轴偏移tz,单位px
*/
/**
* 倾斜
skew ax,[ay] 参数范围-180~180;一个参数时,Y轴坐标不变,X轴坐标延顺时针倾斜ax度;两个参数时,分别在X轴倾斜ax度,在Y轴倾斜ay度
skewX ax 参数范围-180~180;Y轴坐标不变,X轴坐标延顺时针倾斜ax度
skewY ay 参数范围-180~180;X轴坐标不变,Y轴坐标延顺时针倾斜ay度
*/
/**
* 矩阵变形
matrix (a,b,c,d,tx,ty) 同transform-function matrix
matrix3d 同transform-function matrix3d
*/
animation.scale(2, 2)
.rotate(45)
.step() // ❗️step表示一组动画的完成,动画同时播放
// ❗️分开写则按顺序播放动画
animation.opacity(0.5)
.backgroundColor('blue').step()
// ❗️step 可以传入一个跟 wx.createAnimation() 一样的配置参数
// ❗️可以指定当前动画的配置属性
animation.width(200).step({ duration: 2000, timingFunction: 'linear'})
//❗️3.最后通过动画实例的export方法导出动画数据传递给组件的animation属性
this.setData({
animation: animation.export()
})
}
16.page生命周期
17.app.json 配置项列表
18.页面正向传值
// ❗️传object对象,将object转成字符串传递
var info = [{ id: '1', name: '饺子', price: '299元' },
{ id: '2', name: '面包', price: '99元' },
{ id: '3', name: '面条', price: '199元' },
{ id: '4', name: '馒头', price: '499元' },
{ id: '5', name: '热菜', price: '2999元' }]
或
var info = { id: '123', name: '饺子', price: '299元' }
wx.navigateTo({
url: '../viewTest/viewTest?goodInfo=' + JSON.stringify(info),
})
// ❗️传单个数据
wx.navigateTo({
url: '../viewTest/viewTest?goodInfo=' + 'beautiful',
})
onLoad: function (options) {
// ❗️将字符串转成object
var info = JSON.parse(options.goodInfo);
console.log('info:', info.id)
console.log('info:', info.name)
console.log('info:', info.price)
// ❗️单个value直接输出对应的key即可
console.log('info:',options.goodInfo)
},
19.页面反向传值,主要使用的是getCurrentPages()
❗️getCurrentPages()获取页面栈,第一个元素为首页,最后一个元素为当前页面
❗️var currentPage = arr[arr.length - 1],这个是获取的当前页面
❗️var upPage = arr[arr.length - 2],这个是获取的上一个页面
❗️使用 upPage 可以操作上一个页面内部的方法等,比如可以setData,可以调用page里面的方法
❗️反向传值就是使用的这种方法,调用setData
当前页面
var arr = getCurrentPages();
console.log('upPages路径:', arr[arr.length-2].route);
var upPage = arr[arr.length - 2]
// ❗️1.可以调用上一个页面的方法进行传值
upPage.nextPageCallingThisClick('哈哈,这是从下一个页面传过来的值')
// ❗️2.调用上一个页面的setData方法进行传值
wx.navigateBack({
success:function(){
upPage.setData({
nextComeValue: '这是从下一个页面传过来的值'
})
}
})
}
上一个页面
// ❗️onShow方法会被调用,进行赋值操作
onShow:function(){
console.log('nextComeValue1111111=',this.data.nextComeValue)
this.setData({
nextComeValue: this.data.nextComeValue
})
},
// ❗️下一个页面调用当前页面的方法进行传值
nextPageCallingThisClick:function(value){
console.log('nextPageCallingThisClick=', value)
this.setData({
nextComeValue1: value
})
}
20.页面内部传值 (data-{key}="{value}")
比如有好几个标签,通过wx:for 添加,点击标签获取标签的内容
click: function (e){
console.log(e)
console.log(e.currentTarget.dataset.price)
console.log(e.currentTarget.dataset.title)
}
21.页面内部传值另一种方法, 设置 id = {}
<text id='{{index}}' data-title='{{item.name}}' data-price='{{item.price}}' bindtap='click'>
// 根据得到的 id,去data里面找对应的具体数据
var id = e.currentTarget.id;
22.关于form bindsubmit 的传值
❗️form 的内部组件需要设置 name 属性
<input name='input' >
<slider name='slider'>
<switch name='switch' >
23.wx:for wx:if
<view wx:for="{{list}}" wx:item="item" wx:index="index">
<view class='subView' wx:if='{{item.price < 1000}}'>
<text id='{{index}}' data-title='{{item.name}}' data-price='{{item.price}}' bindtap='click'>{{index+1}}. {{item.name}} : {{item.price}}元</text>
</view>
<block wx:else>
<view class='subView' >
<text>大于1000元的食品</text>
<text id='{{index}}' data-title='{{item.name}}' data-price='{{item.price}}' bindtap='click'>{{index+1}}. {{item.name}} : {{item.price}}元</text>
</view>
</block>
</view>
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。
如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,
并在上边使用 wx:if 控制属性。
因为 wx:if 之中的模板也可能包含数据绑定,
所有当 wx:if 的条件值切换时,
框架有一个局部渲染的过程,
因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,
如果在初始渲染条件为 false,
框架什么也不做,
在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,
组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。
因此,如果需要频繁切换的情景下,用 hidden 更好,
如果在运行时条件不大可能改变则 wx:if 较好。
24.wxs
❗️WXS增强了wxml的功能,相当于页面中的脚本语言,
我们可以将比如检查手机格式、邮箱格式的函数放在wxs中来使用(根据是否正确来改变相应的样式),
而不用跑到在js中去检查。
❗️wxs目前似乎并不支持ES6(至少let不能使用)
❗️wxs文件不能被js文件引用。wxml文件能引用wxs文件。
wxs
var appent = function (value){
return value+'元'
}
var message = 'hello world'
module.exports = {
appent: appent,
message: message
}
wxml
<wxs src="./appentYuan.wxs" module="util" />
或者
<wxs module="m1">
var msg = "hello world";
module.exports.message = msg;
</wxs>
<view wx:for='{{prices}}'>
<text>{{util.appent(item)}}</text>
<view> {{m1.message}} </view>
</view>
比如:输入框里面要输入邮箱,正确的邮箱输入框颜色为绿色,不正确的邮箱输入框颜色为红色,就可以使用wxs来判断
// 正则来检验邮箱是否有效
var isEmail = function(email) {
var reg = getRegExp('^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
return reg.test(email)
}
module.exports = {
isEmail: isEmail
}
<wxs src="./inputValidate.wxs" module="util" />
// 这个应该放在 style 里面进行判断...
<input class="{{util.isEmail(email)?'email_input_success':'email_input_error'}}"
placeholder='请输入邮箱' value='{{email}}' bindinput='emailInputClick' />
25.自定义组件
26.自定义js文件
1.新建js文件
/**
* request 有一个参数 {}
*
* url: 网络请求地址
* data: 网络请求参数
* success: 网络请求成功回调
* fail: 网络请求失败回调
* complete: 网络请求完成回调
*
*/
const request = ({ url: url, data: data, success: success, fail: fail, complete: complete }) => {
const requestTask = wx.request({
url: url,
data: data,
header: {
'type': 'application/json'
},
method: 'POST',
success: function (result) {
// 需根据返回的状态码自行判断是否请求成功 200、400、500、504等等
console.log('http成功', result)
success()
},
fail: function (error) {
console.log('http失败', error)
fail()
},
complete: function () {
console.log('http完成')
complete()
}
});
}
module.exports = {
request: request
}
2.在需要的地方引用
❗️var httpRequest = require('../../utils/http.js')
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
console.log('onReady');
httpRequest.request({
url: 'http://',
data: {
'num': 1
},
success: (result) => {
console.log('成功', result)
},
fail: (error) => {
console.log('失败', error)
},
complete: () => {
console.log('完成')
}
})
},
27.page调用自定义组件内部方法
this.selectComponent("#componentID").componentFunc();
page
<questionItem id="questionItem" />
questionItem
<view animation='{{animation}}'>
...
</view>
showAnimation: function () {
...
}
调用
this.selectComponent("#questionItem").showAnimation();