在小程序中,JSON扮演的静态配置的角色。javascript
小程序配置 app.jsonphp
{ "pages": ["pages/index/index", "pages/logs/logs"], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" } }
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.htmlcss
若是小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏能够切换页面),能够经过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。html
其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每一个项都是一个对象java
{ "pages": ["pages/index/index", "pages/logs/index"], "tabBar": { "list": [ { "iconPath": "assets/fonts/首页.png", "selectedIconPath": "assets/fonts/home.png", "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/logs/logs", "text": "日志" } ] } }
tabBar 还有其余属性json
颜色仅支持十六进制,定位仅支持top和bottom,其中top时不支持图标。小程序
{ "tabBar": { "color": "#ff00ff", "selectedColor": "#0000ff", "backgroundColor": "#00ff00", "position":"bottom" } }
每个小程序页面也可使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项微信小程序
页面配置中只能设置 app.json 中 window 对应的配置项,以决定本页面的窗口表现,因此无需写 window 这个属性。api
WXML 充当的就是相似 HTML 的角色。数组
<view class="container"> <view class="userinfo"> <button wx:if="{{!hasUserInfo && canIUse}}">获取头像昵称</button> <block wx:else> <image src="{{userInfo.avatarUrl}}" background-size="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view>
block标签的做用是直接解析里面的内容,不解析自身block标签。
WXSS 具备 CSS 大部分的特性,小程序在 WXSS 也作了一些扩充和修改。
新增了尺寸单位。在写 CSS 样式时,开发者须要考虑到手机设备的屏幕会有不一样的宽度和设备像素比,采用一些技巧来换算一些像素单位。WXSS 在底层支持新的尺寸单位 rpx ,开发者能够免去换算的烦恼,只要交给小程序底层来换算便可,因为换算采用的浮点数运算,因此运算结果会和预期结果有一点点误差。
提供了全局的样式和局部样式。和前边 app.json, page.json 的概念相同,你能够写一个 app.wxss 做为全局样式,会做用于当前小程序的全部页面,局部页面样式 page.wxss 仅对当前页面生效。
此外 WXSS 仅支持部分 CSS 选择器
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
==iPhone6 1rpx = 0.5px 1px = 2rpx==
<view>{{ msg }}</view> <button bindtap="clickMe">点击我</button>
Page({ data:{ msg: '小程序' }, clickMe() { this.setData({msg: 'Hello World'}) } })
更详细的资料:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
小程序的运行环境分红渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工做在渲染层,JS 脚本工做在逻辑层。
小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,因此渲染层存在多个WebView线程,这两个线程的通讯会经由微信客户端(Native)作中转,逻辑层发送网络请求也经由Native转发。
微信客户端在打开小程序以前,会把整个小程序的代码包下载到本地。
紧接着经过 app.json 的 pages 字段就能够知道你当前小程序的全部页面路径。
整个小程序只有一个 App 实例,是所有页面共享的,具体内容查看注册程序 App https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/app.html
小程序提供了丰富的组件
https://developers.weixin.qq.com/miniprogram/dev/component/
<navigator url="/page/navigate/navigate?title=navigate" hover-class="navigator-hover" > 跳转到新页面 </navigator> <navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover" > 在当前页打开 </navigator> <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover" > 切换 Tab </navigator>
为了让开发者能够很方便的调起微信提供的能力,例如获取用户信息、微信支付等等,小程序提供了不少 API 给开发者去使用。
wx.scanCode({ success: (res) => { console.log(res) } })
https://developers.weixin.qq.com/miniprogram/dev/api/index.html
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,能够构建出页面的结构。
<!--wxml--> <view>{{message}}</view>
// page.js Page({ data: { message: 'Hello MINA!' } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/data.html
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<!--wxml--> <view wx:for="{{array}}">{{item}}</view>
// page.js Page({ data: { array: [1, 2, 3, 4, 5] } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/list.html
如不提供 wx:key,会报一个 warning
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
Page({ data: { objectArray: [ {id: 5, unique: 'unique_5'}, {id: 4, unique: 'unique_4'}, {id: 3, unique: 'unique_3'}, {id: 2, unique: 'unique_2'}, {id: 1, unique: 'unique_1'}, {id: 0, unique: 'unique_0'} ] } })
<!--wxml--> <view wx:if="{{view == 'WEBVIEW'}}">WEBVIEW</view> <view wx:elif="{{view == 'APP'}}">APP</view> <view wx:else="{{view == 'MINA'}}">MINA</view>
// page.js Page({ data: { view: 'MINA' } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/conditional.html
wx:if 是惰性的,若是在初始渲染条件为 false,框架什么也不作,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
通常来讲,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。所以,若是须要频繁切换的情景下,用 hidden 更好,若是在运行时条件不大可能改变则 wx:if 较好。
<view hidden="{{hidden}}"> 内容 </view>
<!--wxml--> <template name="staffName"> <view> FirstName: {{firstName}}, LastName: {{lastName}} </view> </template> <template is="staffName" data="{{...staffA}}"></template> <template is="staffName" data="{{...staffB}}"></template> <template is="staffName" data="{{...staffC}}"></template>
// page.js Page({ data: { staffA: {firstName: 'Hulk', lastName: 'Hu'}, staffB: {firstName: 'Shang', lastName: 'You'}, staffC: {firstName: 'Gideon', lastName: 'Lin'} } })
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html
WXML 提供两种文件引用方式import和include。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/import.html
<!-- item.wxml --> <template name="item"> <text>{{text}}</text> </template>
在 index.wxml 中引用了 item.wxml,就可使用item模板:
<import src="item.wxml" /> <template is="item" data="{{text: 'forbar'}}" />
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,能够构建出页面的结构。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/
<!--wxml--> <wxs module="m1"> var msg = "hello world"; module.exports.message = msg; </wxs> <view>{{m1.message}}</view>
页面输出:
hello world
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
<view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
Page({ tapName(event) { console.log(event) } })
事件绑定的写法同组件的属性,以 key、value 的形式。
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>
须要在捕获阶段监听事件时,能够采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,点击 inner view 会前后调用handleTap二、handleTap四、handleTap三、handleTap1。
<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>
#box2{ height: 100px; width: 100px; background: blue; } #box2:hover{ transform: rotate(180deg) scale(.5, .5); background: red; transition: background 2s ease, transform 2s ease-in 1s; }
// app.wxss 在主页面引入,page页面就均可以使用了 @import './assets/animate.wxss';
<view class='{{a}}'></view>
this.setData({ a : ['box', 'animated', 'fadeOutRight'] })
https://developers.weixin.qq.com/miniprogram/dev/api/wx.createAnimation.html
<button bindtap="fn">动画</button> <view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx;position: absolute;top:1000rpx;" ></view>
data: { animationData: {} }, fn() { const animation = wx.createAnimation({ duration: 3000 }) this.animation = animation animation.scale(2, 2).rotate(45).step().width(400).top(10).step() this.setData({ animationData: animation.export() }) }
step方法表示动画完成。一组动画中的全部动画会同时开始,一组动画完成后才会进行下一组动画。
导出动画队列。export 方法每次调用后会清掉以前的动画操做。
鼠标右键->新建组件,会生成一组文件。
// components/toast/toast.js Component({ //组件的属性列表 properties: { str : String }, //组件的生命周期函数 lifetimes: { attached() { // 在组件实例进入页面节点树时执行 console.log('attached:', this.properties.str); }, detached() { // 在组件实例被从页面节点树移除时执行 console.log('删除') } }, // 组件的初始数据 data: { }, // 组件的方法列表 methods: { show(){ } } })
// components/toast/toast.wxml <view> 传过来的属性:{{str}} </view>
// pages/mine/mine.json { "usingComponents": { "toast":"/components/toast/toast" } }
// pages/mine/mine.wxml <toast id="abc" str="hello"></toast>
// pages/mine/mine.js Page({ data: { }, fn(){ this.toast = this.selectComponent("#abc"); this.toast.show(); } })
page页的生命周期:https://developers.weixin.qq.com/miniprogram/dev/guide/framework/page-life-cycle.html
page页生命周期钩子函数的示例代码:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
component页的生命周期:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html
组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。
其中,最重要的生命周期是 created attached detached ,包含一个组件实例生命流程的最主要时间点。
==自小程序基础库版本 2.2.3 起,组件的的生命周期也能够在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。==
Component({ lifetimes: { attached() { // 在组件实例进入页面节点树时执行 }, detached() { // 在组件实例被从页面节点树移除时执行 }, }, // 如下是旧式的定义方式,能够保持对 <2.2.3 版本基础库的兼容 attached() { // 在组件实例进入页面节点树时执行 }, detached() { // 在组件实例被从页面节点树移除时执行 }, // ... })
在小程序中全部页面的路由所有由框架进行管理。
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html
调用 API wx.navigateTo
保留当前页面,跳转到应用内的某个页面。可是不能跳到 tabbar 页面。
wx.navigateTo({ url: 'test?id=1' }) // test.js Page({ onLoad(option) { console.log(option.query) } })
使用组件
<navigator open-type="navigateTo"/>
调用 API wx.redirectTo
关闭当前页面,跳转到应用内的某个页面。可是不容许跳转到 tabbar 页面。
wx.redirectTo({ url: 'test?id=1' })
使用组件
<navigator open-type="redirectTo"/>
调用 API wx.navigateBack
关闭当前页面,返回上一页面或多级页面。
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码 // 此处是A页面 wx.navigateTo({ url: 'B?id=1' }) // 此处是B页面 wx.navigateTo({ url: 'C?id=1' }) // 在C页面内 navigateBack,将返回A页面 wx.navigateBack({ delta: 2 })
使用组件
<navigator open-type="navigateBack">
用户按左上角返回按钮
调用 API wx.switchTab
跳转到 tabBar 页面,并关闭其余全部非 tabBar 页面
{ "tabBar": { "list": [ { "pagePath": "index", "text": "首页" }, { "pagePath": "other", "text": "其余" } ] } }
wx.switchTab({ url: '/index' })
使用组件
<navigator open-type="switchTab"/>
用户切换 Tab
调用 API wx.reLaunch
关闭全部页面,打开到应用内的某个页面
wx.reLaunch({ url: 'test?id=1' })
使用组件
<navigator open-type="reLaunch"/>
能够将一些公共的代码抽离成为一个单独的 js 文件,做为一个模块。模块经过 module.exports 能对外暴露接口。
// common.js function sayHello(name) { console.log(`Hello ${name} !`) } module.exports.sayHello = sayHello
const common = require('common.js') Page({ helloMINA() { common.sayHello('MINA') } })
在 JavaScript 文件中声明的变量和函数只在该文件中有效;不一样的文件中能够声明相同名字的变量和函数,不会互相影响。
经过全局函数 getApp 能够获取全局的应用实例,若是须要全局的数据能够在 App 中设置,如:
// app.js App({ globalData: 1 })
// a.js // Get the app instance. const app = getApp() // Get the global data and change it. app.globalData++
// b.js // 若是是从a跳转到b,那么此次输出的是2 console.log(getApp().globalData)
每一个微信小程序须要事先设置一个通信域名,小程序只能够跟指定的域名与进行网络通讯。包括普通 HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通讯(wx.connectSocket)
==跳过域名校验==
在微信开发者工具中,能够临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书 选项,跳过服务器域名的校验。此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
wx.request({ url: 'test.php', // 仅为示例,并不是真实的接口地址 data: { x: '', y: '' }, header: { 'content-type': 'application/json' // 默认值 }, success(res) { console.log(res.data) } })
https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html
每一个微信小程序均可以有本身的本地缓存
==单个 key 容许存储的最大数据长度为 1MB,全部数据存储上限为 10MB。==
wx.setStorage({ key: 'key', data: 'value' })
try { wx.setStorageSync('key', 'value') } catch (e) { }
wx.getStorage({ key: 'key', success(res) { console.log(res.data) } })
const value = wx.getStorageSync('key')
wx.clearStorage({ success(){} })
wx.clearStorageSync()
wx.removeStorage({ key: 'key', success(res) { console.log(res.data) } })
wx.removeStorageSync('key')
wx.showToast({ title: '成功', icon: 'success', duration: 2000 })
wx.showModal({ title: '提示', content: '这是一个模态弹窗', success(res) { if (res.confirm) { console.log('用户点击肯定') } else if (res.cancel) { console.log('用户点击取消') } } })
显示 loading 提示框。需主动调用 wx.hideLoading 才能关闭提示框
wx.showLoading({ title: '加载中', }) setTimeout(function () { wx.hideLoading() }, 2000)
wx.showActionSheet({ itemList: ['A', 'B', 'C'], success(res) { console.log(res.tapIndex) }, fail(res) { console.log(res.errMsg) } })
微信小程序固然还提供其余能力,具体应查看官方文档。