03 - 开发环境搭建和项目创建 · 语雀
目标
- 什么是小程序
- 拥有小程序开发者账号
- 安装微信开发者工具
- 创建小程序项目
- 使用基本的组件
- 上线一个体验版小程序
什么是小程序
了解小程序,以及小程序开发为什么会成为一门单独的职业。
我们从以下3个视角,来了解一下小程序。
产品经理视角
小程序是一种不需要下载、安装即可使用的应用,它实现了应用触手可及的梦想,用户扫一扫或者搜一下就能打开应用,也实现了用完即走的理念,用户不用安装太多应用,应用随处可用,但又无须安装卸载。
用户视角
在微信里打开的应用
开发视角
- 新的标签
- 新的 API(JS)
- 新的页面(代码)组织规则
- 新的 IDE
小程序生态了解
查看小程序的运营数据
开发环境搭建
注册小程序开发者账号
打开小程序注册页面
浏览器打开 https://mp.weixin.qq.com,点击右上角的 "立即注册" 进入到小程序开发账号的注册流程。
选择注册的帐号类型
填写账号信息
注意:这里要注意所填写的邮箱要求曾经没有注册过小程序、服务号、订阅号。
邮箱激活
点击链接激活账号
选择主体类型
主体登记信息
补充小程序信息
注册完账号,登录小程序后台。补充小程序的相关信息。
注意:小程序的应用服务类目不要选择小游戏
补充完毕后
查看浏览小程序后台-查看小程序开发者ID
注意: 在开发和发布小程序时必须要填写 AppID
下载安装微信开发者工具
微信开发者工具是官方提供的专门用于微信小程序开发调试的工具,它提供的主要功能如下:
- 快速创建小程序项目(起到脚手架的作用)
- 代码的查看和编辑(相当于 vscode 作用)
- 对小程序功能进行调试(相当于浏览器作用)
- 小程序的预览和发布(打包工具的作用)
下载链接:微信开发者工具下载地址与更新日志 | 微信开放文档
下载并安装微信开发者工具,双击下载好的微信开发者工具,然后后根据引导下一步、下一步操作直到完成。
首次打开微信开发者工具时需要先进行登录(打开手机微信扫码登录)。
小程序开发基础
小程序开发的方式与 Web 开发非常类似,使用 Javascript 做为开发语言,使用 CSS(小程序中换了个名叫 wxss) 来实现页面的布局,除此之外还内置了许多功能丰富的组件,如地图、富文本、轮播图等。
创建小程序项目
打开小程序开发者工具,按照如下步骤创建小程序项目:
1、点击 + 号,新建项目
2、填写项目信息
如上图所示填写信息时 AppID 填写各自申请的小程序账号的 AppID,不使用云开发,选择 Javascript 基础模板。
注意: 创建小程序的目录必须是空目录且当前电脑要处于联网状态。
3、启动小程序项目
小程序开发者工具会自动启动创建好的小程序并初始了小程序的目录结构,如下图所示:
4、小程序开发者工具简单了解
微信开发者工具底层就是一个套壳的 Chrome 浏览器。
熟悉项目目录结构
了解目录结构的文件夹的含义,各个文件的作用,项目启动运行时读取文件的顺序。
总结:
项目启动 => 读取 app 配置 => 运行 app.js => 显示页面 => 读取页面配置 => 运行页面.js => 页面渲染完毕
创建小程序页面
掌握小程序页面的创建和小程序的首页设置
页面创建:
- 在 pages 文件夹上右键点击新建文件夹,输入:home
- 在 home 文件夹右键点击新建 Page 输入:home
- 点击回车
- 工具会自动生成页面需要的四个文件
其中,每个页面 由 4 个基本文件 组成,他们分别是:
- .js 文件 -- 页面的脚本文件,定义页面的数据、事件处理函数、生命周期等,类比 js 理解
- .json 文件 -- 当前页面的配置文件,配置页面的外观、表现等
- .wxml 文件 -- 页面的模板结构文件,类比 html 理解
- .wxss 文件 -- 当前页面的样式表文件,类比 css 理解
设置小程序首页
小程序创建成功后,回自动在项目根目录下的 app.json 文件中生成页面的配置。
将刚刚创建页面配置,放到 pages 数组的第一个,重新编译项目。会发现刚刚创建的 home 页面成为了小程序启动后加载的第一个页面。
总结:
如何配置小程序项目的首页?
小程序常用组件(标签)
接下来我们学习小程序中一些常用的组件。
view 和 text 组件
view 组件类似 html 的 div,是一个块级元素,主要用来布局
text 组件类似 html 的 span,是一个行内元素,主要用来显示文本
我们通过一个案例来学习一下这两个组件
实现如下需求的页面
代码
第一种使用 flex 布局
<!--index.wxml-->
<view class="nav">
<text class="active">推荐</text>
<text>食品</text>
<text>内衣</text>
<text>生鲜</text>
</view>
.nav {
display: flex;
justify-content: space-evenly;
align-items: flex-start;
}
.active {
display: flex;
flex-direction: column;
align-items: center;
color: #f5a11c;
font-size: 18px;
}
.active::after {
content: '';
width: 16px;
height: 2px;
margin-top: 2px;
background-color: #f5a11c;
}
第二种使用 position 布局
.nav {
display: flex;
justify-content: space-evenly;
}
.active {
color: #f5a11c;
font-size: 18px;
position: relative;
}
.active::after {
content: '';
position: absolute;
bottom: 0px;
left: 50%;
top: 28px;
transform: translate(-50%);
width: 16px;
height: 2px;
background-color: #f5a11c;
}
第三种伪元素使用block
.active{
color: #f5a11c;
}
.active::after{
content: '';
display: block;
background-color: #f5a11c;
margin: 2px auto 0;
height: 2px;
width: 16px;
}
总结:
小程序的学习最后又回到了 html css 相关内容的学习。
推荐使用 flex 布局,适配性好。
作业:
面试题:伪类伪元素区别?
CSS中的伪类和伪元素(详细)_LyiRo_的博客-CSDN博客
如何给导航奇数位置或偶数位置设置样式?
/* 2n 是偶数或者是 even, 2n+1是奇数或者是 odd */
.nav text:nth-child(odd){
background-color: red;
}
image 组件
用来渲染一张图片
image 组件的基本使用
- src 属性:指定本地和网络上的图片
- mode 属性:指定图片的裁剪、缩放的模式
<!-- 使用 src 指向本地图片路径 -->
<image src="/images/icon.jpg"></image>
<!-- 使用 src 指向网络图片路径 -->
<image src="http://www.itcast.cn/2018czgw/images/logo.png"></image>
注意:图片组件有默认的宽高(css样式),320x240。默认显示模式:不考虑图片本身的比例全部填充。
image 的缩放模式
image 组件的 mode 属性用来指定图片的裁剪和缩放模式。常用的 mode 属性值如下:
mode 值 | 说明 |
scaleToFill | 默认值 缩放模式:不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
aspectFit | 缩放模式:保持纵横比缩放图片,使图片的长边能完全显示出来。 也就是说,可以完整地将图片显示出来。 |
aspectFill | 缩放模式:保持纵横比缩放图片,只保证图片的短边能完全显示出来。 也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 |
widthFix | 缩放模式:宽度不变,高度自动变化。 宽度就是图片css指定的宽度,css高度会根据图片比例发生改变 |
heightFix | 缩放模式:高度不变,宽度自动变化。 高度就是图片css指定的高度,css宽度会根据图片比例发生改变 |
📎icon.jpg 图片案例资源
总结:
实际开发中我们常用的 mode 属性是 widthFix。
轮播图组件
swiper 标签包含轮播的每一项 swiper-item 。
实现效果
代码
<!-- 轮播图区域 -->
<!-- indicator-dots 属性:显示面板指示点 -->
<swiper indicator-dots class="swiper-container">
<!-- 第一项 -->
<swiper-item>
<view>A</view>
</swiper-item>
<!-- 第二项 -->
<swiper-item>
<view>B</view>
</swiper-item>
<!-- 第三项 -->
<swiper-item>
<view>C</view>
</swiper-item>
</swiper>
.swiper-container {
/* 轮播图容器的高度,swiper-item 会默认撑高到轮播图容器的高度 */
height: 150px;
}
.swiper-container swiper-item view{
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.swiper-container swiper-item:nth-child(1) view {
background-color: lightgreen;
}
.swiper-container swiper-item:nth-child(2) view {
background-color: lightblue;
}
.swiper-container swiper-item:nth-child(3) view {
background-color: lightcoral;
}
swiper 组件的常用属性
属性 | 类型 | 默认值 | 说明 |
indicator-dots | boolean | false | 是否显示面板指示点 |
indicator-color | color | rgba(0, 0, 0, .3) | 指示点颜色 |
indicator-active-color | color | #000000 | 当前选中的指示点颜色 |
autoplay | boolean | false | 是否自动切换 |
interval | number | 5000 | 自动切换时间间隔 |
circular | boolean | false | 是否采用衔接滑动 |
更详细配置请参考:swiper | 微信开放文档
button 组件
button 按钮组件的基本使用配置
属性名 | 类型 | 默认值 | 说明 |
size | String | default | 按钮的大小 |
type | String | default | 按钮的样式类型 |
disabled | Boolean | false | 是否禁用 |
loading | Boolean | false | 名称是否带 loading 图标 |
其他配置参考:button | 微信开放文档
代码
<view>通过 type 指定按钮类型</view>
<button>默认按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<view>size="mini" 小尺寸按钮</view>
<button size="mini">默认按钮</button>
<button size="mini" type="primary">主色调按钮</button>
<button size="mini" type="warn">警告按钮</button>
总结
size="mini" 时,按钮表现为一个行内块元素。
数据绑定
步骤:
- 在页面的 .js 中定义数据。方式: data 属性中定义数据。
- 在页面的 .wxml 中使用数据。有两种试用方式:标签中和标签属性中。
代码
Page({
data: {
name: 'bingo',
age: 18,
url: 'https://www.baidu.com/img/flexible/logo/pc/index_gray.png'
}
})
<view>
<text>{{name}}, {{age}}</text>
<image src="{{url}}" />
</view>
总结:
在标签中试用数据:{{ data中定义数据 }} 语法。
在标签属性中试用数据:属性字符串中 "{{ data中定义数据 }}"
事件绑定
小程序中常用的事件
类型 | 事件描述 | 绑定方式 |
tap | 手指触摸后马上离开,类似于 HTML 中的 click 事件 | bindtap 或 bind:tap |
input | 文本框的输入事件 | bindinput 或者 bind:input |
代码
<view>
<button type="primary" bind:tap="btnClickHandler">按钮</button>
</view>
// pages/home/home.js
Page({
data: {
name: 'bingo',
age: 18,
url: 'https://www.baidu.com/img/flexible/logo/pc/index_gray.png'
},
btnClickHandler(e){
console.log('点击了', e)
}
})
数据修改
通过调用 this.setData({ key: newValue}) 方法,可以给页面 data 中的数据重新赋值。
调用这个方法除了会修改 data 中定义的数据外,还会触发页面更新。
<view>
<text>{{name}}, {{age}}</text>
<button type="primary" bind:tap="changeAge">改年龄</button>
<image src="{{url}}" />
<button type="primary" bind:tap="btnClickHandler">按钮</button>
</view>
// pages/home/home.js
Page({
data: {
name: 'bingo',
age: 18,
url: 'https://www.baidu.com/img/flexible/logo/pc/index_gray.png'
},
btnClickHandler(){
console.log('点击了')
},
changeAge(){
this.setData({
age: 19
// age: this.data.age + 1
})
}
})
案例-购物车计数器
需求
搭建页面
<view class="cart">
<text>商品数量:</text>
<button style="display: inline-block; width: 32px; margin: 0;" type="primary" size="mini">-</button>
<input type="text" value="1"/>
<button style="display: inline-block; width: 32px; margin: 0;" type="primary" size="mini">+</button>
</view>
/* 计数器容器 */
.cart {
display: flex;
align-items: center;
}
input {
margin: 8px;
padding: 4px;
border-radius: 8px;
border: 1px solid red;
display: inline-block;
width: 32px;
text-align: center;
}
绑定事件
<view class="cart">
<text>商品数量:</text>
<button style="display: inline-block; width: 32px; margin: 0;" bind:tap="decrement" type="primary" size="mini" >-</button>
<input type="text" value="{{num}}" bind:input="setNum"/>
<button style="display: inline-block; width: 32px; margin: 0;" bind:tap="increment" type="primary" size="mini">+</button>
</view>
事件处理
// 减少
decrement(){
console.log('减少')
if(this.data.num <=0 ) return
this.setData({
num: this.data.num -1
})
},
// 增加
increment(){
console.log('增加')
if(this.data.num >= 10 ) return
this.setData({
num: this.data.num + 1
})
},
// input 输入事件
setNum(e){
console.log(e.detail.value)
this.setData({
num: parseInt(e.detail.value)
})
}
总结:
input的输入框的值是通过事件处理函数中的 e.detail.value 中获取,不是从 e.target.value 中获取
小程序配置
小程序的配置分为全局配置、页面配置、tabBar配置
全局配置
小程序根目录下的 app.json 文件用来对微信小程序进行全局配置
- 在 app.json 配置文件中,最主要的配置节点是:
-
- pages 数组:配置小程序的页面路径
- window 对象:用于设置小程序的状态栏、导航栏、标题、窗口背景色
- tabBar 对象:配置小程序的tab栏效果
pages 数组
用来配置项目中的页面。
每新建一个页面,pages 数组中就会增加一项配置。反过来手动在 pages 数组中增加一项也会创建一个页面。
window 对象
用来配置小程序窗口的样式
小程序窗口由一下几部分组成
设置导航栏标题文字内容
- app.json --> window --> navigationBarTitleText
- 将属性值修改即可
设置导航栏背景色
- app.json --> window --> navigationBarBackgroundColor
- 将属性值修改为指定的颜色即可。只可以是16进制RGB格式 #ff00ff 不支持字符串色值
设置导航栏标题颜色
- app.json --> window --> navigationBarTextStyle
- 只有 black 和 white 两个选项
全局开启下拉刷新功能
通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为
- app.json --> window --> 把 enablePullDownRefresh 的值设置为 true
设置下拉刷新窗口的背景色
当全局开启下拉刷新功能之后,默认的窗口背景为白色
- app.json -> window -> backgroundColor
设置下拉loading的样式
当全局开启下拉刷新功能之后,默认窗口的loading样式为白色
- app.json --> window --> backgroundTextStyle
- 只有两个选项:dark 和 light
页面配置
页面的属性配置包含在 window 的配置中,上面的配置选项都可以在页面中配置。
注意:页面的配置会覆盖 window 的配置
更多详细配置参考:全局配置 | 微信开放文档
tabBar 配置
tabBar 的配置由两大部分组成:tabBar自身的配置、tabBar页面的配置。
tabBar自身的配置
属性 | 类型 | 必填 | 默认值 | 描述 |
color | HexColor | 是 | . | tab 上的文字默认颜色,仅支持十六进制颜色 |
selectedColor | HexColor | 是 | . | tab 上的文字选中时的颜色,仅支持十六进制颜色 |
backgroundColor | HexColor | 是 | . | tab 的背景色,仅支持十六进制颜色 |
borderStyle | string | 否 | black | tabBar 上边框的颜色, 仅支持 black / white |
list | Array | 是 | . | tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab |
position | string | 否 | bottom | tabBar 的位置,仅支持 bottom/ top |
list 节点的配置项(页面的配置)
属性 | 类型 | 必填 | 说明 |
pagePath | string | 是 | 页面路径,必须在 pages 中先定义 |
text | string | 是 | tab 上按钮文字 |
iconPath | string | 否 | 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px |
selectedIconPath | string | 否 | 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px |
以上的配置不用刻意的去背,根据需要随时查看文档就可以,以下为完整示例代码
"tabBar": {
"color": "#999",
"selectedColor": "#e93b3d",
"backgroundColor": "#fff",
"list": [
{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "/images/home.png",
"selectedIconPath": "/images/home-active.png"
},
{
"pagePath": "pages/message/message",
"text": "消息",
"iconPath": "/images/message.png",
"selectedIconPath": "/images/message-active.png"
},
{
"pagePath": "pages/contact/contact",
"text": "联系我们",
"iconPath": "/images/contact.png",
"selectedIconPath": "/images/contact-active.png"
},
{
"pagePath": "pages/profile/profile",
"text": "我的",
"iconPath": "/images/profile.png",
"selectedIconPath": "/images/profile-active.png"
}
]
},
图片资源📎tabs.zip
小程序的开发调试
任何程序开发都离不开调试,小程序开发者工具自带了调试工具,下面我们就来学习小程序开发者工具的常用开发调试功能。
调试面板
上图中的 【Wxml】 是用来显示小程序页面的结构和样式,【Console】 控制台,【Network】 查看网络请求,【AppData】 查看组件本地数据,【终端】创建命令行窗口等。
预览和真机调试
在大部情况下我们编写的代码会在开发者工具的模拟器中查看到效果,我们还可以在真机中进行预览或调试小程序,这个功能是由小程序开发者工具提供的,如下图所示:
如上图所示点击预览或者真机调试等待片刻会出现一个二维码,管理员或指定的开发成员才可以扫码在真机上查看小程序,如果点击的是真机调试时还会自动打开一个调试面板对真机上的小程序进行调试。
编译模式
编译模式是允许开发者指定某个页面来单独开发调试,首先要掌握编译模式的添加步骤:
当添加了编译模式后再对编译模式进行切换就可以单独针对某个页面进行开发调试了。
刷新和热重载
早期小程序开发者工具是没有刷新的功能,只有编译功能,即每次修改代码后都会将页面重新编译,这种情况下开发效率比较低,现在的小程序开发工具中支持了刷新和热重载的功能。
编译会对小程序重新打包,因此执行时间较长效率比较大,通常如果在开发中代码编写错误后需要重新编译一次,错误才会消息。
刷新是在不重新编译的情况对当前整个页面进行刷新,而执重载是页面的局部刷新即热更新的功能。
注意:.json 类型文件和 app.js 不支持热重载的功能,代码修改后会重新编译整个小程序。
发布上线
小程序开发完毕后,最后一个环节就是将小程序发布到微信小程序的应用商店中。
小程序上传
小程序开发并调试完毕后直接点击【上传】按钮,填写版本信息后小程序会被上传到微信的服务器当中,如下图所示:
在上传小程序代码时有一点大家需要注意,微信官方要求小程序的体积不能超过 2M,超过 2M 时上传不会成功,要解决这个问题可以采用分包的功能,这个功能我们在后面再学习。
文件忽略
在小程序的开发阶段,项目目录中难免会有一些与代码逻辑无关的文件,如页面中用到的图片、文档等,这些文件会占用小程序的代码体积(不能超过 2M),导致无法实现预览、真机调试和上传等功能。
我们有两个方法解决:一种是将不用的图片和文档等删除,另一个种方法是通过配置来忽略这些文件。
在 project.config.json 中进行配置忽略文件:
{
"miniprogramRoot": "miniprogram/",
"packOptions": {
"ignore": [
{ "type": "folder", "value": "static/uploads" },
{ "type": "file", "value": "ui.zip" }
]
}
}
- "type": "folder" 忽略文件目录,"value" 用来指明具体忽略的文件目录
- "type": "file" 忽略文件,"value" 用来指明具体忽略的文件
注意: 被忽略的文件不会被打包到小程序项目当中,因此如果项目中引用了这些图片,图片将无法被加载显示。
体验版
上一步骤只是将代码上传到了小程序的官方服务器上,普通用户还是无法通过小程序商店搜索到,此时可以先将小程序设定为【体验版本】,通过添加或申请体验权限来访问小程序。
每次上传新代码成功后就可以设置【体验版本】了,步骤如下图:
成功设置体验版本后会后自动生成一个二维码,分享这个二维码用户可根据提示申请体验权限,小程序管理员在手机微信中允许后方可访问。
针对公司内部成员如产品、测试、运营人员,可以事先在后台添加为体验成员,这样直接扫码就可以访问小程序无需再申请权限。如下图所示:
添加体验成员仍然是通过【微信号】来添加的,大家互相添加一下。
提交审核
小程序全面测试完毕后还需要提交给小程序官方审核,主要是看小程序有无违规的内容。
发布
审核通过之后,管理员的微信中会收到小程序通过审核的通知,此时在审核版本的列表中,点击 发布 按钮之后,即可把 审核通过 的版本发布为 线上版本,供所有小程序用户访问和使用