【青训营】小程序技术全解

136 阅读3分钟

小程序的业务价值

与WEB的区别

  1. 有固定的语法以及通过一的版本管理,平台可以更方便地进行审核。
  2. 平台能够控制各个入口,如二维码、文章内嵌、端内分享等,入口上能够带来更好的用户体验。
  3. 小程序基于特殊的架构,在流畅度上比WEB更好,有更优秀的转跳。

技术解析

小程序原理

小程序的原理如下图所示: image.png 这个图最可以从右往左看,首先是逻辑层,其中要是是JS代码,因为HTML和CSS代码(对于字节小程序来说,应该是ttml和ttss)都是可以预先渲染的,一般的页面交互和数据的变更都是基于JS的。所以JSCore会将JS中的数据,传递给Native,然后通过Native解析和处理后,传递给渲染层,进行页面的展示。逻辑层JSCore是不能和渲染层进行通信的。Native一般是指小程序所在的环境,如微信小程序的Native就是微信客户端。

渲染层是多个webview的结构,在不同的webview中分别绘制不同的页面或组件,以提升性能。

小程序语法

字节小程序使用TTML、TTSS和JS分别指定界面结构、界面样式和交互逻辑。其具体语法会在下一节中结合实例具体说明。

字节小程序实例——计时器

这个例子是老师在课上举的例子,本文进行了复现,对于样式部分,本人按照老师的界面,进行了代码编写。这个实例的代码只涉及到TTML、TTSS和JS部分,其他部分的配置使用默认配置即可。由于本示例只是简单的入门示例,因为不涉及到其他的复杂配置。

计时器的设计

按照老师的示例,本部分代码将实现一个计时器功能的小程序,当用户点击开始按钮时,小程序会倒计时,直到为0。

image.png

在倒计时过程中,开始按钮会被重置按钮替换,若点击重置,则界面会恢复初始状态。

image.png

代码实现

注: 具体的代码解释都在注释中。

  • 首先是界面的结构TTML代码的编写
<!--使用view标签替换div,用法和div一样的-->
<!--定义整个容器-->
<view class="container">
    <!-- 定义计时器部分-->
    <view class="clock">
        /<!--计数的内容文字-->
        {{timeText}}
    </view>
    <!--使用running变量控制两个按钮的显示情况-->
    <!--重置按钮,绑定了自定义的点击事件onReset,以进行重置-->
    <button tt:if="{{running}}" class="button" bindtap="onReset">重置</button>
    <!--开始按钮,绑定了自定义的点击事件onStart,以进行开始 -->
    <button tt:else class="button" bindtap="onStart">开始</button>
</view>
  • 其次是界面的样式TTSS代码的编写
/* 这部分的代码完全就是CSS,无需多言 */
.container{
  background-color: skyblue;
  height: 100vh;
  padding-top: 50rpx;
}
.clock{
  color: #fff;
  margin: 100rpx auto;
  text-align: center;
  height: 300rpx;
  line-height: 300rpx;
  width: 300rpx;
  border-radius: 200rpx;
  border: 10rpx solid #fff;
}
button {
  color: #fff;
  width: 200rpx;
  background-color: transparent;
  border: 6rpx solid #fff;
  border-radius: 20rpx;
}

需要说明的是,字节小程序中,750rpx为全屏宽度,rpx是一个相对大小的单位,会根据页面的宽度缩放。

  • 最后是界面的交互逻辑JS代码的编写
// 定义倒计时的总时间,默认6分钟,1表示1秒钟,共360秒
const DEFULT_TIME = 6 * 60
// 将数值格式的时间转为时间格式的时间,如 05:05
function formatTime (time) {
  const minutes = Math.floor(time/60)
  const seconds = time % 60;
  // 一个巧妙的方法,左侧补零,然后截取最后两位,实现一直是两位数字的展示效果。
  const mText = `0${minutes}`.slice(-2)
  const sText = `0${seconds}`.slice(-2)
  return mText + ' : ' + sText
}

Page({
  // 定义全局变量及其初始值
  data: {
    timeText: formatTime(DEFULT_TIME),
    // 默认没有运行,就是还没开始倒计时
    running: false
  },
  // 自定义setTimer函数,进行倒计时功能的实现
  setTimer: function(){
    this.timer = setInterval(() => {
      this.time = this.time - 1;
      // 计数完成,停止计时
      if(this.time < 0){
        clearInterval(this.timer)
        return
      }
      // 更新变量值
      this.setData({
        timeText: formatTime(this.time)
      })
    }, 1000)
  },
  onStart: function(){
    if(!this.timer){
      this.time = DEFULT_TIME
      // 调用自定义计时器函数
      this.setTimer()
      // 更新状态变量 running, 控制按钮的切换
      this.setData({
        running: true
      })
    }
  },
  onReset: function() {
    // 清除定时器,停止计时
    clearInterval(this.timer)
    this.timer = null
    // 恢复默认时间
    this.time = DEFULT_TIME
    this.setData({
      timeText: formatTime(DEFULT_TIME),
      // 更新状态变量 running, 控制按钮的切换
      running: false
    })
  }
})