开发工具
微信开发者工具相关内容:微信官方文档-工具。
小图标:iconfont。
高效的设计稿标注、测量工具:马克鳗。
数据:聚合数据。
小程序为了压缩体积,wxss 文件里设置图片,不支持本地资源图片,可以支持base64和网络图片:base64图片在线转换工具。
CSS文档:w3school。
视频加密:POLYV保利威。
minapp:VSCode 开发小程序插件。
Beautify:VSCode 代码格式化工具。
实战项目 DouBan
小程序的生命周期,打开 app.js 文件:
自定义组件
组件生命周期,打开自定义组件的 .js 文件:
stars
自定义组件:评分(stars.wxml):
stars.wxml
|
|
在评分UI中,设置一个 view 作为五个星星和评分的容器:
<view></view>
:创建 view 组件。class='rate-group'
:设置类名,方便在 stars.wxss 文件中设置布局。
以创建黄色星星的的代码为例:
<image></image>
:创建 image 组件。style='width:rpx;height:rpx;'
:通过 style 设置 image 的宽高。wx:for="" wx:key="*this"
:通过 wx:for wx:key 遍历创建 image。src='/images/rate_light.png'
:指定 image 的文件路径。
|
|
<text></text>
:创建 text 组件。wx:if=""
:如果条件成立,则创建 text。style='font-size:rpx;color:;'>
:指定字体大小、字体颜色。<text></text>
:设置展示文案。
用于加载 stars.js 文件中的属性和变量,使用符号:{{}}
stars.wxss
stars 组件的布局:
display: flex;
:布局方式采用 flex 布局。justify-content: center;
:横向居中对齐。align-items: center;
:垂直居中对齐。font-size: 20rpx;
:在 .rate-group 容器中的字体大小。color: #ccc;
:在 .rate-group 容器中的字体颜色。
stars.js
|
|
stars 文件是自定义的组件,rate、starsize、fontsize、fontcolor、istext
都是 stars 文件的属性,是让调用者在调用时进行设置的,如果没有设置则使用默认值。lights、halfs、grays、ratetext
都是 stars 文件的变量,经过数据处理后,用于UI展示。
更新UI:
itemview
自定义组件电影信息(itemview.wxml):
itemview.wxml
|
|
navigator 组件是一个负责页面跳转的系统组件,具有响应点击事件和页面跳转功能。
class='item-navigator'
:设置类名,便于布局。url=""
:需要跳转的页面路径。因为是自定义组件,所以跳转路径由外部调用者传入。wx:if="" wx:else
:条件成立则创建 navigator 组件,否则创建空白 view。
stars 就是上面👆介绍的自定义组件-评分。设置 rate,其它属性使用默认值。
itemview.json
使用自定义组件的前提是在 .json 文件中导入了组件(usingComponents
),如在 itemview.json 文件导入 stars
组件的文件路径:
itemview.wxss
itemview
组件的布局:
margin-right: 20rpx;
:是指容器本身右边距离其他容器有20像素,不包含在容器内;display: inline-block;
:垂直排列。width: 100%;
:宽度跟父view保持一致。text-align: center;
:字体居中显示。text-overflow: ellipsis;
:字体长度超过组件时显示为“…”。overflow: hidden;
:超出组件的view,隐藏。margin-bottom: 20rpx;
:设置底部边距。
itemview.js
|
|
itemview
组件的属性有 item、itemurl
,其中 item 是外部调用者创建好了的数据容器对象。itemurl 是外部调用者设置的跳转路径。
indexmodule
indexmodule.wxml
|
|
创建 scroll-view:
scroll-x="true"
:设置滚动方向,x轴方向。
使用自定义组件:
item=""
:设置数据 item。itemurl="/pages/detail/detail?type=&id="
:设置跳转页面的路径。路径中的 ?type=&id="
是页面间跳转时的数据传递。
indexmodule.wxss
indexmodule 组件的布局:
padding: 40rpx;
:设置上下、左右边距。background-color: #fff;
:设置背景色。justify-content: space-between;
:项目沿主轴均匀分布,位于首尾两端的子容器与父容器紧紧挨着。white-space: nowrap;
:设置 scroll-view 不换行。margin-top: 40rpx;
是指容器本身的顶部距离其他容器有40个像素,不包含在容器内;
indexmodule.json
在 .json 文件中导入了组件:
indexmodule.js
为外部调用者提供了四个属性:title、moreurl、items、type
:
comment
comment.wxml
为了方便布局,嵌套了多层view:
使用网络图片创建 image:
使用自定义组件 stars,自定义了星星的大小(starsize),不需要显示评分(istext = false):
comment.wxss
|
|
justify-content: flex-start;
起始端对齐。默认就是这种对齐方式。padding-top: 40rpx;
是指容器内的内容距离容器的顶部有40个像素,是包含在容器内的;border-radius: 50%;
设置圆角,圆角大小等于宽度的一半。
comment.json
在 .json 文件中导入了组件:
comment.js
只需要一个参数 item 对象:
searchbar
searchbar.wxml
|
|
如果 isnavigator = true,创建导航组件,在点击搜索框时,跳转到 search 页面:
如果 isnavigator = false,创建输入框:
searchbar.wxss
|
|
border-radius: 10rpx;
:设置圆角大小 10rpx。background-image: url("")
:设置背景图。因为 wxss 文件里使用的是本地图片资源,所以需要将图片转成base64。background-position: center center;
:设置图片垂直水平居中。box-sizing: border-box;
:设置的边框和内边距的值是包含在 width 内的。min-height: 40rpx; height: 40rpx;
:同时设置最小高度和高度,防止光标偏移。background-repeat: no-repeat;
:背景图像将仅显示一次。
search.js
|
|
isnavigator
用于判断是否创建导航控件。onInputEvent
是输入框正在输入的回调事件。this.triggerEvent("searchinput",detail,options);
主动触发事件 triggerEvent,参数为 "searchinput"
、detail
、options
。因为这里的 searchbar
是自定义组件,所以需要将输入事件传递给外部调用者,外部调用者需要实现 triggerEvent 事件:
search.json 文件:
search.wxml 文件:
search.js 文件:
网络
urls.js
定义构造器 globalUrls:
定义 url 变量:
创建方法,根据参数拼接 url:
导出构造器 globalUrls,导出后外部调用者通过 import { globalUrls } from "urls.js"
导入后可用:
network
|
|
页面
生命周期函数在 .js 文件:注册页面:
首页
index.wxml
|
|
创建自定义组件 searchbar
, 指定导航 isnavigator = true。
创建三个自定义组件 indexmodule
,分别用于展示电影、电视剧和综艺。moreurl
是更多按钮跳转的页面路径,items
是每一个电影的信息。
index.json
在 .json 文件中导入了组件:
index.js
|
|
导入 network.js 文件后才可以使用 network
:
请求数据,network.getMovieList({ })
方法内部的 {}
是方法 getMovieList: function (params){ }
需要的 params
,可以看到这里的 params
内部只有一个 success: function(movies){ }
方法。在网络请求完成时,network
在 getMovieList()
方法内部可以通过 params.success(moives)
回调过来:
更新数据,并且重新渲染UI:
更多
list.wxml
|
|
创建自定义组件 searchbar
, 指定导航 isnavigator = true。
遍历创建 itemview 组件,展示每一个 item 数据。
list.wxml
|
|
justify-content: space-between;
项目沿主轴均匀分布,位于首尾两端的子容器与父容器紧紧挨着。flex-wrap: wrap;
换行。padding: 30rpx
边距30个像素。
list.json
在 .json 文件中导入了组件:
list.js
|
|
导入网络请求文件 network.js:
定义变量 type:
显示提示框:
移除提示框:
设置导航栏的标题:
电影详情
detail.wxml
|
|
创建自定义组件-评分,指定星星大小、字体大小和字体颜色:
遍历创建自定义组件-评价:
创建“查看更多短评”按钮,需要传递五个参数:id、type、thumbnail、title、rete
。
detail.wxss
|
|
detail.json
在 .json 文件中导入了组件:
detail.js
|
|
数据处理,将 [1, 2, 3] -> ‘1/2/3’ 的样式:
var actornames = [];
定义一个可变数组。actornames.push(actor.name);
向数组中添加元素。
评论
comments.wxml
|
|
comments.wxss
|
|
comments.json
在 .json 文件中导入了组件:
comments.js
|
|
搜索
search.wxml
|
|
使用自定义组件 searchbar
,使用 bindsearchinput="onSearchInputEvent"
绑定输入框的输入事件。其中的 bindsearchinput
= bind
+ searchinput
,而 "onSearchInputEvent"
是搜索页面需要实现的回调方法:
search.wxss
|
|
search.json
使用自定义组件 searchbar:
search.js
|
|
总结
更新UI
|
|
页面跳转
创建 navigator
组件;
设置跳转路径 url
;type、id
:在 url
中通过符号 ?
加入参数,实现页面间传值。
padding、padding-top、margin-top 和 top 的区别
|
|
observer(监听属性)
属性被改变时执行的函数(可选),也可以写成在 methods
段中定义的方法名字符串, 如:'_propertyChange'
。通常 newVal
就是新设置的数据,oldVal
是旧数据
事件回调、主动触发
组件内通过主动触发回调方法,实现事件传递,同时使用到组件的文件需要绑定回调方法。以 searchbar
组件为例:
searchbar.js 文件:
search.wxml 文件:
bindsearchinput
= bind
+ searchinput
。"onSearchInputEvent"
是需要实现的回调事件。
search.js 文件:
加载动画
|
|
scroll-view 滚动到指定位置
|
|
网络请求
|
|
构造器
可以单独创建一个 .js 文件,在文件内部创建构造器。以 globalUrls、ntework
为例,构造器内部可以定义变量、构造方法,这样外部调用者不需要初始化,可以直接使用 globalUrls、ntework
调用构造器内部的变量和方法,同 iOS 里的类方法。
ES6语法
ES6 是 ECMAScript 6 的简写,ECMAScript 6 泛指“下一代 JavaScript 语言”,具体每年发布的都有自己的专属名称,比如2015年发布的则为 ESMAScript 2015。目前说的 ES6 语法,一般值得都是 ESMAScript 2015版。ECMAScript 是 JavaScript 的标准,JavaScript 是 ECMAScript 的一种实现,另外的 ECMAScript 方言还有 Jscript 和 ActionScript。
在小程序开发工具中开启ES6:在微信开发者工具中->详情->ES6转ES5。
定义变量
let
let
跟 var
一样,也是用来定义变量,但是他比 var
更加的安全,体现在以下两点:
不会出现变量提升的情况。
12console.log(a);var a = 10;变量
a
是在打印的后面定义的,但是以上的代码并不会出错,而是会打印undefined
,因为var会把变量a
提升到代码最开始的地方进行定义。但是如果使用let
就不会出现这种问题了:12console.log(b);let b = 10;此时再去打印的时候,就直接会抛出一个错误
ReferenceError: b is not defined.
,这才是正确的方式。注意:小程序中不能真正解析ES6语法,他只是借助了第三方工具将 ES6 语法转成 ES5 语法运行的,在底层也是用
var
来代替let
的,所以依然会发生变量提升。只在当前代码块内有效。
1234for(var i=0;i<=3;i++){console.log(i);}console.log(i);正常逻辑下,在 for 循环结束后 i 就不能够再使用了,但是这里的打印结果是 3 而不是抛出异常,这种现象在一些情况下也会阐释莫名其妙的错误,影响开发。但是
let
就不会出现这种情况:1234for(let i=0; i<=3; i++){console.log(i);}console.log(i);此时再打印i的时候,就会抛出错误
ReferenceError: b is not defined.
。
const
const
是用来定义常量的,常量是一旦定义好了以后,就不能够再修改了:
const
只是用来限制指向的内存地址不能改变,但是如果这个内存地址上的数据改变了,是可以的:
打印结果:
函数
默认参数
|
|
method="get"
表示在调用 fetch
函数的时,可以不传 method
参数,他会默认使用 get
:
- 定义默认参数的时候,默认参数必须要在非默认参数的后面。
有多个默认值的情况:
在调用 person
函数时,如果只提供 gender
,不提供 age
,那么必须与解构赋值默认值结合使用:
箭头函数
函数作为一个参数变量传递的时候,为了简化写法,可以使用箭头函数来实现:
对上面的代码使用箭头函数:
箭头函数的语法
|
|
定义一个网络请求的方法:
如果只有一行代码,那么可以不用花括号((a,b) => a+b
返回 a+b 的结果):
如果只有一个参数,可以不使用圆括号(a => a+1
):
如果没有参数:
Promise
Promise
的实现原理:
类
在 ESS 中实现一个类:
在 ES6 中实现一个类:
定义静态方法
使用 static
关键字定义的静态方法,该静态方法是只属于类,不属于对象。在使用这个方法的时候直接通过类名就可以调用:
模块
在传统的 JS 中,没有办法在多个 js 文件中互相导入,对于大型项目来说很不方便。因此 ES6 提供了一个模块的功能。
export
认在一个js文件中写好的代码或者变量,是不能够给其他的文件使用的,如果想要被外部使用,那么需要使用export关键字:
import
以上文件进行 export
了,那么以后其他文件想要使用的,则需要从这个文件中把需要的进行 import
:
云开发
创建小程序
数据库
创建程序
新建项目 databasedemo:
初始化云开发
在 app.js 文件中的 onLaunch()
方法 初始化 数据库:
env
:指定所有服务的默认环境。traceUser
:是否在将用户访问记录到用户管理中,在控制台中可见。
创建集合
在云开发的数据库中,使用的是 NoSQL
类型的数据库。关系型数据库中的表,对应的是 NoSQL
中的一个集合。所以在所数据操作之前,应该先创建一个集合。创建完集合后,也不需要跟关系型数据库一样,先定义好这个集合中的字段,而是直接插入数据,并且插入数据的时候,每条数据的字段无需保持一致!
获取数据库对象
可以通过 wx.cloud.database
函数来获取数据库对象,这个函数默认会使用 wx.cloud.init
方法中提供的环境下的数据库。如果想要使用其他环境的数据库,可以给 wx.cloud.database
方法传递一个 env
参数,比如:wx.cloud.database({ "env":"数据库环境ID" })
。
获取集合对象
可以通过 db.collection("集合名称")
来获取集合对象,比如通过 const test = db.collection("test")
获取到 test
集合对象,然后就可以对 test
来进行操作了。
插入数据
调用集合 test
的 add()
方法来插入数据:
获取数据
1.获取集合里的所有数据(考虑到性能,小程序一次性最多只能获取20条数据)
2.根据 id
获取指定某一条数据(通过 id
获取数据需要通过 doc()
函数来实现)
3.根据条件获取数据,可以通过 where 函数来实现
删除数据
|
|
删除多条数据(只能在服务端实现,需要用到云函数):
更新数据
|
|
一次更新多个数据:需要在服务器端,使用云函数来实现。
command指令
获取 command 对象:
查询指令
通过 db.command
实现条件查询。
command.eq
示例一,在 test
集合中,找到字段 author == "测试作者03"
的数据:
第一种方式,通过制定数据查询:
第二种方式,通过eq指令查询:
author: _.eq("测试作者03")
强调用是等于,author: "测试作者03"
强调的事匹配条件。
示例二,匹配 dic.key == "测试对象03"
的数据:
指定数据方式可以获取到两条数据,这两条数据的 dic
对象的 key
等于”测试对象03”。
示例三,匹配 dic.key == "测试对象03"
且 dic.key02 == "测试对象03"
的数据:
示例四,获取 dic == { key: "测试对象" }
的数据:
command.neq
表示字段不等于某个值,和 db.command.eq
相反。
command.lt
表示小于某个值。比如查找小于2021/4/1 10:00:00发布的数据:
command.lte
表示小于或者等于某个值。与 command.lt
类似。
command.gt
表示大于某个值。与 command.lt
类似。
command.gte
表示大于或者等于某个值。与 command.lte
类似。
command.in
查询筛选条件,表示字段的值需在给定的数组内。比如查找北京日报和今日头条两个作者发表的文章:
command.nin
查询筛选条件,表示字段的值需不在给定的数组内。与 command.in
类似。
command.and
查询指令,用于表示逻辑 “与” 的关系,表示需同时满足多个查询筛选条件。比如获取发表在 2021/4/1 10:00:00 和 2021/4/1 11:00:00 之间的所有数据:
command.or
查询指令,用于表示逻辑 “或” 的关系,表示需同时满足多个查询筛选条件。或指令有两种用法:
- 可以进行字段值的 “或” 操作;
- 可以进行跨字段的 “或” 操作。
示例一,一个字段的或操作(比如获取时间在 2021/4/1 10:00:00 前或者 2021/4/1 11:00:00 后的数据):
示例二,跨字段或操作(比如想要获取时间在 2021/4/1 10:00:00 前,或者是作者中包含 “测试作者01” 的数据):
注意:where()
没有 {}
,or()
内部是一个数组 []
。
更新指令
command.set
更新指令。用于设定字段等于指定值。比如以下是一条数据:
如果想将这个数据中的 dic
变成 { "key": "测试对象" }
,那么通过传统的方式是无法实现的:
上面这种方式,只能将 dic.key
改成“测试对象”,即 dic == { key: "测试对象", key02: "测试对象03" }
,所以需要用 _.set
方法:
command.remove
更新指令。用于表示删除某个字段。比如我们想将author这个字段删除,那么就可以调用这个方法。示例代码如下:
command.inc
更新指令。用于指示字段自增某个值,这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是:
原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况。
减少一次网络请求:不需先读再写。
比如 test
集合中的一条数据加一个 read_count
字段,给这个字段加1,那么可以使用以下方式实现:
运行两次:
command.mul
自乘指令,跟 command.inc
一样。
command.push
更新指令,对一个值为数组的字段,往数组尾部添加一个或多个值。如果该字段原为空,则创建该字段并设数组为传入值。
比如要给 test
集合中的某条数据添加标签,那么可以使用以下方式来实现:
command.pop
更新指令,对一个值为数组的字段,将数组尾部元素删除。
command.shift
更新指令,对一个值为数组的字段,将数组头部元素删除。
command.unshift
更新指令,对一个值为数组的字段,往数组头部添加一个或多个值。如果该字段原为空,则创建该字段并设数组为传入值。
高级查询
collection.count
统计集合记录数或统计查询语句对应的结果记录数,注意这与集合权限设置有关,一个用户仅能统计其有读权限的记录数。比如查找所有由“测试作者03”发布的数据的个数:
collection.orderBy
该方法接受两个参数:
- 一个必填字符串参数
fieldName
用于定义需要排序的字段; - 一个字符串参数
order
定义排序顺序,order
只能取asc
或desc
。
注意:
- 如果需要对嵌套字段排序,需要用 “点表示法” 连接嵌套字段,比如
author.age
表示字段author
里的嵌套字段age
。 - 同时也支持按多个字段排序,多次调用
orderBy
即可,多字段排序时的顺序会按照orderBy
调用顺序先后对多个字段排序。
比如通过“阅读量”从大到小以及“作者的年龄”从小到大进行排序。那么可以使用以下代码来实现:
没有指定字段的数据也会返回并且默认排在后面:
collection.limit
指定查询结果集数量上限。比如一次性获取10篇文章,那么可以通过以下代码来实现:
collection.skip
指定查询返回结果时从指定序列后的结果开始返回,常用于分页。比如跳过前面4篇文章,从第11篇开始获取。代码如下:
collection.field
指定返回结果中记录需返回的字段。比如只想获取 test
文章中的 author
字段。那么可以使用以下代码来实现:
结果显示,如果数据中没有指定的字段也会返回:
文件管理
小程序文件管理官方文档:文件。
wx.saveFile(Object object)
保存文件到本地。注意:saveFile 会把临时文件移动,因此调用成功后传入的 tempFilePath 将不可用
云函数
node环境搭建
因为云函数在服务器上是运行在 node.js 环境中的,并且云函数会用到一些第三方库。先在本地编写好,再提交到云服务器,所以本地也需要安装好一套 node.js 环境。原则上,本地的 node.js 版本应该跟云服务器的版本一致。
初始化环境
在以上文件夹中,右键->初始化环境:
创建云函数
在 cloudfunctions
文件夹上,右键->创建云函数,填入云函数的名称,然后点击确定即可创建好。然后就可以在相应的 index.js
文件中写代码了。示例代码如下:
上传和部署
在本地创建完云函数后,需要上传到服务器并部署。只需要在相应函数的文件夹上:右键 -> 上传并部署:云端安装依赖。
在云函数中操作数据库
在云函数中操作数据库、文件等,可以通过 wx-server-sdk
实现。这个 sdk 与小程序端的 API 有以下两点不同:
- 服务端的 API 仅支持 Promise 风格调用。
- 服务端 API 可以进行批量的 update 和 remove 操作。
获取微博数据示例: