微信小程序开发探究

前段时间比较流行的微信小程序,因为一直没有所谓内测码也没具体关注。拖到现在正好借组内分享的时机来仔细了解一下微信小程序。了解一个新的事物无外乎从是什么(本质),怎么用(具体用法),为什么用(优缺点)来学习,首先分析一下微信小程序是什么,听起来比较高大上,说实话原来我确实挺疑惑,到底这一套是什么开发机制,native?hybrid?纯h5?看网上各种教程上来就说api说语法,感觉不先理清楚是什么的问题就去搬api过来纯粹是耍流氓。

一、微信小程序是什么:    

言归正传,微信小程序的本质是什么?个人理解微信小程序本质还是一套前端框架,微信团队基于原来第三方h5页面在微信里只能通过h5实现原本可以由native实现的功能,例如上传图片等。进而采取的开放部分jsbridge的api来方便开发者。不过既然作为大厂肯定不会仅仅开放部分jsbridge的api就完了,顺便微信类似vue、react一样实现了一套自己的mvvm的框架就是目前的微信小程序。官方文档这样描述:框架提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,可以让开发者可以方便的聚焦于数据与逻辑上。

本质还是一套前端框架,代码最终将会打包成一份 JavaScript并在小程序启动的时候运行,直到小程序销毁。模版语法类似vue,接近原生的自定义标签。数据绑定和渲染类似vue的语法,不过是以wx:开头(vue 以v: 作为标识) 事件系统类似react一样定义了一套自己的事件系统。

二、微信运行环境:

微信小程序运行在三端:iOS、Android 和 用于调试的开发者工具

在 iOS 上,小程序的 javascript 代码是运行在 JavaScriptCore 中

在 Android 上,小程序的 javascript 代码是通过 X5 内核来解析

在 开发工具上, 小程序的 javascript 代码是运行在 nwjs(chrome内核) 中

页面的脚本逻辑是在JsCore中运行,JsCore是一个没有窗口对象的环境,所以不能在脚本中使用window等bom对象。所以类似jquery、zepto等通过window或者document来获得dom对象的库是不能用来使用的。

三、目录结构:

小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。

一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下:

app.js 逻辑部分,即全局变量或者方法

app.json 公共配置,包括页面配置等,顶部底部tab的设置,背景颜色等

app.wxss 公共样式表 可以被具体page样式覆盖

app.js代码(代码取自微信官方demo)和注释说明如下:

//app.js
 // 微信小程序就是调用微信开放jsbridge,来完成微信h开发中某些原本比较难的功能的特定的微信前端框架
 /**
 * app 即小程序的生命周期管理。 
 * */
 App({
 // 初始化
 onLaunch: function () {
  //调用API从本地缓存中获取数据
  var logs = wx.getStorageSync('logs') || []
  logs.unshift(Date.now())
  wx.setStorageSync('logs', logs)
 },
 // 全局方法或者变量,可在不同page中使用
 getUserInfo:function(cb){
  var that = this
  if(this.globalData.userInfo){
  typeof cb == "function" && cb(this.globalData.userInfo)
  }else{
  //调用登录接口
  wx.login({
   success: function () {
   wx.getUserInfo({
    success: function (res) {
    that.globalData.userInfo = res.userInfo
    typeof cb == "function" && cb(that.globalData.userInfo)
    }
   })
   }
  })
  }
 },
 globalData:{
  userInfo:null
 }
 })

app.json(文件中不允许有注释)示例如下:

微信小程序开发探究

{
 "pages":[
  "pages/index/index",
  "pages/logs/logs",
  "pages/swiper/swiper",
  "pages/input/input",
  "pages/form/form"
 ],
 "window":{
  "navigationBarBackgroundColor": "#ffffff",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "微信小程序",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light"
 },
 "tabBar":{
  "borderStyle": "white",
  "list": [{
  "pagePath": "pages/index/index",
  "iconPath":"image/icon_API.png",
  "selectedIconPath":"image/icon_API_HL.png", 
  "text": "首页"
   },{
  "pagePath": "pages/form/form",
  "iconPath":"image/plus.png",
  "selectedIconPath":"image/green_tri.png",
  "text": "更多"
  }, {
  "pagePath": "pages/swiper/swiper",
  "iconPath":"image/icon_COM.png",
  "selectedIconPath":"image/icon_COM_HL.png",
  "text": "其他"
  }
  ]
 } 
 }

具体页面一般包括一下文件(与全局文件类似,不过仅仅作用于该页面):

  • .js 页面逻辑 就是js没什么差别
  • .wxml 页面结构 对应html,不过是应用了不少自定义标签
  • .wxss 页面样式表 对应css文件,优先级比appapp.wxss高,css的写法并未完全支持
  • .json 页面配置 指定特定页面的title等元素

为了方便开发者减少配置项,规定描述页面的这四个文件必须具有相同的路径与文件名。

也就是说,我们不用指定某个页面对应的js或者wxss文件,只需要保持路径和文件名相同即可。

四、模版语言及事件系统

1):模版语法类似vue,接近原生的自定义标签。数据绑定和渲染类似vue的语法,不过是以wx:开头(vue 以v: 作为标识)

/**
* 类似vue的条件渲染语法,熟悉vue的话应该不会陌生
**/
<view wx:if="{{condition}}"> 
</view>

2):事件系统

事件系统类似react:定义了一套自己的事件系统。包含一系列常用事件类型:

  • touchstart 手指触摸动作开始
  • touchmove 手指触摸后移动
  • touchcancel 手指触摸动作被打断,如来电提醒,弹窗
  • touchend 手指触摸动作结束
  • tap 手指触摸后马上离开
  • longtap 手指触摸后,超过350ms再离开

绑定方式:事件绑定的写法同组件的属性,以 key+value 的形式:

以bind或catch开头,然后跟上事件的类型,如bindtap catchtouchstart,

value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。

bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡 。例如:

/**
*bind/catch +事件类型,两种事件绑定方式
*/
<view id="outter" bindtap="handleTap1">
 outer view
 <view id="middle" catchtap="handleTap2">
 middle view
 <view id="inner" bindtap="handleTap3">
  inner view
 </view>
 </view>
</view>

3):事件对象:包括BaseEvent 基础事件对象,CustomEvent 自定义事件对象,TouchEvent 触摸事件对象等。

五、优缺点:

1):优点

1、提供相应的类似jsbridge的支持,使得某些功能更为方便

2、本质是mvvm的前端框架,简化操作。

3、提供了比较成型的组件库,构建比较方便

4、基于微信appapp,使得开发成本下降

5、支持模块化

2):缺点 

1、由于框架并非运行在浏览器中,js相关bom的方法无法使用。如 document,window等。不过可以获取当前事件对应的dom对象。相比react还是一样不建议操作dom,jq,zepto等工具库也不好使了 

2、又是一套自己的语法,需要学习时间,不过学习曲线不陡峭

3、目前不支持直接引入 node_modules ,开发者需要使用到node_modules时候建议拷贝出相关的代码到小程序的目录中这样局限性就比较大了,需要自己手动的东西好多

相关推荐