• 0471-4599451
    您的当前位置:首页 > 新闻动态 > 呼搜动态 >

    微信小程序到底提供了什么?怎样看待微信小程

    时间:2021-03-17 09:45    来源:未知

      微信小程序就是一个类似 RN(React Native)的轮子,可以快速开发,有一定的适用场景,但是也有其局限性。
      
      注:该结论是基于微信小程序的示例代码做的解读,可能存在谬误。
      
      早先,看到很多「权威人士」说小程序是 Hybrid 模式。一度怀疑自己之前判断的准确性,担心误导别人,所以额外备注可能存在谬误。
      
      目前来看,这篇文章的判断比大部分博客文章的判断都准确。
      
      简单总结下观点:
      
      微信小程序是原生应用,是 React Native 和 Weex 类似的模式。
      
      微信小程序的生态除了官方提供的组件和 API,几乎没有其他的组件。所以部分看上去「复杂」的功能,开发起来真的很复杂。
      
      微信小程序只能在微信中运行。
      
      由于微信的限制,微信小程序的应用场景极度有限。
      
      大家想知道微信小程序能干什么?对比服务号就知道了。比如订票、航旅信息、ToDo List、天气日历、星座、理财、实时点菜系统等,核心是低频但重要的需求。
      
      而且,微信不允许分享(导流),不允许链接(导流或广告),所以想要靠微信朋友圈爆发的小机灵被彻底被浇灭了,媒体也不适合微信小程序。
      
      此外,不得不吐槽一下微信和微信小程序:
      
      1. 微信小程序的官方文档写得不完善,很多方面没有覆盖
      
      如何定义一个组件。
      
      无法使用 LESS 或者 SASS 之类的预编译。
      
      WXML 没得到主流编辑器的支持,导致开发速度偏慢。
      
      2. 微信小程序的开发工具极不稳定
      
      和 Shadowsocks 等 VPN 冲突。
      
      经常无故卡死。
      
      开发工具和真机表现偶尔会有差异。
      
      有时候代码无故不生效,需要重启才行。
      
      没有类似 HMR 的机制导致经常刷新。
      
      调试工具不好用等等。
      
      3. 微信小程序的生态和问答社区几乎为零
      
      微信的生态为零,导致部分功能开发起来吃力,比如解析富文本。
      
      微信的问答社区就更差了,遇到问题全靠猜,实在找不到办法就重启。
      
      4. 微信小程序的应用场景太受限
      
      这个和微信的一贯保守风格很像,或许以后会慢慢放开,慢慢期待吧。
      
      以上观点是站在一个普通开发者的角度,对微信小程序的看法。相反,从微信角度出发,某些限制和规范的确很有必要。
      
      希望大家客观对待微信小程序。
      
      而本文主要针对微信小程序的示例代码进行分析,想告诉大家以下几件事:
      
      微信小程序到底提供了什么?
      
      开发微信小程序方便么?
      
      微信小程序的具体适用场景?
      
      最后,还自作主张地说了点对于微信小程序的个人观点。
      
      微信小程序都提供了什么?
      
      微信小程序主要为我们提供了两部分东西:底层 API 、组件。
      
      不仅如此,微信小程序还引入新的文件格式。
      
      1. 引入了新的文件格式
      
      微信小程序并不是传统意义的 HTML 5 页面,微信定义了新的文件格式,然后对这些文件做编译解析。
      
      所以,微信小程序是原生应用!是基于微信的原生应用!微信正式尝试做一个 OS(操作系统)!
      
      微信小程序组件
      
      上图是一个 wx-action-sheet 组件,文件应用了新的后缀。
      
      其中,WXML 功能和 HTML 类似,WXSS 功能和 CSS 类似,JS 包含组件逻辑。这点是不是和 RN/Weex 很像?
      
      2. 微信提供了一套基础组件库
      
      微信为微信小程序提供了一套基础组件库,可以满足开发的基础开发需求,从而实现简单的快速开发。
      
      至于这些基础组件支持多大程度的自定义,以及能否满足实际项目的需求,就留给后续开发者去体验吧。
      
      基础组件库主要分为四类:
      
      控件(controller)主要包括:action-sheet / button / searchbar / modal / / drawer
      
      表单(form)主要包括:checkbox / radio / form / or / switch / slider /input / label / picker
      
      媒体(media)主要包括:image / audio / video
      
      视图(view)主要包括:progress / toast / scroll-view / text / view / mask / icon/ spinner / swiper / slide-tab
      
      嗯,不用介绍大家也都知道这些组件大概是什么功能了,几乎是每个 UI 组件库都必备的。
      
      以后大家应该都基于这个组件库去开发具体的产品。
      
      和 RN/Weex 不同的是,微信小程序多半只能基于微信提供的组件进行个性化封装,而不能基于系统组件进行个性化封装。
      
      原因很简单,因为微信就是一个「系统」。
      
      微信是一个「系统」
      
      我们挑一个稍微复杂的 picker 组件示例来分析分析:
      
      // wx-picker.wxml文件 <view class="page"> <view class="page__hd"> <text class="page__title">picker</text> <text class="page__desc">选择器</text> </view> <view class="page__bd"> <view class="section"> <view class="section__title">地区选择器</view> <picker bindchange="bindPickerChange"  value="{{index}}"  range="{{array}}"> <view class="picker"> 当前选择:{{array[index]}} </view> </picker> </view> <view class="section"> <view class="section__title">日期选择器</view> <picker mode="date"  value="{{date}}"  start="2015-09-01"  end="2017-09-01"  bindchange="bindDateChange"> <view class="picker"> 当前选择: {{date}} </view> </picker> </view> </view> </view>
      
      是的,所有的标签都是自定义标签,进一步佐证了微信小程序是原生应用。组件使用很简单,所以很适合快速开发。
      
      // wx-picker 文件
      
      Page({
      
      data: {
      
      array:["中国","美国","巴西","日本"],
      
      index:0,
      
      date:"2016-09-01"
      
      },
      
      bindPickerChange: (e) {
      
      console.log('picker发送选择改变,携带值为', e.detail.value)
      
      this.setData({
      
      index: e.detail.value
      
      })
      
      },
      
      bindDateChange:(e){
      
      this.setData({
      
      date:e.detail.value
      
      })
      
      },
      
      bindTimeChange:(e){
      
      this.setData({
      
      time:e.detail.time
      
      })
      
      }
      
      })
      
      也很清晰,通过 this.setData 来设置属性,实现 action-sheet 的显示与隐藏切换。React 的感觉,连 API 都很像。
      
      // wx-picker.wxss
      
      .picker{
      
      padding: 13px;
      
      background-color: #FFFFFF;
      
      }
      
      可以重新设置微信小程序的组件样式,和 CSS 很相似,轻量简洁。
      
      3. 底层 API
      
      没有提供底层 API 的基础组件库都是流氓库,有了底层 API 才能开发真正的原生应用,才能做更多丰富的功能。
      
      其中底层 API 包括:
      
      animation / backgronud-audio / canvas / download-file / file / get-location / get-network-type / get-system-info / get-user-info / image / login / navigation-bar-loading / / on-accelerometer-change / on-compass-change / open-location /pull-down-refresh / request / request-payment / set-navigation-bar-title / storage/ upload-file / voice / web-socket
      
      从名字也能看出个大概,小程序提供了比较完整的 API,能够开发更丰富的功能和程序。
      
      我们仍然挑一个稍微复杂点的、图片相关的 API 使用示例来分析分析:
      
      // image.wxml文件 <import src="../common/header.wxml" /> <import src="../common/footer.wxml" /> <view class="container"> <template is="header"  data="{{title: 'choose/previewImage'}}"/> <view class="page-body"> <view class="page-body-wrapper"> <form bindsubmit="openLocation"> <view class="page-body-form"> <picker range="{{sourceType}}"  bindchange="sourceTypeChange"  value="{{sourceTypeIndex}}"> <view class="page-body-form-picker"> <view class="page-body-form-picker-key">  图片来源  </view> <view class="page-body-form-picker-value">  {{sourceType[sourceTypeIndex]}}  </view> </view> </picker> <picker range="{{sizeType}}"  bindchange="sizeTypeChange"  value="{{sizeTypeIndex}}"> <view class="page-body-form-picker"> <view class="page-body-form-picker-key">  图片质量  </view> <view class="page-body-form-picker-value">  {{sizeType[sizeTypeIndex]}}  </view> </view> </picker> <picker range="{{count}}"  bindchange="countChange"  value="{{countIndex}}"> <view class="page-body-form-picker"  style="border-bottom: none;"> <view class="page-body-form-picker-key">  数量限制  </view> <view class="page-body-form-picker-value">  {{count[countIndex]}}  </view> </view> </picker> </view> <view class="images-wrapper"> <text class="images-text">请选择图片</text> <view class="images-list"> <block wx:for-items="{{imageList}}"  wx:for-item="image"> <image src="{{image}}"  class="images-image"  data-src="{{image}}"  bindtap="previewImage"></image> </block> <image src="/image/plus.png"  class="images-image images-image-plus"  bindtap="chooseImage"></image> </view> </view> </form> </view> </view> <template is="footer" /> </view>
      
      简单清晰 WXML,居然让选择图片及及预览实现起来这么简单。并且,可以通过简单的 template 语法来引入其他 WXML 文件。
      
      // image 文件
      
      var sourceType = [
      
      ['camera'],
      
      ['album'],
      
      ['camera', 'album'] ]
      
      var sizeType = [ ['compressed'],
      
      ['original'],
      
      ['compressed', 'original'] ]
      
      Page({
      
      data: {
      
      sourceTypeIndex: 0,
      
      sourceType: ['拍照', '相册', '拍照或相册'],
      
      sizeTypeIndex: 0,
      
      sizeType: ['压缩', '原图', '压缩或原图'],
      
      countIndex: 0,
      
      count: [1, 2, 3, 4, 5, 6, 7, 8, 9]
      
      },
      
      sourceTypeChange: (e) {
      
      this.setData({
      
      sourceTypeIndex: e.detail.value
      
      })
      
      },
      
      sizeTypeChange: (e) {
      
      this.setData({
      
      sizeTypeIndex: e.detail.value
      
      })
      
      },
      
      countChange: (e) {
      
      this.setData({
      
      countIndex: e.detail.value
      
      })
      
      },
      
      chooseImage: () {
      
      var that = this
      
      wx.chooseImage({
      
      sourceType: sourceType[this.data.sourceTypeIndex],
      
      sizeType: sizeType[this.data.sizeTypeIndex],
      
      count: this.data.count[this.data.countIndex],
      
      success: (res) {
      
      console.log(res)
      
      that.setData({
      
      imageList: res.tempFilePaths
      
      })
      
      }
      
      })
      
      },
      
      previewImage: (e) {
      
      var current = e.target.dataset.src
      
      wx.previewImage({
      
      current: current,
      
      urls: this.data.imageList
      
      })
      
      }
      
      })
      
      因为微信对这个 API 已经封装得很好了,所以使用起来只需要传入几个参数,绑定一下回调函数即可。
      
      // image.css 文件
      
      .images-wrapper {
      
      padding: 20rpx;
      
      background-color: #fff;
      
      margin-top: 20rpx;
      
      }
      
      .images-wrapper-text {
      
      font-size: 28rpx;
      
      }
      
      .images-list {
      
      display: flex;
      
      margin-top: 20rpx;
      
      flex-wrap: wrap;
      
      }
      
      .images-image {
      
      width: 150rpx;
      
      height: 150rpx;
      
      margin: 10rpx;
      
      }
      
      .images-image-plus {
      
      border: 1px solid #999;
      
      }
      
      同样,样式表语法近似 CSS,从上面的 rpx 单位可以看出,这不是真正的 CSS,我猜测是 CSS 的子集,类似 RN。
      
      开发微信小程序方便么?
      
      1. 微信小程序的开发目录结构
      
      WX 的开发目录结构也很清晰简单。
      
      WX 目录结构
      
      入口文件就是最外层的 appappon,app.wxss。
      
      app 提供了入口文件的一些初始化和绑定。
      
      appon 提供了项目的结构和一些项目配置,微信之所以采用 appon 的模式,声明项目需要加载的页面和组件,应该是为了方便实现云端编译打包然后下发到微信吧。
      
      app.wxss 就是样式啦。
      
      page 目录放你需要实现具体功能的页面。
      
      util 存放项目需要用到的一些工具函数。
      
      // appon
      
      {
      
      "pages": [
      
      "page/component/component-pages/wx-picker/wx-picker",
      
      "page/API/image/image"
      
      ],
      
      "window": {
      
      "navigationBarTextStyle": "black",
      
      "navigationBarTitleText": "小程序演示",
      
      "navigationBarBackgroundColor": "#fbf9fe",
      
      "backgroundColor": "#fbf9fe"
      
      },
      
      "tabBar": {
      
      "color": "#dddddd",
      
      "edColor": "#3cc51f",
      
      "borderStyle": "black",
      
      "backgroundColor": "#ffffff",
      
      "list": [{
      
      "pagePath": "page/component/index",
      
      "iconPath": "image/wechat.png",
      
      "edIconPath": "image/wechatHL.png",
      
      "text": "组件"
      
      }, {
      
      "pagePath": "page/API/index/index",
      
      "iconPath": "image/wechat.png",
      
      "edIconPath": "image/wechatHL.png",
      
      "text": "接口"
      
      }]
      
      },
      
      "networkTimeout": {
      
      "request": 10000,
      
      "connectSocket": 10000,
      
      "uploadFile": 10000,
      
      "downloadFile": 10000
      
      },
      
      "debug": true
      
      }
      
      2. 微信小程序的部署流程
      
      微信小程序的整个开发与使用流程都在微信的体系中,所以安装和使用应该都很轻量。
      
      微信采用云端编译打包的方式,将编译后的文件发送到微信上,接着,微信内置的解析器会解析并渲染这个文件。
      
      简而言之,微信小程序的开发体验还算流畅,代码可读性也很高,也不需要做太多新的知识储备,但是有硬伤,后文会分析。