IDE的选择
我自己选择的是微信小程序发布的开发工具-微信开发者工具
调试器
- console:控制台面板,在代码执行错误时会将错误信息显示在面板中。例如:console.log('aaa')
- sources:当前项目所有的脚本文件,但微信小程序框架会对脚本文件进行编译工作,开发者代码会被包裹在define函数中,对于page代码会在尾部require的主动调用
- network:请求和响应的相关信息
- appData:用于显示当前项目中的具体数据,时时反馈数据
- storage:显示当前项目使用本地存储的情况,可以使用wx.setStorage或者wx.setStorageSync将数据保存到手机本地存储中
- Wxml:用于帮助开发者查看Wxml转化后的界面(跟源程序中的wxml代码有所不同)
代码编辑快捷键
- ctrl+s:保存
- ctrl+,:打开设置
- alt+shift+f:代码格式化
- alt+up:上下移动一行
- shift+alt+up:向上复制
- ctrl+shift+enter:向当前行上方插入一行
- ctrl+end:移动到文件结尾
- ctrl+home:移动到文件开头
- ctrl+i:选中当前行
- shift+end:选择从光标到行尾
- ctrl+enter:向下插入一行
- ctrl+i:选中当前行
- shift+end:选择从光标到行尾
- shift+home:选择从行首到光标出
- ctrl+d:选中匹配
- ctrl+u:光标回退
- ctrl+:隐藏侧边栏
微信小程序架构分析
一般软件分为数据层、业务逻辑层、服务层、控制层、展示层、用户
微信小程序只是一套系统的展示层,主要展示系统的信息
主目录(项目描述文件)
- app.js:主逻辑文件
- app.wxss:主样式文件
- app.json:主配置文件
子目录(页面描述文件)
- xxx.js:页面逻辑文件
- xxx.wxss:页面样式文件
- xxx.json:页面配置文件
- xxx.wxml:页面结构文件
- 其他文件
配置文件详解
- app.json(主配置文件)
用于对当前项目进行全局配置,多用于设置页面路径、窗口表现、设置网络超时时间、多tab等,采用json的格式 - "pages":["a","b"..]
pages对应的是一个文件路径字符串的数组,如果没有将某个文件路径添加到该数组中,即使在代码中跳转到该页面,但是也不会显示,同时控制台也不会有任何提示的信息 "window"属性,设置窗口表现
"window": { "backgroundColor":"#00ff0f",//设置背景色,由16进制的rgb "backgroundTextStyle": "light",//设置背景字体颜色 "navigationBarBackgroundColor": "#00ff00", "navigationBarTitleText": "微创音", "navigationBarTextStyle": "black", "enablePullDownRefresh":true }
配置窗口底部tabBar
"tabBar": { "color": "#000000",//为选中时tabBar文字的颜色 "selectedColor": "#ff0000",//选中时 "borderStyle": "black",//窗口的上边框颜色,只支持black和white "backgroundColor": "#ffffff",//tabBar背景颜色 "list": [ {//每个tab列表项,最少2个,最多5个 "pagePath": "pages/index/index", "iconPath":"image/1.jpg",//设置的图片大小不能超过40kb "selectedIconPath":"image/2.jpg", "text": "测试一"//列表项的名称 }, { "pagePath": "pages/index/index", "iconPath": "image/1.jpg", "selectedIconPath": "image/2.jpg", "text": "测试二" } ] }
配置超时响应时间
"networkTimeout": { "request": 1,//设置wx.rquest接口的超时响应时间 "connectSocket": 1,//设置wx.connectSocket接口的响应时间 "uploadFile": 1,//设置wx.uploadFile接口的响应时间 "downloadFile": 1//设置wx.downloadFile接口的响应时间 }
- 设置debug模式,将调试信息以info的形式放置在控制台上
"debug":true
页面配置文件
页面配置文件的文件名与页面其他3个文件名相同,不用写window,会覆盖原来的相同配置
逻辑层js文件
- 提供app和page方法,用来进行程序和页面的注册
- 提供丰富的API,如扫一扫
- 每个页面有独立的作用域,并提供模块化能力
- 由于框架不是运行在浏览器中,js在web中能访问的document和window等js对象限制不能访问
- 开发者写的所有代码最终被打包成一份js,并在小程序启动的时候运行,直到小程序销毁
用APP函数注册小程序
每个小程序必须在app.js中进行程序注册,App函数的参数是一个json对象,可指定其程序的三个周期
- onLaunch:当小程序初始化完毕,会触发该函数,但全局只触发一次
- onShow:当小程序启动,或者从后台进入前台,会触发该函数
- onHide:当小程序从前台切换到后台
注意:这里的前后台指的是小程序是否在手机中展示出来
App({
onLaunch: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
// 获取用户信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
globalData: {
userInfo: null
}
})
用page函数注册页面
微信小程序中每个页面都需要使用page()函数进行注册
初始化数据
初始化数据位于data中,初始化数据作为页面的第一次渲染,data将会以json形式由逻辑层传递到视图层- motto:字符串值
- userInfo:空对象
视图层可以通过wxml对数据进行绑定,在wxml中就可以使用这两个变量
生命周期函数
- onLoad:页面加载完调用函数
一个页面只会调用一次,该函数的参数可以获取wx.navigateTo和wx.redirectTo以及<navigate/>中的query - onShow:页面显示时调用该函数,每次打开页面都会调用一次
- onReady:页面初次渲染完成调用,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互
- onHide:页面隐藏时调用该函数(当navigateTo或者底部tab切换时调用该函数)
- onUnload:页面卸载时调用该函数(当redirectTo或navigateBack的时候调用该函数)
- onPullDonwnRefresh:下拉刷新时调用该函数,监听用户下拉刷新事件。需要在config的window选项中开启enablePullDownRefresh。当处理完数据刷新后,wx.stopPullDownRefresh可以停止页面的下拉刷新
- onLoad:页面加载完调用函数
事件处理函数:
在视图层可以在组件中加入事件绑定,当达到触发事件时就会执行page中定义的事件处理函数页面js中的page函数 Page({ click:function(){ console.log("onclick"); }, 页面wxml中添加view的单击事件 <view bindtap="click">点击事件</view> //注意在单击事件bindtap中属性值必须跟page中的事件处理函数的名称一致
- 使用setData修改初始化数据
为了更新数据,在page对象中封装了一个setData函数
页面描述文件
微信小程序的视图层将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。视图层由页面描述文件和页面样式文件构成。
组件是视图的基本组成单元
数据绑定
页面中的动态数据军来自对应page中的data,用两个大括号,微信小程序在渲染页面时,发现{{motto}}就从index.js中的page函数的data属性中找motto,找到这个变量就把这个变量中的值渲染到对应的位置简单数据绑定
<view class="container"> <view class="content"> <!-- content:'微信小程序数据绑定内容', hiddencontent:'隐藏的内容', flag:false, num1:1, num2:2, user:{ name:"yanyi", age:18 } --> <text>{{content}}</text> </view> <view class="content" hidden="{{flag ? true :false }}"> <text>{{hiddencontent}}</text> </view> <view class="content"> <text>{{num1}}+{{num2}}={{num1+num2}}</text> </view> <view class="content"> <text>{{num1}}+{{num2}}={{num1+num2}}</text> </view> <view class="content"> <text>{{"hello"+user.name}}</text> </view> </view>
条件渲染
根据绑定表达式的逻辑值来判断是否渲染当前组件wx:if条件渲染,wx.elif,wx.else,需要添加在组件中,作为组件的属性使用
<view class="content" wx:if="{{flag}}"> <text>{{hiddencontent}}</text> </view>
block wx.if条件渲染
可以将多个组件包装到<block>标签中,然后在block标签中添加一个wx:if控制属性,block并不是一个组件,他仅仅是一个包装元素,不会被页面中作任何渲染,只能接受属性<!--使用block wx:if包装--> <block wx:if="{{flag}}"> <view class="content">view1</view> <view class="content"><text>view2</text></view> </block>
循环渲染
wx:for
注意:默认循环下index代表索引,item代表每个元素,可以通过重命名下标和变量名;使用wx.for-item=""可指定元素的变量名;使用wx.for-index可指定索引的变量名<!--for循环--> <view wx:for="{{students}}"> <text>{{index}}-{{item.name}}-{{item.age}}</text> </view> <!--for循环取别名--> <view wx:for="{{students}}" wx:for-index="num" wx:for-item="student"> <text>{{num+1}}-{{student.name}}-{{student.age}}</text> </view>
block wx:for包装for
<!--block包装for循环--> <block wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="i"> <block wx:for="{{[1,2,3,4,5,6,7,8,9]}}" wx:for-item="j"> <view wx:if="{{j>=i}}"> {{i}} * {{j}} = {{i*j}} </view> </block> </block>
使用<block>标签包装多个组件进行列表渲染
使用模板
如果某个组件的组合要反复使用到,就可以定义模板,然后之间使用这个模板;使用template标签,在定义好模板后使用<template is="模板名称" data="{{传入的数据}}"(data可以省略)>;模板拥有自己的作用域只能使用data传入的数据<!--定义模板--> <template name="bianli"> <block wx:for="{{nums}}" wx:for-item="i"> <block wx:for="{{nums}}" wx:for-item="j"> <view wx:if="{{j>=i}}"> {{i}}*{{j}}={{i*j}} </view> </block> </block> </template> <!--使用模板--> <template is="bianli" data="{{nums}}"></template>
引入其他页面文件
import方式引用文件定义的模板代码
import由作用域的概念,只会import源文件中定义的模板,而不会import源文件又使用import引用的源文件的模板<import src="template.wxml"/> <!--使用模板--> <template is="bianli" data="{{nums:[1,2,3,4,5,6,7,8,9]}}"></template>
include引用文件定义的除模板外的其他代码
可以将源文件中除了模板定义之外的其他代码全部引入,其引入方式相当于将源文件中的代码拷贝<include src="template.wxml"/> <!--使用模板--> <template is="bianli" data="{{nums:[1,2,3,4,5,6,7,8,9]}}"></template>
页面的事件
事件可以绑定在组件上,当事件触发时就会执行逻辑层中对应的事件处理函数,在调用事件处理函数时还可以将事件对象作为参数传递到处理函数中,事件对象可以携带信息
事件的类型
冒泡事件,当一个组件上的事件被触发时,该事件会向父节点传递
- touchstart:手指触碰
- touchmove:手指触碰后移动
- touchcancel:手指触碰动作被打断,如来电提醒,弹窗
- touchend:手指触摸动作结束
- longtap:手指触摸后,超过350ms再离开
除这些外,其他组件自定义事件都是非冒泡事件
- 非冒泡事件,当一个组件上的事件被触发时,该事件不会向父节点传递
事件的绑定
在组件的属性中定义一个绑定事件的属性,并设置该属性的值即可,作为组件的属性是以bind或catch开头再加上事件类型字符串;bind开头的事件绑定不会阻止冒泡事件向上冒泡,catch开头的事件绑定可以阻止冒泡事件向上冒泡wxml: <view class="container" bindtouchstart="write"> js中的page函数: write:function(event){ console.log(event); }
事件对象
一个object对象,展开该对象后可以看到有6个属性,其中4个属性又是独立的对象,可以继续展开- type属性
字符串,用于表示当前事件的类型 - timeStamp
整数,表示该页面打开到触发事件所经过的毫秒数 target属性
对象,表示触发事件的源组件- id
当前触发事件的组件的id - dataset
当前组件上有data-开头的自定义属性组成的集合 - offsetLeft,offsetTop
当前组件的坐标系统的偏移量
dataset集合使用比较多,通过这个集合可以获取组件中自定义数据的值
- id
- currentTarget属性
对象,表示事件绑定的当前组件,其属性与target属性的相同,在大多数情况下,两个属性的值都相同,即事件绑定的组件和触发事件的源组件使相同的。但是如果组件嵌套,并且外层组件和内层组件都定义了事件处理函数,这时触按内层组件时,外层组件的事件处理函数中,这两个属性的对象会不同.
currentTarget代表的外层组件,current代表的内层组件
<view class="content" bindtouchstart="write"> <text bindtouchstart="write">{{num1}}+{{num2}}={{num1+num2}}</text> </view>
touches属性
数组,用来保存触摸点信息,每个触摸点包括一下属性- pageX,pageY:距离文档左上角距离,文档左上角为原点
- clientX,clientY:距离页面可显示区域(屏幕出去导航条)左上角距离
- screenX,screenY:距离屏幕左上角的距离
- detail属性
对象,用来保存特殊事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息
- type属性
页面样式文件wxss
尺寸单位
- rpx
根据屏幕宽度进行自适应,规定屏幕宽为750rpx - rem
规定屏幕宽度为20rem
尽量使用这两种扩展来表示尺寸
样式导入
@import "xxx.wxss";导入外联样式表用;结束