文章目录
14、微信小程序数据绑定与数组的运用
01 微信小程序数据绑定
WXML数据绑定
运用 JS 的 data 对象完成的 WXML 数据的动态显示
绑定分类:
1、基础绑定
data: {
studentName: 'tom'
}
;<text>{{ studentName }}</text>
data 的作用
1、初始始数据
2、我们的所有数据和面页中的内容绑定时的对接程序。
2、组件绑定
属性设定(需要在双引号内)
<view class="{{flag ? 'color-red' : 'color-green'}}">
<text>name: {{studentName}}</text>
<view id="item{{id}}"> item-view </view></view
>
运算符的操作
02、微信小程序数组
小程序数组的写法
studentScroes:[90, 70, 85],
和绑定表达式的组合使用
{{studentScroes[0]}}
和绑定表达式的对象组合使用
{{studentClassScroes[0].className}}
扩展运算符(模板时后期讲解)
Js 里的 data 页面的初始数据,让我们所有的数据与页面的内容进行数据绑定时的对接程序
data: {
studentName: "tom"
},
15、微信小程序条件渲染与列表渲染
在微信里所有的字符串都是真
01、微信小程序条件渲染与列表渲染
wx:if 用来做判断是否需要渲染该代码块
也可以用 wx:elif 和 wx:else 来写 if-else 语句
Block wx:if
wx:if --> if(){}
wx:elif -> if else(){}
wx:else --> else(){}
block --> template
特别区分:
wx:if 和 hiiden 相当 display:none(css 隐藏 )
wx:if 是遇 true 显示,hidden 是遇 false 显示。
wx:if 在隐藏的时候不渲染,而 hidden 在隐藏时仍然渲染,只是不呈现。
所以如果频繁切换的话,用 hidden 将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁。
如果切换并不频繁的话,用 wx:if 相对来说较好些,因为它会避免初始就一下渲染那么多。
02、微信小程序条件渲染与列表渲染
wx:for 的通用写法
修改特定属性:
wx:for-item 修改循环变量
<view class="inner-view margin20" wx:for="{{navigatorScroll}}">
<navigator url="{{item.url}}">
<image src="/icon/{{item.img}}"></image>
<view class="inner-fnt">{{item.title}}</view>
</navigator>
</view>
wx:for-index 可以指定数组的下标
view wx:for=“{{array}}” wx:for-index=“idx” wx:for-item=“itemName”
指定义: wx:for-index=“scoredID”
指定义: wx:for-item=“studentScore”
<view
wx:for="{{studentScores}}"
wx:for-index="scoredID"
wx:for-item="studentScore"
>
{{scoredID}}:{{studentScore}}
</view>
数组的嵌套
block wx:for
block 与 view 区别
用在 block 中可以渲染一个包含多节点的结构块。(相当一个 vue 中的 template 标签)
用在 view 中只能应用单个节点。
16、微信小程序模板操作与引用
template 定义模板后可以在不同的位置使用模板
模板的定义 name 起名字
<!-- 模板定义 -->
<template name="studentInfo">
<view>学号:{{ studentName }}</view>
<view>姓名: {{ studengXingMing }}</view>
<view>年龄:{{ age }}</view>
</template>
使用模板 is
<!-- 模板调用 -->
<template is="studentInfo" data="{{studentName, age}}" />
模板的作用域
模板的引用的两种方式import和include
include 引入的模板里面不能包含 template 元素
<include src="/templates/footer.wxml" />
Improt(引入模板)
模板文件 templates 下目录:
studentInfo.wxml
text_student.wxml
引入到 templateDemo.wxml
可以把外部的一个文件导入指定的文件。然后再调用
Import 的作用域:没有继承性
就是 A 引入 B,B 引入 C, 在 A 里面不能展示 C
Include(导入代码)
可以将目标文件整个代码引入,相当于拷贝
17、微信小程序的事件调用
微信小程序事件
事件是用户与微信小程序的交互的通讯接口
事件是视图层到逻辑层的通讯方式。
事件可以将用户的行为反馈到逻辑层进行处理。
事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
事件对象可以携带额外信息,如 id, dataset, touches。
在 JS 中就有事件操作的概念,微信小程序的更加简便
事件的使用方式
在组件中绑定一个事件处理函数。
<view bindtap="tapName">Click me</view>
在相应的 Page 定义中写上相应的事件处理函数,参数是 event。
tapName(event) {
console.log(event);
},
返回对象
{type: “tap”, timeStamp: 2774, target: {…}, currentTarget: {…}, mark: {…}, …}
以“bind+事件类型”或“catch+事件类型” 作为用户的事件绑定监听器,连接事件源和事件处理程序
事件绑定函数可以是一个数据绑定
<view bindtap="{{eventFun}}">Click me</view>
data: {
eventFun:"tapName"
},
事件分类
#### 事件分为冒泡事件和非冒泡事件:
1、冒泡事件 bind 开头:当一个组件上的事件被触发后,该事件会向父节点传递。
2、非冒泡事件 catch 开头:当一个组件上的事件被触发后,该事件不会向父节点传递
绑定并阻止事件冒泡
除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。
例如在下边这个例子中,点击 inner view 会先后调用 handleTap3 和 handleTap2(因为 tap 事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发 handleTap2,点击 outer view 会触发 handleTap1。
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
{' '}
inner view{' '}
</view>
</view>
</view>
类型 触发条件 最低版本
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 1.5.0
longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发
touchforcechange 在支持 3D Touch 的 iPhone 设备,重按时会触发 1.9.90
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的 submit 事件,input 的 input 事件,scroll-view 的 scroll 事件,(详见各个组件)
事件的捕获阶段
事件捕获是先外后里,且优于事件绑定。
<view
id="outer"
bind:touchstart="handleTap1"
capture-bind:touchstart="handleTap2"
>
outer view
<view
id="inner"
bind:touchstart="handleTap3"
capture-bind:touchstart="handleTap4"
>
inner view
</view>
</view>
handleTap1() {
console.log("handleTap1")
},
handleTap2() {
console.log("handleTap2")
},
handleTap3() {
console.log("handleTap3")
},
handleTap4() {
console.log("handleTap4")
},
点击 inner view
返回
handleTap2
handleTap4
18 handleTap3
handleTap1
事件对象
每次触发事件时都会传递一个对象给到 JS(逻辑层)
BaseEvent的属性
Type事件类型
Timestamp 时间戳
Target 属性集合(事件源组件)
Id 事件源组件id
Dataset data- 事件源组件上的自定义集合
currentTarget 当前组件的一些属性值集合
dataset data- 事件源组件上的自定义集合
二个盒子:当第二个子级盒子高度用 100%时,外面父盒子一定要有固定的高度。
微信给一个获取屏幕高度、宽度的 API
获取不同屏幕的高度、宽度 px,用一个固定的格式进行 rpx 的转换
第一步
/**
* 生命周期函数--监听页面加载
**/
onLoad: function (options) {
wx.getSystemInfo({
success: function(res) {
let clientHeight = res.windowHeight;
let clientWidth = res.windowWidth;
let ratio = 750 / clientWidth;
let rpxHeight = clientHeight _ ratio;
console.log(clientHeight);
console.log(rpxHeight);
},
})
},
// 第二步在 data 定义变量
data: {
swiperRPXHeight:0
},
// 第三步修改变量
onLoad: function (options) {
let that = this;
wx.getSystemInfo({
success: function(res) {
let clientHeight = res.windowHeight;
let clientWidth = res.windowWidth;
let ratio = 750 / clientWidth;
let rpxHeight = clientHeight \* ratio;
console.log(clientHeight);
console.log(rpxHeight);
that.setData({
swiperRPXHeight: rpxHeight
})
},
})
},
第四步
<swiper style="height:{{swiperRPXHeight}}rpx"> </swiper>
18、微信小程序媒体组件 audio
audio 音频
可以播放在线音频资源
支持的属性:参考在线字典
支持 wx.createInnerAudioContext
从内部代码完成播放操作,是 audio 的升级版本
案例演示
<view>
<audio name="{{name}}" poster="{{poster}}" author="{{author}}" src="{{src}}" id="myAudio"></audio>
<button type="primary" bindtap="audioPlay">播放</button>
<button type="primary" bindtap="audioPause">暂停</button>
<button type="primary" bindtap="audio14">设置当前播放时间为 14 秒</button>
<button type="primary" bindtap="audioStart">回到开头</button>
</view>
/**
* 播放
*/
audioPlay() {
this.audioCtx.play();
},
/**
* 暂停
*/
audioPause() {
this.audioCtx.pause();
},
/**
* 指定位置
*/
audio14() {
this.audioCtx.seek(14);
},
/**
* 从头开始
*/
audioStart() {
this.audioCtx.seek(0);
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
// 创建一个音频对象(音频上下文)
this.audioCtx = wx.createAudioContext("myAudio")
},
媒体组件 video
video 视频组件:
该组件为原生组件,需要注意部分事项
小程序中的原生组件有如下
camera,canvas,input,live-player,live-pusher,map,textarea,video
原生组件的使用限制
1.原生组件的层级是最高层,其他组件无法通过 z-index 来覆盖
2.原生组件可以覆盖原生组件
3.部分样式无法支持原生组件
CSS 动画,position:fixed 4.在 IOS 下,原生组件不支持触摸事件
属性:在线字典查询
案例演示:弹幕制作
19、视图容器 movable-view 与 cover-view 的操作
微信小程序控件 movable-view
movable-area,movable-view
可移动区域
需要设置movable-area高和宽,默认值:10px
movable-view 可拖动区域容器
属性:参考在线字典
案例演示
照片的拖动缩放
cover-view
覆盖在组件上的文本视图
cover-image
覆盖在原生组件智商的图片
案例演示
20、件 rich-text 与 progress 操作
微信小程序控件 rich-text 通过 rich-text 组件可以加载 HTML 的容器
富文本对话框
可以直接导入HTML标签文本
nodes属性
属性值可以是 array或string
案例演示 加载逻辑层数据
下面是wxhtml结构
微信小程序控件 progress->进度条
percent 进度多少
stroke-width:宽度
进度条操作
属性:参考在线字典
案例演示
20、表单 form 控件的提交原理与提交操作
微信小程序 form 提交原理
form 表单的提交
和 PC 端的表单提交有所不同
更贴近表单的异步提交模式
两大重要事件
bindsubmit
bindreset
<from bindsubmit="formSubmit" bindreset="formReset">
<buttom form-type="submit">Submit</button>
<buttom form-type="reset">Reset</button>
</from>
点击这二按钮后会完成事件的处理:formSubmit formReset
微信小程序提交事件操作
button
size = “mini” 小的
type = “primary” 颜色
plain 镂空
disabled=‘{{false}}’ 不是不可用
loading = ‘{{true}}’ 名称前是否带 loading 图标
用于 form 组件,点击分别会触发 form 组件的 submit/reset 事件
<button form-type="submit"></button>
<button fro-type ="reset"></button>
radio
用 radio-group 归为一类别
<radio-group name="radio">
<label>
<radio value="radio1" />
选项一
</label>
<label>
<radio value="radio2" />
选项二
</label>
</radio-group>
checkbox
用 checkbox 归为一类别
用 e.detail.value 获取 value 值
/**
* 提交事件
*/
checkedChange(e){
console.log(e.detail.value)
//获取数据
//处理数据
//提交数据
},
<checkbox-group checkbox='checkedChange'>
<label>
<checkbox value="checkbox1" />
选项一
</label>
<label>
<checkbox value="checkbox2" />
选项二
</label>
</checkbox-group>
editor 富文本编辑器
input
type 为键盘类型
<input value='文本' type='tex' maxlength="5" focus="true"></input>
<input value='数字'></input>
<input password placeholder="密码" placeholder-style='color:red'>
confirm-type = send 发送 search 搜索 next 下一个 go 前往 done 完成
label
点击控件的区域大小
21、导航组件 navigator 跳转与 tabbar 的跳转操作
navigator 跳转
主要用于直接在 wxml 的跳转
可跳转其他小程序
具体属性参考:在线微信字典
tabbar 的跳转
通过 app.json 的配置
通过微信接口进行跳转
注意事项
tabbar 跳转与 navigator 跳转不可同时作用在一个对象上
同一对象
<navigator target='self' url="/pages/form/form' open-type='switchTab'>tabbar</navigator>
<navigator target="self" url="/pages/audio/audio" open-type="reLaunch">
跳转操作
</navigator>
<button bindtap="tabbarNivagtor">tatbar跳转</button>
tabbarNivagtor(){
wx.switchTab({
url: '/pages/index/index' //这个路径一定要在app.json中的
})
}
其他的跳转方式
<button bindtap="otherNavigator">跳转</button>
otherNavigator(){
wx.redirectTo({
url: '/pages/index/index' //这个路径一定要在app.json中的
})
}
// open-type 的合法值
navigate 与 reLaunch 的区别
reLaunch可以把前面打开的页面关闭,而navigate前面页面打开着,当前页面跳转。
personCenter
<view class="container">
<view class="page">
<form bindsubmit="regFormSubmit" bindreset="regFormReset">
<view class="area">
<label class="model">
<text>name:</text>
<input class="input" bindblur="inputValue"></input>
</label>
<label class="model">
<text>password:</text>
<input
class="input"
password
bindblur="passwordValue"
></input>
</label>
<label class="model">
<text>password:</text>
<radio-group
class="control-center"
bindchange="genderRadio"
>
<radio value="1" checked>
male
</radio>
<radio value="0">female</radio>
</radio-group>
</label>
<label class="model">
<text>hobby:</text>
<checkbox-group
class="control-center"
bindchange="hobbyCheckbox"
>
<checkbox value="tour">tour</checkbox>
<checkbox value="book" checked>
book
</checkbox>
<checkbox value="game">game</checkbox>
</checkbox-group>
</label>
<label class="model">
<text>birthday</text>
<picker mode="date" bindchange="birthdayValue">
<view>[please choose birthday]</view>
</picker>
</label>
<label class="model">
<text>study years:</text>
<slider
step="1"
show-value
bindchange="sliderValue"
></slider>
</label>
<label class="model">
<view>
isMember:
<switch bindchange="isMemberValue"></switch>
</view>
</label>
<label class="model">
<text>agreemeng:</text>
<textarea class="textarea control-center">
this is psersonReg.please read it first.
</textarea>
</label>
<button size="default" form-type="submit">
submit
</button>
<button size="default" form-type="reset">
reset
</button>
</view>
</form>
</view>
</view>
Page({
//表单数据
personName:'',
password:'',
gender:'',
hobby:'',
birthday:'',
studyYears:'',
isMember:'',
/**
* 页面的初始数据
*/
data: {
},
/**
* 获取姓名
*/
inputValue(e){
this.personName = e.detail.value;
console.log(this.personName)
},
/**
* 获取密码
*/
passwordValue(e){
this.password = e.detail.value;
console.log(this.password)
},
/**
* 获取性别
*/
genderRadio(e){
this.gender = e.detail.value == 1 ? "male" : "female";
console.log(this.gender)
},
/**
* 获取爱好
*/
hobbyCheckbox(e){
this.hobby = e.detail.value
console.log(this.hobby)
},
/**
* 获取生日
*/
birthdayValue(e){
this.birthday = e.detail.value;
console.log(this.birthday)
},
/**
* 获取学习年数
*/
sliderValue(e){
this.studyYears = e.detail.value;
console.log(this.studyYears)
},
/**
* 获取判断会员
*/
isMemberValue(e){
this.isMember = e.detail.value;
console.log(this.isMember)
},
/**
* 提交按钮
*/
regFormSubmit(){
let memberData = {
personName: this.personName,
password: this.password,
gender: this.gender,
hobby: this.hobby,
birthday: this.birthday,
isMember: this.isMember
}
if(memberData.personName == ""){
wx.showModal({
title: 'error',
content: '姓名没有填写',
})
}
})
手机验证码
按钮-> 服务器 -> 电信(移动,联通) 渠道商接(短信下发) -> 在服务器端记录验证号,
用户输入 -> 提交 -> 服务器
用户输入 -> 服务器的记录匹配
24、camera 系统相机。扫码二维码功能,
<view class="page-body">
<view class="page-body-wrapper">
<camera device-position="back" flash="off" binderror="error" style="width: 100%; height: 300px;"></camera>
<view class="btn-area">
<button type="primary" bindtap="takePhoto">拍照</button>
</view>
<view class="btn-area">
<button type="primary" bindtap="startRecord">开始录像</button>
</view>
<view class="btn-area">
<button type="primary" bindtap="stopRecord">结束录像</button>
</view>
<view class="preview-tips">预览</view>
<image wx:if="{{src}}" mode="widthFix" src="{{src}}"></image>
<video wx:if="{{videoSrc}}" class="video" src="{{videoSrc}}"></video>
</view>
</view>
/**
* 页面的初始数据
*/
data: {
src:''
},
/**
* 拍照
*/
takePhoto(){
let that = this
//获取相机对象
const ctx = wx.createCameraContext();
//通过接口调用拍照方法
ctx.takePhoto({
quality:'high', //高质量
success:(res)=>{
// 设定到缓存中
wx.setStorage({
key: 'photoPeople',
data: restempImagePath, //存在本地的图片临时的路径
})
// 跳转页面
wx.redirectTo({
url: "/page/case/photo",
})
that.setData({
src:res.tempImagePath
})
},
error(e) {
console.log(e)
}
})
},
25、map 地图
canvas 组件
画布(原生组件)
画布 canvas 标签默认宽度 300px、高度 225px
同一页面中的 canvas-id 不可重复
<view class="container">
<!-- 画布区域 -->
<view class='canvas-area'>
<!-- 注意:同一个页面中的canvas-id不可重复,如果使用了已经出现过的canvase-id,该canvas标签对于的画布将被隐藏病不再正常工作 -->
<canvas canvas-id='myCanvas' class='myCanvas'
disable-scroll='false'
bindtouchstart='touchStart'
bindtouchmove='touchMove'
bindtouchend='touchEnd'
>
</canvas>
</view>
<!-- 画布工具区域 -->
<view class='canvas-tools'>
<!-- 细笔绘制 -->
<view class='box box1' bindtap='penSelect' data-param='5'></view>
<!-- 粗笔绘制 -->
<view class='box box2' bindtap='penSelect' data-param='15'></view>
<!-- 红色笔 -->
<view class='box box3' bindtap='colorSelect' data-param='#c03'></view>
<!-- 黄色笔 -->
<view class='box box4' bindtap='colorSelect' data-param='#f90'></view>
<!-- 橡皮 -->
<view class='box box5' bindtap='clearCanvas'></view>
</view>
</view>
Page({
data: {
pen: 3, //画笔粗细默认值
color: '#000' //画笔颜色默认值
},
startX: 0, //保存X坐标轴变量
startY: 0, //保存X坐标轴变量
isClear: false, //是否启用橡皮擦标记
//手指触摸动作开始
touchStart: function (e) {
//得到触摸点的坐标
this.startX = e.changedTouches[0].x
this.startY = e.changedTouches[0].y
this.context = wx.createContext()
if (this.isClear) { //判断是否启用的橡皮擦功能 ture表示清除 false表示画画
this.context.setStrokeStyle('#F8F8F8') //设置线条样式 此处设置为画布的背景颜色 橡皮擦原理就是:利用擦过的地方被填充为画布的背景颜色一致 从而达到橡皮擦的效果
this.context.setLineCap('round') //设置线条端点的样式
this.context.setLineJoin('round') //设置两线相交处的样式
this.context.setLineWidth(20) //设置线条宽度
this.context.save(); //保存当前坐标轴的缩放、旋转、平移信息
this.context.beginPath() //开始一个路径
this.context.arc(this.startX, this.startY, 5, 0, 2 * Math.PI, true); //添加一个弧形路径到当前路径,顺时针绘制 这里总共画了360度 也就是一个圆形
this.context.fill(); //对当前路径进行填充
this.context.restore(); //恢复之前保存过的坐标轴的缩放、旋转、平移信息
} else {
this.context.setStrokeStyle(this.data.color)
this.context.setLineWidth(this.data.pen)
this.context.setLineCap('round') // 让线条圆润
this.context.beginPath()
}
},
//手指触摸后移动
touchMove: function (e) {
var startX1 = e.changedTouches[0].x
var startY1 = e.changedTouches[0].y
if (this.isClear) { //判断是否启用的橡皮擦功能 ture表示清除 false表示画画
this.context.save(); //保存当前坐标轴的缩放、旋转、平移信息
this.context.moveTo(this.startX, this.startY); //把路径移动到画布中的指定点,但不创建线条
this.context.lineTo(startX1, startY1); //添加一个新点,然后在画布中创建从该点到最后指定点的线条
this.context.stroke(); //对当前路径进行描边
this.context.restore() //恢复之前保存过的坐标轴的缩放、旋转、平移信息
this.startX = startX1;
this.startY = startY1;
} else {
this.context.moveTo(this.startX, this.startY)
this.context.lineTo(startX1, startY1)
this.context.stroke()
this.startX = startX1;
this.startY = startY1;
}
//只是一个记录方法调用的容器,用于生成记录绘制行为的actions数组。context跟<canvas/>不存在对应关系,一个context生成画布的绘制动作数组可以应用于多个<canvas/>
wx.drawCanvas({
canvasId: 'myCanvas',
reserve: true,
actions: this.context.getActions() // 获取绘图动作数组
})
},
//手指触摸动作结束
touchEnd: function () {
},
//启动橡皮擦方法
clearCanvas: function () {
if (this.isClear) {
this.isClear = false;
} else {
this.isClear = true;
}
},
penSelect: function (e) { //更改画笔大小的方法
console.log(e.currentTarget);
this.setData({ pen: parseInt(e.currentTarget.dataset.param) });
this.isClear = false;
},
colorSelect: function (e) { //更改画笔颜色的方法
console.log(e);
console.log(e.currentTarget);
this.setData({ color: e.currentTarget.dataset.param });
this.isClear = false;
}
})