与普通的JS差异
- 小程序不是运行在浏览器中,所有没有BOM和DOM对象
console.log(window) //=> undefined
console.log(document) // => undefined
- 小程序的JS中有一些额外的成员
// App 方法: 用于定义应用程序实例对象
// Page 方法:拥有定义页面对象
// getApp 方法:用来获取全局应用程序对象
// getCurrentPages 方法:用来获取当前页面的调用栈
// wx 对象:用来提供核心API
- 小程序的JS是支持CommonJS规范的
module.exports = {
say:say
}
// 小程序不支持 export.say = {} 这种格式的
1. 界面层-数据绑定{{ }}
mustache(小胡子)语法{{}} 可以用在:
1. innerHtml(类似)
2. 元素的属性上
3. 不能用在标签名和属性名上
4. 可以直接使用字面量和简单的逻辑运算符
Page({
// 为页面提供数据
// data就是节目和逻辑之间的桥梁
data: {
message: 'hello world',
person:{
name: '张三',
age: 18
},
viewClassName:'active'
}
})
<view class="container">
{{ message }}
{{person.name}} - {{person.age}}
<view class="tab {{ viewClassName }}"></view>
<text>{{ 'hello' }}</text>
<text>{{ 111 }}</text>
<text>{{ 111 + 999 }}</text>
<text>{{ 100 > 50 ? '是的' : '不是' }}</text>
<!-- checked="false" 不起作用 -->
<checkbox checked="{{ false }}"></checkbox>
</view>
2. 界面层-列表渲染wx:for
基本的循环 wx:for
- 明确页面结构中的循环体
- 删除多余的重复内容,只保留一个
- 在剩下的这个上加上wx:for属性, 属性值等于要遍历的数据源,数据源必须是一个数组
- 在这个标签(循环体)内部使用item代表当前被遍历的元素
给被遍历到的对象定义名称 wx:for-item
给遍历的下标(索引)定义名称 wx:for-index
<!-- 列表循环-->
<view wx:for="{{ todos }}" wx:for-item="todo" wx:for-index="i">
<text>{{ i }}</text>
<checkbox checked="{{ todo.done }}"></checkbox>
<text>{{ todo.name }}</text>
</view>
Page({
data: {
todos: [
{ name: 'JavaScript', done: false },
{ name: 'HTML', done: true },
{ name: 'CSS', done: true }
]
}
})
3. 界面层-事件处理
- 基本的事件使用
bindtap="fnName"
就是通过给组件添加一个 “bind+事件名” 的属性,属性的值指向一个定义在当前页面对象中JS方法
事件的基本使用 bind[xxx] catch[xxx] - 事件冒泡
catch+事件名
小程序中事件冒泡和和HTML中处理起来不一样 这里是使用catch[xxx] - 事件传参
e.target.dataset
如果需要给事件处理函数指定参数只能通过dataset方式
<view>
<!-- 基本事件绑定 -->
<button bindtap="buttonTapHandle">基本事件绑定</button>
<!-- 事件冒泡 -->
<view bindtap="outterHandle" style="width:200px; height:200px; background-color: red">
<view catchtap="innerHandle" style="width:100px; height:100px; background-color: blue"></view>
</view>
<!-- catch+事件名 是阻止冒泡并且绑定事件 -->
<!-- 事件传参 -->
<button bindtap="tap2Handle" data-name="张三" data-age="13">传参1</button>
<button bindtap="tap2Handle" data-hello-world="张三">传参2</button>
</view>
Page({
buttonTapHandle (e) {
console.log('事件绑定基本用法')
console.dir(e) //将一个对象以树状形式打印到控制台
},
innerHandle () {
console.log('inner')
},
outterHandle () {
console.log('outter')
},
tap2Handle (e) {
// e.target 拿到的就是点击的元素
// dataset指的是元素上所有以data-开头的属性集合
console.dir(e.target.dataset) // { age: "13", name: "张三" } // { helloWorld: "张三" }
// console.log(this) // 事件处理函数中的this指向的还是页面对象!!!跟跟HTML不一样
}
})
4. 单向数据流
<view>
<input class="weui-input" placeholder="请输入内容" bindinput="change" />
<text>{{ message }}</text>
</view>
Page({
data: {
message:'initial'
},
change (e) {
this.setData({'message': e.detail.value})
}
})
this.setData() 是用来改变 data 中的数据,它与直接赋值的区别在于setData() 可以实现响应式的数据变化,即界面上的值也同时发生改变。
5. 界面层-条件渲染 wx:if
block wx:if
在框架中,使用 wx:if=""
来判断是否需要渲染该代码块:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif
和 wx:else
来添加一个 else 块:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
block wx:if
因为 wx:if
是一个控制属性(wx:开头的),需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
wx:if vs hidden
因为 wx:if
之中的模板也可能包含数据绑定,所以当 wx:if
的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if
也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下, hidden
就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if
有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if
较好。
6. 界面层-WXSS vs. CSS
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
尺寸单位:rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。