赞
踩
公众号
app:基于手机操作系统提供的API进行开发
小程序:基于微信提供的API进行开发
组件
是视图层的基本组成单元,自带一些功能与微信风格一致的样式
一个组件通常包括 开始标签 和结束标签,属性 用来修饰这个组件内容在两个额标签之内
小程序中 所有的组件名称和属性名称都是小写
最后再进行设置于小程序的基本信息(项目发布阶段再写)
下载开发者文档
app.js全局入口文件
app.json // 第一个就是小程序默认运行的页面(一打开就显示的页面)
可以直接在app.json文件中直接写一个陌路和页面,项目目录就会自动的创建一个目录和4个小程序文件
“pages/user/user”
{
"pages": [
"pages/home/home",
"pages/index/index",
"pages/logs/logs",
"pages/user/user"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "black"
}
}
小程序的结构与配置
<text> 组件在一行进行显示
长按选中 selectable
space属性 设置每一个空格的宽度
view组件就相当于div,用来进行布局(块级,没有margin和padding)
button按钮(看官网提供的文档)
<button size="mini" type="warn" plain>按钮4</button>
input输入框
image图片(不是img标签!!)
注意:image组件默认宽度是300px,高度是225px.即使没有给指定src属性还是会有一个宽高
小程序中的样式
wxss
WXSS(WeiXin Style Sheets)是一套样式语言,用来决定 WXML 的组件应该怎么显示;
WXSS 具有 CSS 大部分特性;
WXSS 对 CSS 进行了扩充以及修改,以适应微信小程序的开发;
与 CSS 相比,WXSS 扩展的特性有:
wxss目前支持的选择器
<view data-color="pink">12312312313</view>
/* 自定义属性,属性选择器 */
[data-color='pink']{
background-color: lightblue;
}
rpx尺寸单位(类似之前的rem)
rpx(responsive pixel): 是微信小程序独有的、解决屏幕自适应的尺寸单位。
rpx与px之间的换算
以 iPhone6 为例,iPhone6 的屏幕宽度为375px,共有750个物理像素,(把iPhone5上分为750份,750rpx)则750rpx = 375px
= 750物理像素,1rpx = 0.5px = 1物理像素。
在iPhone6上,如果要绘制宽100px,高20px的盒子,换算成rpx单位,宽高分别为 200rpx 和 40rpx。
rpx 和 iPhone6 设计稿的关系
官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准。如果要根据iPhone6的设计稿,绘制小程序页面,可以直接把单位从
px 替换为 rpx 。例如,假设iPhone6设计稿上,要绘制一个宽高为 200px 的盒子,换算为 rpx 为 200rpx。(设计师给的是2倍图,显示到真实手机页面是1倍,然后如果使用rpx作为像素单位,又需要再乘以2)
使用rpx单位可以适配,随着屏幕的大小进行变换(类似rem)
.vv1{
width: 375rpx;
height: 375rpx;
background-color: red;
}
@import 样式导入(一个css文件中导入另外一个样式文件)
全局样式与局部样式
app.json配置文件的作用
小程序根目录下的 app.json 文件用来对微信小程序进行全局配置,它决定了页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。
在app.json配置文件中,最主要的配置节点是:
pages – 配置小程序的页面路径
自动创建新页面
设置默认首页
window节点常用的配置项(小程序的窗口组成部分)
`"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#2b4b6b",
"navigationBarTitleText": "我的小程序",
"navigationBarTextStyle": "white",
"enablePullDownRefresh":true
}
tabBar - 配置Tab栏
backgroundColor:导航条背景色
selectedIconPath:选中时的图片路径
borderStyle:tabBar上边框的颜色
iconPath:未选中时的图片路径
selectedColor:tab 上的文字选中时的颜色
color:tab 上的文字默认(未选中)颜色
在app.json文件和window配置选项平级的位置设置 tabBar
tabBar节点中list的配置项(必填项)
案例
tabBar图标切换
pagePath 指定当前tab对应的页面路径【必填】
text 指定当前tab上按钮的文字【必填】
iconPath 指定当前tab未选中时候的图片路径【可选】
selectedIconPath 指定当前tab被选中后高亮的图片路径【可选】
使用页面配置文件page.json(例如我只想要消息页面的顶部颜色变红色。就需要对页面文件进行配置。打开消息文件)
页面级别和全局级别配置的关系
小程序中,app.json 中的 window节点,可以全局配置小程序中每个页面的窗口表现;
如果某些小程序页面,想要拥有特殊的窗口表现,此时,“页面级别的.json配置文件”就可以实现这种需求;
总结:页面级别配置优先于全局配置生效。
小程序中的生命周期(时间段)
应用生命周期:特指小程序从启动 -> 运行 -> 销毁的过程;
页面生命周期:特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程;
其中,页面的生命周期范围较小,应用程序的生命周期范围较大
生命周期函数:(时间点)
是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行;
生命周期函数的作用:允许程序员在特定的生命周期时间点上,执行某些特定的操作。例如,页面刚加载的时候,在生命周期函数中自动发起数据请求,获取当前页面的数据;
注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
生命周期函数的分类
应用生命周期函数
app.js 是小程序执行的入口文件,在 app.js 中必须调用 App() 函数,且只能调用一次。其中,App() 函数是用来注册并执行小程序的。
App(Object) 函数接收一个Object参数,可以通过这个Object参数,指定小程序的生命周期函数。
例如:
App({
// 小程序初始化完成时,执行此函数,可以做一些初始化的工作。
onLaunch: function(options) {},
// 小程序显示到屏幕上的时候,执行此函数。
onShow : function(options) {},
// 小程序被最小化的时候,执行此函数。
onHide : function() {}
})
注意onlaunch只执行一次 其他的是一直会执行
页面生命周期函数
每个小程序页面,必须拥有自己的 .js 文件,且必须调用 Page() 函数,否则报错。其中Page() 函数用来注册小程序页面。
Page(Object) 函数接收一个Object参数,可以通过这个Object参数,指定页面的生命周期函数。
例如:(定义的顺序也是函数加载的顺序)
Page({
onLoad : function(options) {}, // 监听页面加载
onShow : function() {}, // 监听页面显示
onReady : function() {}, // 监听页面初次渲染完成
onHide : function() {}, // 监听页面隐藏
onUnload: function() {} // 监听页面卸载
})
注意:onLoad与onReady,onUnload只显示一次,onHide与onShow循环执行
数据绑定
如何定义页面的数据
小程序中每个页面,由4部分组成,其中 .js 文件内可以定义页面的数据、生命周期函数、其它业务逻辑;
如果要在.js文件内定义页面的数据,只需把数据定义到 data 节点下即可;
示例代码如下:
Page({
data: {
info: 'init data', // 字符串类型的数据
array: [{msg: '1'}, {msg: '2'}] // 数组类型的数据
}
})
Mustache语法格式 (差值表达式)(既可以用在内容节点,也可以用在属性节点)
把data中的数据绑定到页面中渲染,使用 Mustache 语法(双大括号)将变量包起来即可;
语法格式为:
<view> {{ 要绑定的数据名称 }} </view>
Mustache 语法的主要应用场景:
页面结构:
<view id="item-{{id}}"> </view>
页面数据:
Page({
data: {
id: 0
}
})
页面结构:
<view> {{ flag ? ‘条件为真’ : ‘条件为假’ }} </view>
页面数据:
Page({
data: {
flag: true
}
})
事件
事件是视图层到逻辑层的通讯方式。
事件可以将用户的行为反馈到逻辑层进行处理。
事件可以绑定在组件上,当组件触发事件,就会执行逻辑层中对应的事件处理函数。
事件对象可以携带额外信息,如 id, dataset, touches。
bindtap绑定触摸事件
在小程序中,不存在网页中的 onclick 鼠标点击事件,而是通过 tap 事件来响应触摸行为;
通过 bindtap,可以为组件绑定触摸事件,语法如下:
<view bindtap=“tapName”> Click me! <view>
2.在相应的Page定义中写上相应的事件处理函数,事件参数是event:
Page({
tapName: function(event) {
console.log(event)
}
})
**bindinput绑定文本框输入事件(只要input框中内容发生改变就会出发这个事件)
在小程序中,通过 input 事件来响应文本框的输入事件;
\1. 通过 bindinput,可以为文本框绑定输入事件,语法如下:
<input bindinput=“inputName”><input>
在相应的Page定义中写上相应的事件处理函数,事件参数是event:
Page({
inputName: function(event) {
console.log(event)
}
})
**data和文本框之间的数据同步(相当于vue中的数据双向绑定)
监听文本框的数据变化
在文本框的 input 事件处理函数中,通过事件参数 event,能够访问到文本框的最新值:
语法:event.detail.value
示例代码如下:
inputName: function (event) {
// 获取到文本框中最新的内容
console.log(event.detail.value)
}
通过 this.setData(dataObject) 方法,可以给页面中的 data 数据重新赋值。
例如:监听文本框的数据变化,并把最新的值赋值给 data 中的 msg
示例代码如下:
inputName: function (event) {
this.setData({
msg: event.detail.value // 为 data 中的 msg 重新赋值
})
}
总代码如下:
inputEvent:function(e){
// 1.获取到最新的值
console.log(e.detail.value)
// 2,。调用this.setData({})为data中数据重新赋值
this.setData({
info: e.detail.value
})
},
事件传参(小程序中华不支持事件传参方式,因为小程序会把 bindtap 后指定的值,统一当作事件名称来处理;)
不能在绑定事件的同时传递参数
小程序中的事件传参比较特殊,不能在为组件绑定事件的同时,为事件处理函数传递参数。
例如,下面的代码将不能正常工作:
<button type="primary" bindtap='btnHandler(123)'>事件传参</button>
通过data-*自定义属性传参
如果要在组件触发事件处理函数的时候,传递参数,可以为组件提供 data-* 自定义属性传参。
示例代码如下:
<button bindtap='btnHandler’ data-info=“{{123}}”>事件传参</button>
其中,info 会被当作参数名,数值 123 会被当作参数值。
接收传递的参数
通过e.target.dataset来接收
结构:
<button bindtap="inputEvent2" data-msg="123" type="primary">按钮</button>
数据:
inputEvent2:function(e){
console.log('ok')
console.log(e)
console.log(e.target.dataset.msg)
},
wxs 脚本
wxs(WeiXinScript)是小程序的一套脚本语言,结合WXML,可以构建出页面的结构
wxs遵循CommonJS模块化规范(和node语法一样)
CommonJS 是 javascript 的模块化规范之一,小程序的脚本语言 wxs 遵循了 CommonJS 规范,因此,使用 wxs 时的体验和使用 node.js 的体验比较相似。
在 wxs 中,可以使用 CommonJS 中规定的如下成员:
wxs 基础语法
使用module.exports 向外共享成员
通过 module.exports 属性,可以对外共享本模块的私有变量与函数。示例代码如下:
var foo = “‘hello world’ from wxs”; // 定义私有变量 foo
var bar = function (d) { // 定义私有函数 bar
return d;
}
module.exports = { // 通过 modules.exports 向外共享私有成员
FOO: foo, // 向外共享私有变量 foo
bar: bar, // 向外共享私有函数 bar
};
module.exports.msg = “some msg”; // 额外向 module.exports 中挂载 msg 变量
使用
require 引入其它wxs 模块
假设有两个wxs模块,路径分别为/pages/tools.wxs 和/pages/logic.wxs,如果要在logic.wxs中引入tools.wxs
脚本,则示例代码如下:
// 使用 require 导入 tools.wxs 脚本
var tools = require("./tools.wxs");
// 得到的 tools 对象,可以直接访问到 tools.wxs 中向外暴露的变量和方法
在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。
引用的时候,要注意如下几点:
①只能引用 .wxs 文件模块,且必须使用相对路径。
②wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。(节省了内存。内存中值占一份的内存,但是可以多次使用)
③如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。s
支持的数据类型
WXS 语言目前共有以下8种数据类型:
number 数值类型、string 字符串类型、boolean 布尔类型、object 对象类型、
function 函数类型、array 数组类型、 date 日期类型、 regexp 正则
详细的类型说明文档,请翻阅如下网址:
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/06datatype.html
注意:由于wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致,所以在使用以上8种数据类型的时候,一定要先翻阅官方文档,再进行使用!
内嵌 wxs 脚本
wxs 代码可以编写在 wxml 文件中的标签内,就像 javascript 代码可以编写在 html 文件中的 标签内一样。
wxml 文件中的每个 标签,必须提供一个 module 属性,用来指定当前 标签的模块名。在单个 wxml 文件内,建议其值唯一。
module 属性值的命名必须符合下面两个规则:
外联 wxs 脚本
wxs 代码还可以编写在以 .wxs 为后缀名的文件内,就像 javascript 代码可以编写在以 .js 为后缀名的文件中一样。
在微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。
示例代码如下:
// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
return d;
}
module.exports = {
FOO: foo,
bar: bar,
};
module.exports.msg = "some msg";
wxml 内引用外联的 wxs 脚本
在 wxml 中如果要引入外联的 wxs 脚本,必须为 标签添加 module 和 src 属性。
示例代码如下:
<!-- page/index/index.wxml -->
<wxs src="./../tools.wxs" module="tools" />
<view> {{tools.msg}} </view>
<view> {{tools.bar(tools.FOO)}} </view>
注意:在wxs中尽量不要使用高级的es5,es6语法(wxs和js是不一样的,不要想当然的就使用,就使用之前的语法,不要使用es5,es6新语法)
页面渲染
条件渲染wx:if
在.js文件的data中设置好length的值,然后再.wxml文件中写:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
elif 就是 else-if(vue中)
blockwx:if
因为wx:if是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
hidden
在小程序中,直接使用
hidden="{{condition}}" 也能控制元素的显示与隐藏:
<view hidden="{{condition}}"> 条件为 true 隐藏,条件为 false 显示 </view>
wx:if与hidden的对比(类比vue中的 v-if v-show 是一样的作用)
wx:for
绑定一个数组
<view wx:for="{{array}}">
索引是:{{index}} 当前项是:{{item}}
</view>
手动指定索引和当前项的变量名
l使用 wx:for-item 可以指定数组当前元素的变量名
l使用 wx:for-index 可以指定数组当前下标的变量名,示例代码如下:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
索引是:{{idx}} 当前项是:{{itemName}}
</view>
blockwx:for
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
列表渲染中的 key
作用:
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 中的输入内容, 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
<view wx:for="{{list}}" wx:key="index">
id:{{item.id}}
name:{{item.name}}
</view>
js文件中
data: {
length:4,
contation:false,
array:[1,2,3,4,5],
list:[
{ id: 0, name: '张三' },
{ id: 1, name: '张三1' },
{ id: 2, name: '张三2' },
{id:3,name:'张三3'}
]
},
添加数据到列表中案例分析
<view>
<input value="{{name}}" bindinput="iptHandler"></input>
<button type="primary" bindtap="add">添加</button>
</view>
<view wx:for="{{list}}" wx:key="index">
<checkbox></checkbox>
id:{{item.id}}
name:{{item.name}}
</view>
main.js文件
data: { length:4, contation:false, array:[1,2,3,4,5], list:[ { id: 0, name: '张三' }, { id: 1, name: '张三1' }, { id: 2, name: '张三2' }, {id:3,name:'张三3'} ], name:'', }, iptHandler:function(e){ // console.log(e.detail.value) this.setData({ name:e.detail.value }) // console.log(this.data.name) }, add:function(){ console.log(this.data.name) const userInfo = {id:this.data.list.length,name:this.data.name} console.log(userInfo) const arr = this.data.list; arr.unshift(userInfo); // 重新把新的数组赋值给 list this.setData({ list:arr }) },
双向绑定input框中的数据 bindinput=""
函数中的操作,想要改变data中的数据值,必须使用 this.setData({ name:e.detail.value }) 这种方式
一个bug:如果在添加的每条数据列表前加上 checkbox选项。选中当前序号为1的数据,如果再添加一条数据,之前选中的序号为1的数据就会发生变化(不会始终都选中,选择的序号不唯一)这是因为没有为其绑定唯一的值来标识他。
解决方案:将绑定的标识换成当前数据的id值(每个数据的id是唯一的)wx:key=“id”
注意:这里和vue中不太一样,不能写item.id ,而是直接写 id
<view>
<input value="{{name}}" bindinput="iptHandler"></input>
<button type="primary" bindtap="add">添加</button>
</view>
<view wx:for="{{list}}" wx:key="id">
<checkbox></checkbox>
id:{{item.id}}
name:{{item.name}}
</view>
key值的注意点
①key 值必须具有唯一性,且不能动态改变
②key 的值必须是数字或字符串
③保留关键字 *this 代表在 for 循环中的 item 本身,它也可以充当 key 值,但是有以下限制:需要 item 本身是一个唯一的字符串或者数字。(就是在数组中的值不能有重复的值出现)
④如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
key值的两种使用方式
wx:key 的值以两种形式提供:
①字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
②保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
注意:如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
<!-- 也可使用 *this 来为每一条数据绑定唯一的标识值,前提是必须数组里面的值是唯一的,不能有重复的值 -->
<!-- <view wx:for="{{list0}}" wx:key="*this">{{item}}
</view> -->
<!-- 默认就是索引值变量是 index,上面如果是 对象中,可以用 item.id -->
<view wx:for="{{list0}}" wx:key="index">{{item}}</view>s
下拉刷新
启用下拉刷新
两种方式:
①需要在 app.json 的 window 选项中或页面配置中开启 enablePullDownRefresh。但是,一般情况下,推荐在页面配置中为需要的页面单独开启下拉刷新行为。
②可以通过 wx.startPullDownRefresh() 触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。(前提是在json文件中开启了 “enablePullDownRefresh”:true)
配置下拉刷新窗口的样式
需要在 app.json 的 window 选项中或页面配置中修改 backgroundColor 和 backgroundTextStyle 选项。
backgroundColor 用来配置下拉刷新窗口的背景颜色,仅支持16进制颜色值
backgroundTextStyle 用来配置下拉刷新 loading 的样式,仅支持 dark 和 light
{
“usingComponents”: {},
“enablePullDownRefresh”:true,
“backgroundColor”:"#ccc",
“backgroundTextStyle”:“light”
}
onPullDownRefresh() 函数,可以监听用户在当前页面的下拉刷新事件。
stopPullDownRefresh()自动监听到刷新完毕,关闭下拉刷新
注意写在onPullDownRefresh函数里面
onPullDownRefresh: function () {
// 监听用户的下拉刷新操作
console.log('触发了下拉刷新操作!!')
// 触发下拉刷新按钮,触发下拉刷新函数,为页面中的数值重新赋值或者修改数据
this.setData({
list0:['zs','ls']
})
// 关闭下拉刷新
wx.stopPullDownRefresh()
},
上拉加载更多(原理就是分页加载)
可以在 app.json 的 window 选项中或页面配置中设置触底距离
onReachBottomDistance。单位为px,默认触底距离为 50px。
为页面添加onReachBottom()函数,可以监听用户在当前页面的上拉触底事件,从而实现上拉加载更多列表数据的效果。
onPageScroll(Object)
在main.js文件中直接写这个函数参数默认是 obj,就可以打印出当前的移动的距离
onPageScroll: function (obj){
console.log(obj.scrollTop)
},
onShareAppMessage(Object)
监听用户点击页面内转发按钮(组件open-type=“share”)或右上角菜单“转发”按钮的行为,并自定义转发内容。其中Object参数说明如下:
两种方式进行转发
点击微信上右上角的转发按钮 触发的是menu,也就是事件来源是menu(三个圆点。默认显示的页面就是当前页面的预览)
// 点击默认的转发按钮触发事件
onShareAppMessage:function(obj){
console.log(obj)
}
打印出的对象是 from:menu target:undefined,还有一个原型对象
自定义一个按钮,点击此按钮,转发(open-type=“share”)
转发按钮
打印出一个对象 from:button target值是一个对象(描述当前按钮的所有信息,如果按钮上有一个自定义属性 data-info=“aaa” ,则可以通过 target.dataset.info 得到值 aaa)
自定义转发之前的页面预览结果页面
同时,此转发事件需要 return 一个 Object,用于自定义转发内容,返回内容如下:
// 点击默认的转发按钮触发事件
onShareAppMessage:function(obj){
console.log(obj)
return{
title:"测试转发标题",
path:"/pages/main/main",//这个路径是 当把转发给别人看的时候,别人在一打开页面的时候就显示这个路径页面中的内容(一般都是转发当前页面的路径)
imageUrl:"https://www.baidu.com/img/bd_logo1.png?where=super"
}
}
注意:转发的路径之前一定不要忘了加/
上拉触底案例:
上拉加载,当前页面值加一
新旧数组的追加(新数据追加到就数组中,一起赋值给旧的数组)
this.setData({ msgList: [...this.data.msgList,...newArr] }) onReachBottom: function () { console.log('触底了!') // 先让页码值加一 this.setData({ page:this.data.page + 1 }) // 获取下一页的数据 // 先定义一个数组,然后没加载一页,数值一直自增 const newArr = [] for(let i = 1;i<=10;i++){ const c = (this.data.page - 1 ) * 10 + i; newArr.push(c) } // 在页面快要触底的时候才会触发这个函数,然后打印一下下一页的数据 // console.log(newArr) // 为旧数组重新赋值 this.setData({ msgList: [...this.data.msgList,...newArr] }) },
onTabItemTap(Object)(只要tab栏被点击的时候就会触发这个函数)
在全局的app.json文件中写上,配置tabBar。默认position是bottom,设置为top
"tabBar": {
"position":"top",
"list": [{
"pagePath": "pages/main/main",
"text": "main"
},{
"pagePath": "pages/home/home",
"text": "home"
}]
},
在点击跳转到哪个页面的时候监听,那就在哪个页面中设置 onTabItemTap(obj)事件
打印出一个对象,对象里面就是上面表格中列举出的三个属性(index,pagePath,text)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。