标签:打开 认知 hid 响应 背景 线程 error 声明 微信
最近工作正好有闲暇时间,根据公司安排先前期学习调研一下“微信小程序”,以供后期解决相关的运营需求,而本篇文章就是我对此次学习的一次总结。
个人认为在样式、功能、使用方式上接近传统APP并依赖于微信运行环境的 H5页面就是所谓的“微信小程序”。
微信小程序对比传统的 APP,它无需安装,在微信环境中可直接运行,并且依附于微信的生态圈,所以可以被更快速,方便,高效的推广。
学习“微信小程序”,可以打开“微信公众平台·小程序”平台,里面有非常详细的讲解。
https://developers.weixin.qq.com/miniprogram/dev/
在这个页面中,你可以从“介绍”、“设计”、“开发”、“运营”、“数据”等各个方面对小程序进行一个全面整体的认知。
若你是位“开发者”,那么应该专注学习“设计”,“开发”这两个方面。在“设计”方面你将学会小程序的交互和更棒的用户体验方面。而在“开发”中你将从“简易教程”、“框架”、“组件”、“API”、“工具”等全方面学习如何开发一款小程序应用。
如果有其它疑问,也可以在 社区 中进行反馈交流。
首先,你需要有一个“微信小程序”的账号。通过下面的链接,打开“微信公众平台”,然后点击最上面的“立即注册”,接着选择“小程序”。
https://mp.weixin.qq.com/
目前小程序的开放范围主要有“个人”、“企业”、“政府”、“媒体”、“其它组织”这几个。
如果你是企业级应用,可以直接在企业的微信公众号中直接添加“微信小程序”,从而无需注册。
有了小程序账号后,就可以登录“微信公众平台”,进入“微公众信平台·小程序”后台。
在“微公众信平台·小程序”后台中我们便可以根据流程提示开始新建一个小程序项目,小程序项目新建完成后,可以通过左侧栏目中的 “设置” - “开发设置” 拿到该小程序的 “AppID”,这一步至关重要,因为我们后面通过开发者工具新建的项目就需要填入 “AppID”。
“AppID” 相当于小程序平台的一个身份证 ,后续建立小程序项目,或者腾讯云服务都会使用到它,如果没有 “appID”,也可以使用开发工具上的测试号。
“微信小程序”的开发需要特定的开发工具,通过“微信开发者工具”我们可以编译、调试、预览、上传、发布小程序页面,同时还可以管理微信小程序的授权状态等。
下载 > 微信开发中工具
“微信开发者工具”分为 “beta版” 与 正式版。一般我们使用的都是正式版,而像Git
,NPM
之类新功能目前只有“beta版“才支持。
“微信开发者工具”下载安装完成后,可以选择建立“小程序项目”,然后输入小程序的名称,路径以及 “appID”,然后点击“确定”即可。
“微信开发者工具”不仅可以开发小程序项目,还可以开发“插件”、“代码片段”等。
“微信开发者工具”主要有以下几个重要功能点:
https://developers.weixin.qq.com/miniprogram/dev/devtools/debug.html (更多开发工具的介绍)
“微信开发者工具”常用快捷键:
键名 | 说明 |
---|---|
Ctrl+B | 编译项目(焦点在开发工具中) |
Ctrl+R | 编译项目(焦点不在开发工具中) |
Ctrl+Shift+P | 预览项目 |
Shift+Alt+F | 格式化代码 |
下面是一个小程序完整的目录结构图 (请右击查看大图)。
通过观察上图的目录与文件,你会发现小程序的代码主要有以下几个文件类型构成:
.json
文件是小程序的配置文件。
在小程序中配置文件按照应用范围又分为以下主要四种:
project.config.json
它是开发者工具和小程序项目的共同配置文件,它可以在多个开发者中维护统一的开发设置和开发环境。例如编辑器的颜色、ES6转ES5、上传代码时自动压缩、是否校验不合法域名、版本库等等。
当新的开发者下载了开发者工具后,只需要将团队中的 project.config.json
文件拷贝到本地小程序的根目录中即可。
https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html (更多关于project.config.json)
app.json
它是整个小程序应用的全局配置文件,可以设置小程序的页面、窗口、tab栏、网络超时、debug、插件、分包、多线程等。
其中常用到的字段是 pages
、window
以及 tabBar
。
pages
用于配置小程序的页面路径,其值是一个数组,数组中的第一个元素就是小程序的主页,并且在开发工具中新增一个路径时,编辑器会自动创建对应页面的目录以及文件。
{
"pages":[
"pages/index/index",
"pages/logs/logs"
]
}
PS:路径中的文件名 "index" 与 "logs" 不要加扩展名,小程序的编译工具会自动寻找对应的文件类型进行处理。
window
用于配置窗口的样式以及标题等。
属性 | 说明 | 取值 |
---|---|---|
navigationBarBackgroundColor | 导航栏背景颜色 | HEX |
navigationBarTextStyle | black / white | |
navigationBarTitleText | 导航栏标题文字内容 | text |
backgroundColor | 窗口的背景色 | HEX |
tabBar
也是比较常用的配置,用于设置 tab栏的位置(上、下)以及按钮的文字,样式和 icon。
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE (更多关于app.json)
pages.json
每个页面都有自己的 pages.json
文件。
pages.json
文件可以在全局配置 app.json
的基础上对页面进一步的进行设置。例如导航栏的颜色,标题文字等。
另外 pages.json
还可以通过 usingComponents
字段来声明当前页面引用了那些自定义组件。
https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#%E9%A1%B5%E9%9D%A2%E9%85%8D%E7%BD%AE (更多pages.json)
componet.json
componet.json
是自定义组件的配置文件。
{
"component": true, // 自定义组件声明
"usingComponents": {} // 可选项,用于引用别的组件
}
你可以将 WXML
等同于传统 WEB开发时用到的 html
,他们都是用来描述页面的结构骨架,不同的是 HTML文件由一个个html标记(Tag)组成,而 WXML则是有与之类似的“组件”组成。
除了在结构特性上与 HTML一致外,WXML 文件还支持特定的模版语法,数据绑定,事件处理、自定义模版等等。
同样的 WXML也可以分为页面的 WXML文件,自定义模版的 WXML文件以及自定义组件中的 WXML文件。
wxss
具有大部分 CSS的功能,所以你可以像 CSS一样去编写小程序的样式文件。
对于整个小程序公用的样式,可以放置在 app.wxss
文件中,而对于页面专用的样式,则写到对应页面的 pages.wxss
文件中,其次便是自定义组件也会含有自己的 component.wxss
文件。
在小程序的脚本文件中,我们可以处理事件,响应用户请求,获取接口数据,改变数据状态...并且小程序的脚本文件默认支持commonJS
规范,可以直接通过 require()
来导入模块,module.exports
导出模块,就编码的角度而言,与我们普通编写脚本文件并没有什么太大的区别,如果非要说区别的话,就是小程序中的脚本可以调用小程序内置的一些API接口,例如授权,支付等。
同样的app.js
用于存放全局的数据和方法,而 pages.js
则存放每个页面自己的数据和方法,对于组件中的脚本文件而言,它保存的则是组件自己的数据和方法
(请右击查看大图)
当微信客户端打开一个小程序的时候,会将整个小程序的代码包下载到本地,然后通过读取 app.json
文件获取页面的路径,并将第一条路径作为首页,并根据 app.json
中的配置来初始化小程序窗口的样式。
紧接着,微信客户端再将 app.js
装载进来,执行其中的 App()
方法,实例化一个小程序对象(整个微信小程序也只有一个这样的实例对象,并且全部页面共享该对象,你可以在每个页面使用 getApp()
方法来获取)。
当小程序实例对象创建完成后,会触发生命周期中的 onLaunch()
函数,然后继续装载小程序中的每个页面(默认便是首页),在装载页面的时候,同样的会先装载 pages.json
的代码,用来初始化页面与窗口的样式,然后再装载 WXML
文件以及其使用到的资源(wxs,模版、组件)来生成页面结构,一切就绪再加载 wxss
获取页面样式,最后再去装载 .js
的脚本文件。
当最后的 .js
文件也被装载进来后, 就会调用脚本中的Page()
构造函数,还回一个页面的实例对象,页面实例对象创建好后,就会根据其中的 data 数据与 WXML文件中的内容 一起渲染出最终的页面,最后页面渲染完成后,并且在这一过程中,页面实例会根据不同时期的状态触发不同的页面生命周期函数。
明白小程序的基本执行流程,对后面了解小程序执行的生命周期非常有帮助。
(请右击查看大图)
小程序开发还是很简单的,像一些 API接口以及组件的使用,在开发手册上都有详细列举,所以这里我就将我个人认为小程序中比较常用或者是比较重要(跟传统web开发有点区别)的地方单独记录下来。
WXSS
是基于 CSS 改进而来的,所以大部分的 CSS写法也可以套用在 WXSS
上,这里主要对这两者重点的区别加以说明。
rpx
新增的相对单位,rpx
默认将屏幕划分为750个单位。
注意的是:px
在小程序中依然也可以用。
选择器
WXSS 支持的选择器相比 CSS要少一些,但是主流的:类、ID、元素,分组、伪类(after,before)、伪元素(:hover 这里表示元素选中)等选择器都支持。
模块化样式
支持 @import "path"
导入样式。
内嵌样式
小程序中组件支持通过 style
属性来内嵌内联样式,并且还可以通过表达式来接收绑定的数据。
<view style="font-size:{{fontSize}}pt"></view>
背景图
wxss 不支持本地图片(相对路径图片)作为背景图,对于需要内嵌在 wxss文件中的图片,请使用 base64
或者是网上的图片。
不过,image 组件支持本地图片
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html (更多关于WXSS)
WXML文件也称之为“WXML模版”文件,它与 HTML文件结构相同,都是有许多结构标记组成,只是在小程序中,这些标记被称之为“组件”。
WXML文件与 HTML文件的不同在于WXML模版支持特定的模版语法,可以直接再模版中进行运算处理。
表达式
WXML支持通过 {{variant}}
表达式来获取对应页面脚本中 data
定义的数据。
#page.wxml
<view>{{names}}</view>
#page.js
Page({
data:{
names:"xiaoming"
}
})
{{}}
表达式不仅可以读取变量的值,还支持一些常规的运算操作,比如“算数运算”、“三元运算”、“比较运算”、“字符串运算”等,另外还可以在表达式中定义数组、对象等类型的值。
{{a + b}} + {{c}}
{{flag ? true : false}}
{{length > 5}}
{{"hellow" + name}}
{{[zero, 1, 2, 3, 4]}}
{{for: a, bar: b}} | {{...obj1, ...obj2, e: 5}} | {{name,age}}
条件判断
微信小程序支持在WXML模版文件中进行条件判断。
<view wx:if="{{variant > 70 && variant >=90}}">...</view>
<view wx:elif="{{variant <70 && variant >=30}}">...</view>
<view wx:else="{{variant < 30}}">...</view>
循环遍历
WXML模板同样还支持循环遍历。
<view wx:for="{{arrs}}">
{{item}} - {{index}}
</view>
其中 arrs
是页面脚本 data
中定义的一个数组,而 item
与 index
都是循环体中固定的写法,分别表示了每次循环“项”和每次循环的“索引”。
列表渲染
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i" wx:for-index="a">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j" wx:for-index="b">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
wx:for-item
与 wx:for-index
用来解决多层循环嵌套item
与 index
重复的问题。
另外,还有一个 wx:key
的控制属性,它的取值有 String
与 *this
两种。
String
可以是 for循环中每个 item自身的 property
的名称,这个 property
的值要保证在整个循环遍历中,相对其它的 item property
的值都是唯一的。
*this
则是代表每次循环的 item本身,这种表示需要 item 本身是一个唯一的字符串或者是数值。
wx:key
要求唯一的原因是当数据改变触发渲染时,列表中通过 wx:key
指定的选项,不会被重新渲染只会改变位置顺序,也就是说不会被移出重新插入,从而能够保持一种固定的状态。这样也更加的节省性能。当然如果你非常确定你的列表是静态的并且不会发生改变,那么也无需使用该属性。
block
当我们在模版中使用控制属性,总需要将其挂载到一个组件上,这往往就会让不需要组件加入到页面渲染中。
为了解决这个问题,小程序提供了另一个特殊的组件:<block> </block>
,使用 block
以作为控制属性的载体,并切不会被渲染到页面上。
<block wx:for="" >
<view wx:if="" ></view>
</block>
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/ (更多关于模版以及模版语法)
WXML支持两种模版类型,一种是通过 <template>
组件定义的“动态模版”,我们可以向“动态模版”中传入数据,并运用表达式、模版语法、控制属性等进行运算。另一中就是“静态模版”,通过 <include>
组件将静态的 wxml 文件引入到指定的位置中。
动态模版
定义模版
<template name="example-tem">
<view wx:for="{{arrs}}"></view>
</template>
调用模版
<template is="example-tem" data="{{arrs:[1,2,3]}}"
外部导入模版并调用
<import src="template/example-tem" /> #引入外部模版
<template is="example-tem" data="{{arrs:[1,2,3]}}" #使用模版
静态模版
总结
对比 import
,include
只是单纯的将一个模版中的所有组件内容拷贝到你使用 include
的位置处(需要注意的是模版中的 template
与 wxs
不能被拷贝)。除此之外,import
有自己的作用域,如果要传递数据到对应的 template内,须要借助 data
属性。
微信小程序支持类似 vue的MVVM模式,即数据(逻辑层)与视图(渲染层)相互分离,当数据发生改变的时候,可自动的刷新视图。
使用起来也非常简单,通过模版的表达式结合逻辑层的 setData
方法既可以使用。
示例:
<view>{{names}}</view>
Page({
data:{
names:"xiaoming"
},
onLoad:function(){
this.setData({names:"xiaohong"});
}
})
事件绑定(支持事件冒泡)
bind:eventName
事件绑定(不支持事件冒泡)
catch:eventName
事件捕获(可以再冒泡)
capture-bind:eventName
事件捕获(不会冒泡)
capture-catch
“自定义组件”可以认为是具有特定可复用功能的最小型页面,“自定义组件”与小程序内置组件一样可以定制自己的功能,数据还有属性。
“自定义组件”的目录结构以及代码构成与普通页面完全一致,其中 *.js
是自定义组件的数据方法文件,*.json
是配置文件。*.wxml
是自定义组件的结构模版文件,*.wxss
是自定义组件的样式文件。
首先建立组件的目录,然后创建以下几个文件(比如这里以assambley)为例:
assembly:
- assembly.wxml
- assembly.wxss
- assembly.js
- assembly.json
接着在 assembly.wxml
、assembly.wxss
中编写好你的结构与样式代码,在你的JS文件中调用 Component()
构造函数,来实例化一个组件实例:
Component({
//行为
behaviors:[],
//数据
data: {
names: Math.random()
},
//属性
properties: {
nowIn: String
},
//方法
methods: {
showData: function(e) {
let radomNumber = Math.random();
this.setData({ names: radomNumber });
//自定义触发的事件
this.triggerEvent('assmbleySignal', this.data.names);
}
},
//生命周期函数
attached: function() {
this.triggerEvent('assmbleySignal', this.data.names);
}
});
最后在 assembly.json
中进行组件的声明。
{
"component":true
}
这样一个组件就定义完成了,使用的时候,只需要在用到的页面或者是其它组件中,对它们的配置文件添加以下配置即可(例如这里以index页面为例)
#index.json
"usingComponents": {
"assembly": "/pages/component/assembly/assembly"
}
需要注意的是,在 properties
中自定义属性的时候要用驼峰命名,但是应用在组件上的时候要记得用小写并且采用 “-” 分割,例如:
properties:{
nowIn:String
}
使用:
<assembley now-in="index" bind:assmbleySignal="onAssmbleySignal"></assembly>
PS:自定义事件方法 onAssmbleySignal
在index.js中定义。
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component (更多关于组件)
通过 behaviors
(行为)可以让多个组件之间的“属性”、“数据”、“方法”、“生命周期”实现共享。
并且 behavior
中还可以引用其它的 behaviors
。 属性会按照先后进行覆盖,而数据虽然也会覆盖,但是如果类型是对象则会进行合并,生命周期函数也会顺序触发,多个组件调用同一个 behaviors
则生命周期函数也只会执行一次。
module.exports = Behavior({
behaviors:[],
properties: {
behavior_attr: String
},
data: {
behavior_data: {}
},
methods: {
behavior_method: function() {
console.log('behavior_method')
}
},
attached: function() {
console.log('behavior-attached');
}
});
组件中调用:
var myBehavior = require('./behavior');
Component({
behaviors: [myBehavior],
data: {
names: Math.random()
},
properties: {
nowIn: String
},
methods: {
showData: function(e) {
console.log('component showData');
}
},
lifetimes: {
attached: function() {
console.log('component attached');
}
}
});
behaviors
除了自定义的还有内置的 behaviors
var myBehavior = require('./behavior');
Component({
behaviors: ['wx://form-field'],
data: {
names: Math.random()
},
properties: {
nowIn: String
}
});
小程序中的生命周期函数主要有以下几类:
小程序应用的生命周期
状态名 | 说明 |
---|---|
onLuanch | 小程序实例初始化 |
onShow | 小程序启动,或从后台进入前台显示 |
onHide | 小程序隐藏,或从前台进入后台 |
onError | 当小程序发生脚本错误,或者 api 调用失败时 |
onPageNotFound | 当小程序出现要打开的页面不存在的情况 |
页面的生命周期
状态名 | 说明 |
---|---|
onLoad | 页面资源加载完毕 |
onShow | 页面显示(但不代表页面已经绘制完毕) |
onReady | 页面初次渲染完成 |
onHide | 页面隐藏 |
onUnload | 页面被卸载 |
PS:需要注意的是小程序中tab切换只是多个页面的显示隐藏切换,而不会重新加载,如果使用 navigator
等跳转则每次都会重新加载,显示,渲染。
组件的生命周期
状态名 | 说明 |
---|---|
created | 创建组件实例,注意此时无法使用 this.setData 方法 |
attached | 组件实例进入页面节点树时执行 |
ready | 组件布局完成后执行,此时可以获取节点信息(使用 SelectorQuery ) |
moved | 组件实例被移动到节点树另一个位置时执行 |
detached | 组件实例被从页面节点树移除时执行 |
生命周期函数的默认流程
假设一个小程序(含有页面,组件)被打开并且正常运行,那么它一般都会经过以下生命周期的改变流程:
实际上小程序中还存在另一种生命周期:“行为 Behaviors
的生命周期,不过其常用的也就 attached
,因此可以再需要的时候自己去查阅文档。
在小程序中,JS文件,模版文件(动态模板),wxs文件都有自己的独立作用域,模块的导入导出遵循 CommonJS 规范。
如果想实现多页面数据共享或者是跨页面数据交互,可以采用以下方式:
golbalData
对象Storage
实现通过 canIUse
可以判断小程序的API,回调,参数,组件等是否在当前版本可用。
返回值一般而言都是布尔值。
wx.canIUse('openBluetoothAdapter')
wx.canIUse('getSystemInfoSync.return.screenWidth')
wx.canIUse('getSystemInfo.success.screenWidth')
wx.canIUse('showToast.object.image')
wx.canIUse('onCompassChange.callback.direction')
wx.canIUse('request.object.method.GET')
或者你也可以基于能力去判断:
if(this.setData) //....
开发者通常向用户发起权限授权主要是通过 wx.authorize
这个接口实现,但需要注意的是如果调用的是“用户信息”,则需要使用特定的按钮组件来引导用户操作,单纯的使用 scope:scope.userinfo
是无法弹出授权弹窗。
<button open-type="getUserInfo">允许获取个人信息</button>
另外,每个权限都有对应的 API接口可以获取该权限的的状态以及详情,例如:wx.getUserInfo、wx.getLocation
等..
如果想查看全部权限的状态,可以通过另一个 API接口获取当前的权限列表:wx.getSetting
。
对于用户拒绝授权的接口并且短时间无法再次打开,我们可以调用 wx.openSetting
来让用户自己手动操作。
WXS
代码可以编写在 WXML 文件中的 .wxs
为后缀的文件里。
WXS
可以看作成小程序自己定义的一套脚本,它的语法非常类似于原生 JS,但是运行环境并不相同,所以 有些 JS的对象或方法无法使用,也不能调用小程序的 API,其主要目的还是为增强 WXML的模版处理能力。
不论是 WXML中的 wxs内的代码,还是独立的 *.wxs
文件中的代码,它们都有独立的作用域。
实例:
<wxs module="mthodName">
function methodName(value){ return value.split(','); }
module.exports = methodName; //需要导出
</wxs>
调用模块中的方法
<view wx:for="{{methodName(names)}}"> //names是页面JS中的data配置的。
<text>{{item}}</text>
</view>
或者你可以单独将wxs中的脚本单独的保存在一个文件中,然后使用wxs引入。
<wxs src="methodName.wxs" module="methodName"></wxs>
<view wx:for="{{methodName(names)}}"> </view>
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/ (更多关于WXS)
https://github.com/tumobi/nideshop-mini-program (NideShop:基于Node.js+MySQL开发的开源微信小程序商城(微信小程序)
https://github.com/EastWorld/wechat-app-mall (微信小程序商城,微信小程序微店)
https://github.com/ecomfe/echarts-for-weixin (ECharts 的微信小程序版本)
https://github.com/sqaiyan/NeteaseMusicWxMiniApp (仿网易云音乐APP的微信小程序)
https://github.com/zce/weapp-demo (仿豆瓣电影微信小程序)
https://github.com/myvin/juejin (掘金小程序)
https://github.com/xiehui999/SmallAppForQQ (高仿手机QQ应用程序
https://github.com/liuxuanqiang/wechat-weapp-mall (微信小程序-移动端商城)
https://github.com/web-Marker/wechat-Development (微信小应用-小程序-demo-仿芒果TV)
https://github.com/lanshan-studio/wecqupt (We重邮 - 微信小程序 )
https://github.com/RebeccaHanjw/weapp-wechat-zhihu (微信中的知乎--微信小程序 demo)
https://github.com/eyasliu/wechat-app-music (微信小程序:音乐播放器 )
https://github.com/skyvow/m-mall (微信小程序-小商城前台(基于 WeUI.wxss、ES6 前端技术开发...)
https://github.com/sesine/wechat-weapp-movie (电影推荐 - 微信小程序)
https://github.com/ahonn/weapp-one (仿 「ONE · 一个」 的微信小程序)
https://github.com/kraaas/timer (小程序版番茄时钟)
https://github.com/hijiangtao/weapp-newsapp (微信小程序-公众号热门文章信息流)
https://github.com/zhengxiaowai/weapp-github (微信小程序--github)
https://github.com/vace/wechatapp-news-reader (微信小程序 —— 新闻阅读器)
https://github.com/natee/wxapp-2048 (微信小程序2048)
在掌握小程序开发的基础只是后,后面我将会多做小程序的实战项目,掌握小程序的开发框架、收集小程序常用的插件、样式UI库,以及汇总小程序开发过程的问题收获。
最后,如果文章中存在错误或者是歧义的地方,也或者您有更好的建议,请务必跟我联系或者给我留言。
感谢您的批评指正!
标签:打开 认知 hid 响应 背景 线程 error 声明 微信
原文地址:https://www.cnblogs.com/HCJJ/p/9536135.html