我是学传播学出身,但坚持认为跟计算机交流要比跟人交流更容易一点,程序开发中,我们所做的就是将自己想要的东西完整地传达给计算机,计算机理解之后有条不紊地执行呈现出来,说话是一门艺术,做开发也一样,一旦从这个角度来理解「开发」,接下来的一切看来都是那么自然。

当我在做「编程」这件事情的时候,我更倾向于使用「开发者」来描述自己的身份,而不是「程序员」或者「码农」或者其它什么,这些称呼将开发者群体在从事编程工作时发挥的创造力视若无物。

在本节内容中,我们将了解小程序开发的一些「背景知识」,做好开发前的「准备工作」,并完成「简单版本」的「首页开发」。

背景知识

首先,「小程序」是一个产品名字,跟「网站」是同一个范畴的,它们都属于「程序」,当我们说开发小程序的时候,指的是开发「小程序」这样一种程序。在产品层面上,小程序是脱胎于网站应用的,微信团队为了解决在微信中使用网站应用的性能低、不安全、体验差等缺点,提出了小程序的解决方案,在技术层面上,开发小程序采用的「语言」也与开发网站应用采用的「语言」高度类似。

一系列网页的集合构成网站应用,也存在单页面应用(SPA,Single Page Application),本专栏中不对「网页」和「网站应用」做明确界定,它们都直接以 Web 为载体,故以下都称 「Web 应用」。

显然,我们目前还无法通过意念直接向计算机传达意图,就像人与人之间的交流一样,语言是交流的一种载体,做开发的时候,我们也通过语言向计算机表达我们的意图。

我们在日常交流中采用的「通用语言」其实是不甚明确且带有诸多歧义的,计算机比较死板,它们无法理解通用语言中蕴含的丰富含义,所以我们需要使用一种表意更加明确的方式来与它们交流,这种方式就是「编程语言」。与通用语言相比,编程语言具有更加明确的规则且逻辑性更强,大多数人在初接触编程的时候不可避免地会有不适应感和畏难情绪,个人认为这种感觉就来自于「日常交流的宽松语义情境」和「编程的强规范语义情境」之间的差异,属于正常现象。在适应了编程语言的表达方式之后,很多人的说话做事方式都会不自觉地变得更加「严谨」(不是死板 🤨),这就是大家对于「开发者」的刻板印象了(「程序员」这种称呼无疑加深了这种刻板印象)。

一般来说,开发 Web 应用主要会使用三种「编程语言」,分别是 HTMLCSSJavaScript,三者分别负责呈现内容设置样式添加交互,对于一般的展示性网站比如企业官网、网址导航、个人博客等来说,以 HTML 和 CSS 为主就可以完成开发,而对于涉及到大量交互事件、数据处理、服务器通信等功能的复杂应用网站来说,就必须使用 JavaScript 来完成开发,三者结合,构建出我们透过浏览器看到的整个花花世界。这三种语言看起来分别是下面这样的:

  1. <html>
  2. <head>
  3. <title>Hello, Miniprogram!</title>
  4. </head>
  5. <body>
  6. 在本节内容中,我们将了解小程序开发的一些背景知识并完成「简单版本」的首页。
  7. </body>
  8. </html>
body {
    background-color: #d4d4d4;
  color: #2b2b2b;
  font-size: 15px;
  text-algin: justify;
}
let age = 23;
function printAge() {
    console.info("我今年:" + age + "岁!");
}
printAge() // 输出:我今年 23 岁!

关于 HTML、CSS 和 JavaScript 的详细介绍,大家可以查阅:MDN Web Docs

小程序的开发方式,与 Web 应用开发基本无异,小程序中的 WXML 和 WXSS 分别对应于 HTML 和 CSS,用于编写小程序页面的内容结构和样式,小程序开发中的 JavaScript 与 Web 应用开发中的 JavaScript 语法完全一致,但在能力方面有一些区别。同时,小程序开发中还涉及到一种叫做 WXS 的脚本语言,设计的目的是用来与 WXML 结合构建页面内容结构,也可以用以完成一些特殊情况下渲染性能的优化工作,尽管官方宣称它与 JavaScript 是不同的两种语言,但它的语法其实与 JavaScript 高度相似。

小程序开发中的 JavaScript 与 Web 应用开发中的 JavaScript 在能力方面的区别主要是运行环境决定的,Web 应用开发中 JavaScript 与浏览器打交道比较多,拥有众多与浏览器交互的能力,但小程序开发中 JavaScript 运行在微信单独划分的一个专用的房间中,在这个房间中不需要具备与浏览器交互的能力(BOM),同时,为了打造良好的、可控的应用体验,微信客户端接手了另外一部分能力(DOM),也开放了一众微信独有的能力(登录鉴权、调起支付等),这些便捷易用的特殊能力正是小程序相较网页应用来说最大的优势。

总体来说,小程序开发中的 WXML、WXSS、WXS,JavaScript 可以理解为 Web 应用开发中使用的 HTML、CSS、JavaScript 的「方言版本」。对于具备 Web 应用开发基础的同学来说,小程序开发可以说是轻而易举,手到擒来,对于没有任何基础的同学来说,不妨从小程序开发着手学习,得益于 Web 应用开发中成熟的框架和实践,小程序的开发方式同样可以移植到 Web 应用开发中!

我个人最喜欢的还是写下每一行代码的时候进行的思考,编程语言日新月异,唯有思考能让我们受益终身 🤯

另外,我们需要了解一种叫做 JSON 的语法格式,用于结构化地表达内容或数据,一定程度上它跟 HTML 类似,相较之下缺少了 HTML 标签的语义规范,但比 HTML 更为简洁,常用作配置文件或者客户端与服务器通信的数据格式。以我的个人介绍为例,JSON 看起来是这个样子的:

{
    "nickname": "cigaret",
  "age": 23,
  "hobby": ["movies", "programming"],
    "study-career": {
      "university": "CUC" 
  }
}

一般来说,在单个文件中只会书写一种语言,特定语言的文件具有特定的「文件后缀名」,以便计算机能够正确识别,以上提到的语言对应的文件后缀名包括:.html.css.wxml.wxss.wxs.js.json ,相信大家可以将它们「对号入座」😉

  • 关于 WXML、WXSS 和 WXS 的基本语法,可以查阅 WXMLWXSSWXS
  • 关于 JavsScript 详细信息,可以查阅 JavaScript | MDN
  • 关于 JSON 的简单介绍,可以查阅 JSON 教程 | W3school
  • 🚀 如果已经对基础知识有了相当的了解,不妨查阅这份深入版的 小程序开发指南 了解更多关于小程序的原理性知识。

准备工作

不同于 Web 应用开发,写好代码后在浏览器即可直接预览,小程序最终在微信客户端之上运行,开发者写的代码要实际运行在用户手机中还需要非常多的额外工作需要进行。「微信开发者工具」是一个一站式的小程序/小游戏开发工具,它默默地处理了一般情况下不需要开发者关心的「杂务」,为大家提供便捷清爽的开发、预览、调试功能,有效增强开发效率和体验。本期专栏中,我们的全部开发工作都会在微信开发者工具中进行,大家可以去 微信开发者工具下载页面 进行下载安装。

安装完成之后,微信扫码登录,左侧选择「小程序」,新建一个项目,填写项目信息,这里有两点注意事项:

  • 目录是放置项目文件的地方,需要指定一个空目录;
  • AppID 是小程序的唯一标识,需要注册小程序账号之后在小程序的管理后台获得,注册小程序账号是开发完成之后发布上线的必经流程。在没有注册好之前可以使用测试号进行开发,但部分功能会受到限制,大家可以参考 申请账号 进行小程序账号的申请和注册。
  • 后端服务一项选择「小程序 · 云开发」,虽然我们目前还用不到,但勾选之后开发者工具会为我们做一些目录和文件的初始化工作,避免我们之后手动创建,如果选择测试号的话并没有这个选项,暂时就不必关心了。

填写完成之后的信息如下所示:

image.png

点击右下角新建之后,稍等片刻,待初始化完成,开发者工具会自动为我们打开新建的项目,由于勾选了「小程序 · 云开发」作为后端服务,开发者工具会自动创建一份云开发的项目模板,其目录结构如下所示:

| - cloudfunctions/
    | - ...
| - miniprogram/
    | - components/
  | - images/
  | - pages/
  | - style/
  | - app.js
  | - app.json
  | - app.wxss
  | - sitemap.json
| - project.config.json
| - README.md

cloudfunctions 是云函数文件目录,在使用云开发功能的时候会用到,「简单版本」的小程序不涉及云开发,可以先忽略它, miniprogram 是小程序的主体文件目录,我们编写小程序涉及到的核心文件都是在这个目录下,project.config.json 文件是小程序的配置文件,里面记录了我们这个项目的详细信息,README.md 是一个约定俗成的项目介绍文件。

project.config.json 中默认的前两个字段是 miniprogramRootcloudfunctionRoot ,它们分别记录了小程序的「云函数资源目录」和「主体资源目录」,我们编写的代码就是给计算机看的任务手册,小程序运行的时候计算机会从 project.config.json 开始去寻找对应的文件,然后按照文件中的描述来完成指定任务。在计算机能够理解的前提下,项目文件夹的命名和文件的组织结构都是可以自定义的,按照你认为最合理的方式组织即可。

在小程序主体资源目录即 miniprogram 目录中, app.js 用于编写应用级别的业务逻辑,比如启动的时候做一些什么事情、页面找不到的时候做一些什么事情等等,也常常用来挂载全局可用的数据,app.wxss 用于书写作用于全局的样式,即该文件中的样式每个页面都可以使用,最终我们的大部分样式都是写在这里的, app.json 用于对小程序做全局配置,包括每个页面的路径、导航栏的样式、用到的扩展库等, sitemap.json 用于协助微信的搜索引擎对小程序的页面进行收录。 pages 目录用于放置小程序的页面文件,每个页面又包括 .wxml & .wxss & .js & .json 四个文件,分别用来写该页面的内容结构、样式、业务逻辑和配置。至于 componentsimagesstyle 三个目录,则依项目情况而定,非常灵活,目前先不做介绍。

为了让应用尽可能简洁,我们将 miniprogram 目录下所有的目录全部清空,并删除暂时无用的 images & style & components 目录,整理完成之后目录结构如下:

| - cloudfunctions/
    | - ...
| - miniprogram/
  | - pages/
  | - app.js
  | - app.json
  | - app.wxss
  | - sitemap.json
| - project.config.json
| - README.md

小程序官方文档中与上述准备工作相关的部分详见:概览 | 微信开发者工具目录结构小程序配置sitemap 配置

首页开发

开发首页之前要先拥有一个首页,我们在 pages 目录下新建一个 index 文件夹,将首页的文件放在 index 文件夹中,一个页面也许还好,但页面多起来的时候如果还需要逐个创建 4 个文件就过于麻烦了,开发者工具贴心地准备了快捷创建的选项,只需要在 index 文件夹上点击右键,选择 新建 Page 后填写页面名称(此处是 index)即可自动创建 index.js & index.json & index.wxml & index.wxss 四个文件,并且在各个文件都填充了基本的代码模板。

「index」 是「首页」约定俗称的命名方式,你可以换做任何你认为合适的名称,但最好使用英文命名,而不是中文或者拼音,计算机理解英文字母的能力比中文更强一点,使用英文可以降低未知错误出现的概率,此外,使用规范的英文单词而不是中文拼音是项目专业性的体现,也可以有效降低不同开发人员之间的理解和交流成本。

创建完成之后,保存代码,控制台(或者叫调试器)应该会报错,这是因为我们在进行了上面一番修改之后小程序应用的页面已经发生了变更,而应用的配置文件还没有更新,打开 app.json ,将已经删除的页面路径移除,处理完之后的 app.json 局部如下所示:

{
    "pages": [
      "pages/index/index"
  ],
  ...
}

代码全部呈现的话篇幅太长了,在文章中我们只会贴出与当前介绍的内容相关的部分,... 意即省略了一部分代码,之后不再做特殊说明。

修改完成之后,保存代码( Ctrl + S),不出意外模拟器区域(或预览区域)会自动刷新,显示 index.wxml 中默认的内容,即 「miniprogram/pages/index/index.wxml」。

  • 关于菜单栏、工具栏、调试器、模拟器等开发者工具各个区域的界定和功能介绍,请查阅:界面 | 微信开发者工具
  • 使用快捷键可以极大程度地提升工作效率,关于开发者工具更多的默认快捷键,请查阅:快捷键 | 微信开发者工具,我们也可以通过 菜单 → 设置 → 快捷键设置 对快捷键进行自定义;
  • 强烈推荐为 菜单 → 设置 → 快捷键设置 → 工具 一项中的 文档搜索 设置快捷键,我这里是 Ctrl + D ,该功能允许我们使用关键词迅速搜索小程序/小游戏的官方文档,再也不用刻意去记代码片段了,谁用谁知道 😏;

  • 「开发者写的代码」→ 「可以直接在用户设备(真机)上运行的代码」这一转换过程叫做编译,开发者工具的默认配置中,在「保存」代码之后会自动进行编译,这也是我们能够在保存之后即可自动预览的原因,不过这一步骤比较费时,保存频率高的时候会略微卡顿,可以通过 菜单 → 设置 → 编辑设置 更改这一行为,我目前采用的是 Ctrl + B 手动执行编译。

  • 频繁 Ctrl + S 保存代码是良好的习惯,建议养成 👍

app.json 中还可以自定义小程序状态栏、导航栏等窗口表现,这些内容在 window 字段中进行配置,具体有哪些可配置项,大家可以查阅:window | 小程序全局配置,在这里,我将导航栏的背景颜色设置为白色,并且将应用的标题设置为「🎭定制头像」,代码如下:

{
  "pages": [
    "pages/index/index"
  ],
  "window": {
    "backgroundColor": "#F6F6F6",
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#FFFFFF",
    "navigationBarTitleText": "🎭定制头像",
    "navigationBarTextStyle": "black"
  },
  "sitemapLocation": "sitemap.json",
  "style": "v2"
}

接下来我们去创建「首页」的内容结构和样式,首先是内容结构,先将 index.wxml 清空,然后祭出一张目标图:

image.png

在小程序中 <view></view> 标签用于划分一块视图容器,我们先将页面结构划分出来,然后往结构中填充内容。一眼望去,页面中除去导航栏以外共有四个元素,分别是头像和三个按钮,可以表示为如下:

<view>这里放置头像</view>
<view>这里是第一个按钮</view>
<view>这里是第二个按钮</view>
<view>这里是第三个按钮</view>

这样划分虽然简单,但是层次并不清晰,一般来说我们会将不同类别的元素装在不同的袋子里,在这里意即将页面划分为上下两部分,上面盛放头像,下面盛放三个按钮,此时 WXML 结构表示为如下:

<view>
    <view>这里是头像</view>  
</view>
<view>
  <view>这里是第一个按钮</view>
    <view>这里是第二个按钮</view>
    <view>这里是第三个按钮</view>
<view>

显然这样结构更加清晰一些,结构确定之后我们将内容填充进去,对于头像来说,我们要使用小程序提供的「开放能力组件」在不麻烦用户进行授权的情况下显示他(她)的头像,对于按钮来说将文字替换即可,完成之后,页面代码如下:

<view>
    <open-data type="userAvatarUrl"></open-data>  
</view>
<view>
  <view>选择当前头像</view>
    <view>选择其它图片</view>
    <view>拍照作为头像</view>
</view>

做到这一步,我们的页面是这个样子的:

image.png

编辑器的左侧是预览视图,可以在保存和编译之后实时看到小程序的运行结果,右上方是代码区域,图中的代码与上文贴出来的代码一致,右下角是调试器(或者叫做控制台),调试器分为很多个 Tab,每个 Tab 都是一个特定方面的功能,默认情况下显示的是 Console Tab,即代码的运行提示,切换到 Wxml Tab,可以看到渲染出来的页面结构,我们可以将这个逐级展开的结构称作「页面节点树」,这棵树中的每一个节点都与左侧预览页面中的内容一一对应,当鼠标移到某个节点上时,预览界面中对应的内容也会高亮显示,高亮区域的数字代表的是该节点的尺寸信息。

代码 Doesn’t Work 的时候记得将 Tab 切换至 Console Tab 查看错误提示!!!千万不要砸键盘 😤

大家会发现在调试器中我们的代码被包含在 <page></page> 标签内,事实上在整个应用结构中每个页面都是由 page 标签定义的,我们编写的代码是页面的内容代码,开发者工具会帮我们将代码安排在 page 中。

如你所见,这个页面虽然内容结构与原型图的内容结构是匹配的,页面上方是头像,下方是三个按钮,但整体来说非常简陋,还需要美化一下才可以让它变成预期的样子,这个时候就需要 WXSS 登场啦。

CSS(Cascading Style Sheets,层叠样式表)是专门用来为网页内容添加样式的语言,不夸张地说,我们之所以能够在网上冲浪的时候看到花花绿绿、异彩纷呈的内容,90% 以上都是 CSS 的功劳。它主要由两部分组成,其一是选择器,其二是样式,选择器用来决定为谁添加样式,样式就是字体字号、前景背景颜色、位置布局、边距边框、过渡动画等具体的样式(废话)🤐 WXSS 虽然是 CSS 的「简化版」,但是简化的部分主要是选择器,而不是样式,CSS 能够为网页内容添加的绝大部分样式,WXSS 同样可以为 WXML 添加。

如何定义样式并不是本专栏的重点,所以这里不会对 WXSS 或者 CSS 的细节有过多介绍,在本节中我们只需要了解两部分内容:

  • 在添加样式之前我们首先要拥有样式,这部分内容是写在 WXSS 文件中的;
  • 需要想办法告诉计算机我们定义好的样式要应用于何处,这个工作由「选择器」完成,选择器分别位于 WXML 和 WXSS 中用于建立内容和样式双方的匹配关系;

本节的 WXML 中,我们使用 class 为页面的区域和内容元素分类命名,在 WXSS 中为这些 class 定义样式,两份文件如下所示:

<!--miniprogram/pages/index/index.wxml-->
<view class="avatar">
    <open-data type="userAvatarUrl"></open-data>
</view>
<view class="btn-group">
    <view class="btn">选择当前头像</view>
    <view class="btn">选择其它图片</view>
    <view class="btn">拍照作为头像</view>
</view>
/* miniprogram/pages/index/index.wxss */
page {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}

.avatar {
  width: 30vw;
  height: 30vw;
}

.btn-group {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}

.btn {
  width: 60%;
  margin: 2.5vh 0;
  font-size: 15px;
  line-height: 3;
  border-radius: 30px;
  text-align: center;
  color: rgba(255, 255, 255, 1);
    background-color: rgba(153, 153, 153, 1);
}

class 只是诸多选择器的其中一种,细心的朋友已经发现在上面的代码中还使用了标签名 page 作为选择器,关于组件、标签、选择器的更多知识,我们会在下一节中补充介绍。

目前为止,我们的首页已经跟原型图高度一致啦~

image.png

小结

在本节内容中,我们一起了解了小程序的背景知识,包括它从何而来、技术基础是什么,我们一起完成了小程序开发之前的准备工作,包括账号的注册和项目的创建,以及微信开发者工具的介绍和使用技巧,最主要的是,我们按照设计好的原型图一起完成了「🎭头像定制」小程序的首页 🌟 千里之行,始于足下,终点就在不远处,一起冲呀!

在接下来的内容中,我们逐渐会涉及到大量 WXML 和 WXSS 的使用,这是构建小程序的基石,大家可以在 组件 | 小程序官方文档CSS | MDN Web Docs 以及 WXSS | 微信官方文档 中学习到关于它们的更多内容!

by-nc-sa-4.0.png
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.