小程序结构目录
小程序语法
导航栏标题文本
navigationBarTitleText
js语法
事件
bindtap 点击事
页面的初始化数据
data: {
msg:"初始化测试数据"
}
事件绑定
-
事件分类
-
冒泡事件
子节点向父节点传递的事件就是冒泡事件
-
非冒泡事件
表单事件和自定义事件通常是非冒泡事件
-
绑定事件
-
bind绑定:事件绑定不会阻止事件向上冒泡
bindtap
-
catch绑定:事件绑定可以阻止冒泡事件向上冒泡
catchtap
路由跳转
页面跳转,最多跳转十层
wx.navigateTo({
url: '/pages/logs/logs',
})
关闭当前页面,页面可以返回首页的跳转
wx.redirectTo({
url: '/pages/logs/logs',
})
关闭所有页面,跳转页面
wx.reLaunch({
url: '/pages/logs/logs',
})
生命周期
/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
// debugger
console.log("onLOad()");
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
// debugger
console.log("onReady()");
},
/**
* 生命周期函数--监听页面显示
*/
onShow:function () {
console.log("onShow() 执行多次");
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide:function () {
console.log("onHide()");
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload:function () {
console.log("onUnload()");
}
获取用户信息
<button bindgetuserinfo="handleGetUser" open-type="getUserInfo">获取用户信息</button>
js回调
/**
* 获取用户信息的回调
*/
handleGetUser(res) {
if(res.detail.userInfo){ //点击允许
// 修改userInfo的状态数据
this.setData({
userInfo:res.detail.userInfo
});
}else{ // 点击拒绝
console.log("拒绝");
}
},
// 显示头像
<image class="img" src="{{userInfo.avatarUrl}}"></image>
用户授权后再次登录保存登录信息
/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
// debugger
console.log("onLOad()");
// 授权以后获取用户信息
wx.getUserInfo({
// 登录成功
success: (res) => {
// 保存用户信息,不用再次授权
this.setData({
userInfo:res.userInfo
})
},
// 登录失败
fail: (err) => {
console.log(err);
}
})
},
条件渲染
// wx:if 如果后面的值为true,渲染,为false不渲染
// wx:else 相反
<image wx:if='{{userInfo.avatarUrl}}' class="img" src="{{userInfo.avatarUrl}}"></image>
<button wx:else bindgetuserinfo="handleGetUser" open-type="getUserInfo">获取用户信息</button>
音乐实战
轮播图
<swiper indicator-dots="true">
<swiper-item>
<image class="banners" src="/static/images/nvsheng.jpg"></image>
</swiper-item>
</swiper>
滑动区域
<scroll-view class="recommendScroll" enable-flex scroll-x="true">
<view class="scrollItem">
<image src="/static/images/nvsheng.jpg"></image>
<text>我喜欢贾静雯,贾静雯喜欢我,贾静雯喜欢倪马乐</text>
</view>
</scroll-view>
css
.recommendScroll {
display: flex;
}
一定要给scroll-view一个高度,不然就是纵向排列的高度(发轴)
多行文本隐藏 省略号代替
display: -webkit-box;
font-size: 26rpx;
-webkit-box-orient: vertical; /* 设置对齐样式 */
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
前后端交互
- 语法:wx.request()
- 协议必须是https协议
- 一个接口必须是20个域名
- 并发限制上线是10个
- 开发设置不校验合法域名:开发工具–>右上角详情—>本地设置—>不校验域名
封装功能函数
/utils/request.js
// 发送ajax请求
/**
* 1. 封装功能函数
* 1.功能点明确
* 2. 函数内部应该保留固定代码(静态的)
* 3. 将动态的数据抽取成形参,有使用者根据自身的情况动态的传入实参
* 4. 一个良好的功能函数应该设置形参的默认值(ES6的形参默认值)
* 2. 封装功能组件
* 1. 功能点明确
* 2. 组件内部保留静态的代码
* 3. 将动态的数据抽取成props参数,由使用者根据自身的情况以标签属性的形式动态出入props数据
* 4. 一个良好的组件应该设置组件的必要性及数据类型
*/
// 使用promise
export default (url, data = {}, method = "get") => {
return new Promise((resolve, reject) => {
wx.request({
url,
data,
method,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
reject(err)
}
})
})
}
// 发送请求
/pages/index/index.js
onLoad: async function (options) {
let result = await request("http://localhost:3000/banner", {
type: 2
});
console.log(result);
},
async 是异步函数,返回promise
await 是在async内部使用的,如果await是异步函数,async会停下等await执行成功,返回结果在继续执行
使用回调函数的形式
export default (url, data = {}, method = "get", fun) => {
// return new Promise((resolve, reject) => {
// wx.request({
// url: config.host + url,
// data,
// method,
// success: (res) => {
// resolve(res.data)
// },
// fail: (err) => {
// reject(err)
// }
// })
// })
wx.request({
url: config.host + url,
data,
method,
success: (res) => {
fun(res.data);
},
fail: () => {
}
})
}
request("/banner", {
type: 2
}, "get", function (data) {
console.log(data);
});
设备返回数据
0 电脑
1 安卓
2 苹果
3 ipad
微信循环列表渲染
<!-- 轮播图区域 -->
<swiper indicator-dots="true" indicator-color="ivory" indicator-color="#d43c33">
<swiper-item wx:for="{{bannerList}}" wx:key="bannerId">
<image class="banners" src="{{item.pic}}"></image>
</swiper-item>
</swiper>
wx:for 是连同自身一起循环,
wx:key 使用了diff算法
1. 使用对象中的唯一属性,只能是数字或者是字符串
2. 保留关键字 *this 代表for循环的item本身,标识item本身是一个唯一的字符串或数字
注意微信中的key不用加上点来引用
// 二位数组遍历的使用
使用wx:for-index 指定下标变量名
wx:for-item 指定元素变量
封装组件component
注册组件
/pages/index/index.json
{
"usingComponents": {
// 注册组件
"NavHeader":"/components/NavHeader/NavHeader"
}
}
设置默认值
/components/NavHeader/NavHeader.js
/**
* 组件的属性列表,等于Vue中的props
*/
properties: {
title:{
type:String,
value:'我是默认值'
},
nav:{
type:String,
value:"我是nav的默认值"
}
},
wxml 中使用 {{title}} {{nav}}
/pages/index/index.wxml
<NavHeader title="推荐歌曲" nav="为你精心推荐"></NavHeader>
内网穿透进行真机测试
使用utools进行内网穿透
// 配置服务器相关信息
export default {
host: 'http://localhost:3000',
mobieHost: 'https://flx123.cn.utools.club'
}
tabBar
"tabBar": {
"color": "#333",
"selectedColor": "#d43c33",
"backgroundColor": "#fff",
"position": "bottom",
"list": [{
"pagePath": "pages/index/index",
"text": "主页",
"iconPath": "/static/images/tabs/tab-home.png",
"selectedIconPath": "/static/images/tabs/tab-home-current.png"
},
{
"pagePath": "pages/video/video",
"text": "视频",
"iconPath": "/static/images/tabs/select.png",
"selectedIconPath": "/static/images/tabs/selected.png"
},
{
"pagePath": "pages/persoal/persoal",
"text": "个人中心",
"iconPath": "/static/images/tabs/tab-my.png",
"selectedIconPath": "/static/images/tabs/tab-my-current.png"
}]
}
个人中心
个人中心手指移动动画
获取手指的坐标
handleTouchStart(event) {
startY = event.touches[0].clientY;
console.log(startY);
},
// touches是手指的坐标,0代表了第一个手指,clientY取y坐标
登录验证
<input id="需要传递一个id值" type="text" data-type="phone" placeholder="请输入手机号码" bindinput="handleInput"/>
传入id值可以快速找到个id值
data-自己命名 = "值" 这个使用自定义传递数值
事件委托
-
什么是事件委托
- 将子元素的事件委托(绑定)给父元素
-
事件委托的好处
- 减少绑定的次数
- 后期新添加的元素也可以享用之前委托的事件
-
事件委托的原理
- 冒泡
-
触发事件的是谁
- 子元素
-
如何找到出触发事件的对象
- event.target
-
currentTarget VS target
- currentTarget要求绑定事件的元素一定是触发事件的元素
- target绑定事件的元素不一定是触发事件的元素
事件提示框
icon “sucess” 成功
icon “loading” 加载中
icon “none” 没有
icon “error” 错误
数据缓存
-
将用户信息存储到本地
语法:wx:setStorage()||wx:setStorageSync
同H5 locaStorage
获取cookie
header: {
cookie: wx.getStorageSync('cookies') ? wx.getStorageSync('cookies').find(item => item.indexOf("MUSIC_U") !== -1) : ''
},
正在加载
wx.showLoading();
关闭
wx.hideLoading();
获取视频实例
// 点击播放的回调/继续播放的回调
handlePlay(event) {
/**
* 思路:
* 1. 在点击播放的事件中需要找到上一个播放的视频
* 2. 在播放新的视频之前关闭上一个正在播放的视频
*/
let vid = event.currentTarget.id;
console.log(vid, "233");
// 关闭上一个播放的视频
this.id != vid && this.videoContext && this.videoContext.stop();
this.id = vid;
this.videoContext = wx.createVideoContext(vid);
},
video无法播放或者一直加载转圈
解决方法
将选中的video从图片转换成video
- 需要一个封面图
- 当点击封面图时,加载视频
- 使用poster属性
<video
src="{{item.data.urlInfo.url}}"
bindplay="handlePlay" id="{{item.id}}"
// poster图片
poster="{{item.data.coveUrl}}"
></video>
下拉刷新
<scroll-view class="videoScroll" scroll-y="true"
bindrefresherrefresh="handleRefresher"
refresher-enabled
refresher-triggered="{{isTriggered}}"
>
界面下拉刷新
{
"usingComponents": {},
"navigationBarTitleText": "视频页",
"enablePullDownRefresh": true
}
用户转发
<button open-type="share" class="item btn">
歌曲详情
通过跳转路由传参
url?key=value
歌曲播放
async musicControl(isPlay, musicId) {
let backgroundAudioManager = wx.getBackgroundAudioManager();
if (isPlay) {
// 音乐播放
console.log(musicId);
// 获取播放链接
let musicLinkData = await request("/song/url", {
id: musicId
});
let musicLink = musicLinkData.data[0].url;
// 创建音频播放实例
backgroundAudioManager.src = musicLink;
// 必填项
backgroundAudioManager.title = this.data.song.name;
} else {
// 音乐暂停
backgroundAudioManager.pause();
}
},
通过系统监视音乐的播放和暂停
// 监视音乐播放/暂停/停止
this.backgroundAudioManager.onPlay(()=>{
this.setData({
isPlay:true
})
});
this.backgroundAudioManager.onPause(()=>{
this.setData({
isPlay:false
})
});
this.backgroundAudioManager.onStop(()=>{
this.setData({
isPlay:false
})
});
使用pubsub消息订阅
npm install pubsub-js
小程序和React对比
-
小程序
- data中初始化数据
- 修改数据:this.setData
- 修改数据的行为始终是同步的
-
Vue
- data中初始化数据
- 修改数据:this.key=value
-
React
- state中初始化数据
- 修改数据:this.setState
数据的劫持和代理
// 模拟组件的实例
let _this = {
}
// 利用Object.defineProperty() 看见有.... 的就是使用了defineProperty
for (let item in data) {
Object.defineProperty(_this, item, {
// 用于获取扩展属性值的
get() {
return data[item]
},
// 监视扩展属性的,只要已修改就调用
set(value) {
data[item] = value;
}
})
}
_this.age = "dddd";
console.log(_this.age);
console.log(_this);