一、引言
相信各位码农们都有过要调用各大资源网站提供的API的经历,但是在接入的时候出现许多这样那样的问题,最近在做一个业界备受关注的微信小程序项目,使用了多个网站的API接入,接下来我就以“豆瓣电影”小程序的demo与大家分享下我在学习网站API使用的一些心得体会,本文为个人观点,如有不当之处,恳请批评指正。
二、.开发工具与资源平台
1. [微信web开发者工具]:主要用于敲网页代码,但是最主要用来进行网页效果预览。我这里用的是微信web开发者工具0.19.191900,现在最新版本是0.20.191900版本,功能基本一样,没什么大变化,不过建议使用最新版本,功能功能更强大,操作更方便。
2. [Atom编辑器]:主要用于布局排版,也是敲代码的主战场,真心觉得这个编辑器不错,快捷输入和排版,大大提高了开发效率,使用简单,一学就会。
3. [微信小程序开发者文档]:微信小程序开发的文档,资源库,以及API规范
4. [Iconfont-阿里巴巴矢量图标库]:提供项目中的所有图标,资源丰富。
5. [野狗实时通信云wilddog]:提供项目中数据的存储以及通信功能,实现微信登录。
6. [豆瓣开发者平台]:豆瓣电影的应用接口和开发规范说明文档
三、.目录结构展示
├── app.js
├── app.json
├── app.wxss
├── pages
│ ├── welcome
│ ├── mine
│ ├── comingSoon
│ └── top250
│ ├── detail
│ ├── search
│ ├── video
│ └── index
│ └── log
├── wilddog-weapp.js
├── images
└── utils
└── util.js
"pages":[
"pages/welcome/welcome", //电影首页
"pages/mine/mine", //我的信息页
"pages/comingSoon/comingSoon", //近期上映列表页
"pages/inTheaters/inTheaters", //热门电影列表页
"pages/top250/top250", //top250电影列表页
"pages/detail/detail", //电影详情页
"pages/search/list", //电影搜索页
"pages/video/video" //电影播放页
]
四、效果预览
项目github地址:https://github.com/webstormshi/ActualProject.git
说明:由于项目中所有电影数据是通过请求豆瓣官方提供API远程获取,微信授权登录是通过第三方野狗平台实现,所以加载速度可能稍微有点慢,视频播放功能由于不能获得电影视频资源地址,所以电影播放页面使用了一个固定的视频资源地址访问。
五、项目实现功能列表
电影首页查看
栏目列表查看
电影详情查看
电影搜索查看
电影播放暂停弹幕
登录退出
六、项目难点解析
1.野狗平台API实现微信登录配置
野狗官方API文档引用:
wilddog.App 对象是野狗 Web SDK 的核心,它维护着应用的全局上下文数据,不同模块之间需要通过它来
进行交互。同时 App 实例也是我们访问野狗各个功能模块的入口,所以初始化 App 实例是我们使用其他任
何 API 接口的前提。要使用野狗的身份认证功能,你的初始化参数中必须包含 authDomain, 代码如下:
var config = {
authDomain: "<appId>.wilddog.com"
};
wilddog.initializeApp(config);
初始化多个 App 实例
//上面的代码相当于如下初始化动作
var wilddog = wilddog.initializeApp(config);
//我们还可以使用不同配置声明多个不同的 App 实例
var configA = {
authDomain: "<appId-a>.wilddog.com"
};
var a = wilddog.initializeApp(configA, "APP_A");
//通过 a 来访问 auth
//a.auth().signInXxx().then(...)
**定义** auth()
**说明**获取 wilddog.Auth 实例,wilddog.Auth 实例只能通过此方法获取。
**返回值**[wilddog.Auth](https://docs.wilddog.com/auth/Web/api/Auth.html)
**定义** sync()
**说明** 获取 wilddog.Sync 实例,wilddog.Sync 实例只能通过此方法获取。
**返回值** [wilddog.Sync](https://docs.wilddog.com/sync/Web/api/App.html)
新手由于对微信小程序的的目录结构以及微信提供的API不熟悉,可能不知道怎样实现微信授权登录,在这里为了操作简便,本人使用了wilddog提供的接口,让第三方代理实现微信登录(操作详情见开发文档),而在项目中只需进行如下操作:
将wilddog-weapp-all.js拷贝到根目录下,并在js中进行如下配置:
App({
onLaunch: function () {
var config = {
syncURL : "https://sywx.wilddogio.com", //这里写wilddog中新建的项目域名
authDomain:\'sywx.wilddog.com\'
}
wilddog.initializeApp(config)
this.ref = wilddog.sync().ref(\'todo\')
},
login:function(callback){
console.log(callback);
wilddog.auth().signInWeapp().then(function(user){
callback(user);
wx.showToast({
title: \'登录成功\',
})
}).catch(function(err){
wx.showToast({
title: \'登录失败\',
})
})
},
2.豆瓣电影API获取电影信息
首先,应该要仔细阅读下豆瓣开发者平台的API文档,因为各个网站的提供的接口规范各不相同,所以需要搞明白他们使用的套路,我脑子不太好使,文档看了整整一天才搞明白;然后,在获取API链接的时候,应该注意不是所有的接口都全部开放的,有的数据无法获取,我试了好几个才找到能用的,所以在选择之前,应该提前测试以下是否可用,一般文档下面都会一个提供一个测试示例,最后在微信小程序中调用API的步骤可以参看下面项目中的代码:
//全局变量数据配置
globalData:{
userInfo:null,
doubanBase:"https://api.douban.com", //豆瓣电影api域名
inTheaters:"/v2/movie/in_theaters", //热门电影URI
comingSoon:"/v2/movie/coming_soon", //最近上映URI
top250:"/v2/movie/top250", //top250电影URI
detail:"/v2/movie/subject/", //电影详情URI
search:"/v2/movie/search" //电影搜索URI
}
//拼接请求电影列表的URL并调用获取方法
onLoad:function(options){
var comingSoonURL = app.globalData.doubanBase + app.globalData.comingSoon+ "?start=0&count=10";
// console.log(comingSoonURL);
// 页面初始化 options为页面跳转所带来的参数
this.getComingSoonListData(comingSoonURL,\'comingSoon\',\'近期上映\');
}
//获取近期上映电影列表并存放到data中
getComingSoonListData:function(url,settedKey,categoryTitle){
wx.showToast({
title:"加载中",
icon:\'loading\',
duration:10000
});
var that = this;
wx.request({
url:url,
method:\'GET\',
header:{
"Content-Type":"json",
},
success:function(res){
that.setData({
comingSoon:res.data.subjects,
})
}
});
}
3.微信小程序API实现视频播放
微信小程序自带媒体组件 video(视频)可以对视频媒体信息进行加载,播放等操作,并且可以对video组件的一些相关属性进行自定义,以下展示部分video组件的相关属性:
video组件属性部分列表
属性名 类型 默认值 说明
src String 要播放视频的资源地址
duration Number 指定视频时长
controls Boolean true 是否显示默认播放控件(播放/暂停按钮、播放进度、时间)
danmu-list Object Array 弹幕列表
danmu-btn Boolean false 是否显示弹幕按钮,只在初始化时有效,不能动态变更
autoplay Boolean false 是否自动播放
loop Boolean false 是否循环播放
muted Boolean false 是否静音播放
//电影播放页面的wxml文件
<!--pages/video/video.wxml-->
<view class="section tc">
<video id="myVideo" src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400" enable-danmu danmu-btn controls></video>
<view class="btn-area">
<input bindblur="bindInputBlur" />
<button bindtap="bindSendDanmu" type="primary">发送弹幕</button>
<button bindtap="bindStop" type="default" hidden="{{hiddenVideo}}">停止播放</button>
<button bindtap="bindplay" type="primary" hidden="{{!hiddenVideo}}">继续播放</button>
</view>
</view>
//电影播放页面的交互js文件
// pages/video/video.js
Page({
data: {
hiddenVideo:false
},
inputValue: \'\',
bindInputBlur: function (e) {
wx.login({
success: function(res) {},
fail: function(res) {},
complete: function(res) {},
})
this.inputValue = e.detail.value
},
bindSendDanmu: function () {
this.videoContext.sendDanmu({
text: this.inputValue,
color: getRandomColor()
})
},
bindStop:function() {
this.videoContext.pause();
this.setData({
hiddenVideo: true
});
},
bindplay:function(){
this.videoContext.play();
this.setData({
hiddenVideo: false
});
},
onReady: function () {
this.videoContext = wx.createVideoContext(\'myVideo\')
}
})
//随机生成颜色函数
function getRandomColor() {
let rgb = []
for (let i = 0; i < 3; ++i) {
let color = Math.floor(Math.random() * 256).toString(16)
color = color.length == 1 ? \'0\' + color : color
rgb.push(color)
}
return \'#\' + rgb.join(\'\')
}
4.微信小程序调用野狗API登录
//微信小程序微信授权登录获取用户信息
doLogin: function () {
var that = this;
wx.showModal({
title: \'登录\',
content: \'是否允许微信授权登录\',
success: function (res) {
if (res.confirm) {
app.login(function (user) {
console.log(user);
that.setData({
userText: user,
status: \'退出\',
displayInfo: \'block\',
hiddenInfo: \'none\'
})
})
}
}
})
}
//退出登录,清楚本地用户信息
doLogout:function(){
var that = this;
wx.showActionSheet({
itemList: [\'退出\', \'重新登录\'],
success: function (res) {
if (!res.cancel) {
that.setData({
userText: \'\',
status: \'登录\',
displayInfo: \'none\',
hiddenInfo: \'block\'
})
}
}
})
}
七、API应用心路历程
1.准确获取调用API的请求URL
其实,通过API对网站的数据资源进行访问的最关键就是根据业务需求准确无误的拼接出访问的URL链接,再调用访问方法将数据存储到data中,所以我们在拼接url时需要十分小心,注意细节,根据文档的要求规范URL链接形式,以下介绍一个项目中的例子说明:
//全局数据信息
globalData:{
userInfo:null,
doubanBase:"https://api.douban.com",
inTheaters:"/v2/movie/in_theaters",
comingSoon:"/v2/movie/coming_soon",
top250:"/v2/movie/top250",
detail:"/v2/movie/subject/",
search:"/v2/movie/search"
}
// top250电影列表数据请求URL
// "?start=0&count=10" 表示从0开始,取10条数据
onLoad:function(options){
// 页面初始化 options为页面跳转所带来的参数
var top250URL = app.globalData.doubanBase + app.globalData.top250 + "?start=0&count=10";
console.log(top250URL );
}
2.明确传递参数与返回值
在进行数据访问的时候,会带上一些参数,在使用带参数的链接时,我们应该特别注意页面跳转的起始位置,参数从一个页面传递到另一个页面,传递参数的格式要求,接收参数一般时在js的onLoad方法中,可以通过赋值的方式接收参数列表。而在调用方法的完成后一般都会有返回值,在对返回数据进行使用一定要先明确返回数据的类型及结构,返回值类型一般有number,boolean,object,Array等。
//电影搜索API部分文档信息
Domain: https://api.douban.com/
Resources URI: /v2/movie/search?q={text}
Example: GET /v2/movie/search?q=张艺谋 GET /v2/movie/search?tag=喜剧
//关键字搜索电影列表请求URL
//?q=keyword表示将输入的关键字作为参数传入
InputTap:function(e){
var keyword = e.detail.value;
var searchURL = app.globalData.doubanBase + app.globalData.search + "?q=" + keyword;
console.log(searchURL);
}
3.明确this,options,that等概念
在微信小程序的js文件中this关键字与在javascript中作用类似,都是指当前对象,但是微信小程序中的当前对象即为当前应用,在pages的页面获取方式:
var app = getApp(); /获取当前应用,之后可用this调用
js文件中的options参数
<!--pages/comingSoon/comingSoon.wxml-->
<block wx:for="{{comingSoon}}" wx:key="">
<view class="scroll-view-item" >
//点击跳转到制定带有参数的url页面
<navigator url="/pages/detail/detail?id={{item.id}}">
<image class="movie-img" src="{{item.images.large}}"/>
<view class="movie-name">{{item.title}}</view>
<view class="movie-grade">
<view id="{{item.rating.average}}" class="commentStar" style="background-position-y:(10-{{item.rating.average}})*11px"></view>
<view id="movie-grade-value">{{item.rating.average}}</view></view>
</navigator>
</view>
</block>
options是从其他页面跳转到所现在页面链接中传递进来的参数,由于不确定传入参数的数量,这里的对象为一个数组。
// pages/detail/detail.js
//之前页面跳转到的页面,传递的参数被options接收
onLoad:function(options){
var that = this; //把this对象复制到临时变量that
console.log(options); //打印出optios对象,参数列表
var detailURL = app.globalData.doubanBase + app.globalData.detail + options.id;
console.log(detailURL);
},
上面的代码中用到了that,主要因为this会随着执行的上下文随时会变化,为了能找到原来页面的对象,在一开始将原始变量复制保存,这样有效的解决了数据丢失的问题。
4.利用控制台查看object结构
微信开发者工具不仅可以预览当前页面效果,也配备控制台,可以进行结果输出,我们在使用api访问数据的时候,可以通过使用console.log()输出对象查看对象的属性结构或者通过这种方式进行断点调试。以下给大家演示下我项目中控制台的查看结构操作:
Page({
data:{},
inTheaters: [],
onLoad:function(options){
var inTheatersURL = app.globalData.doubanBase + app.globalData.inTheaters + "?start=0&count=10";
console.log(inTheatersURL); //打印链接,控制台输出,通过点击访问,检测是否正确
this.getMovieListData(inTheatersURL, \'inTheaters\', \'热门电影\');
},
getMovieListData: function (url, settedKey, categoryTitle) {
var that = this;
wx.request({
url: url,
method: \'GET\',
header: {
"Content-Type": "json",
},
success: function (res) {
console.log(res.data); //控制台打印通过API获取的object对象,可展开查看结构
that.setData({
inTheaters: res.data.subjects
})
}
});
}
控制台输出结果:
https://api.douban.com/v2/movie/in_theaters?start=0&count=10
Object {count: 10, start: 0, total: 32, subjects: Array[10], title: "正在上映的电影-北京"}count: 10start: 0subjects: Array[10]0: Objectalt: "https://movie.douban.com/subject/26363254/"casts: Array[3]collect_count: 19015directors: Array[1]genres: Array[1]id: "26363254"images: Objectoriginal_title: "战狼2"rating: Objectsubtype: "movie"title: "战狼2"year: "2017"__proto__: Object1: Object2: Object3: Object4: Object5: Object6: Object7: Object8: Object9: Objectlength: 10__proto__: Array[0]title: "正在上映的电影-北京"total: 32__proto__: Object
单个对象的截图:
<!--pages/inTheaters/inTheaters.wxml-->
<block wx:for="{{inTheaters}}" wx:key="">
<navigator url="/pages/detail/detail?id={{item.id}}">
<view class="movie-list">
<view class="movie-list-info" index="{{index}}">
<!--电影图片-->
<image class="movieimg" src="{{item.images.large}}" />
<view class="item-box">
<view class="userinfo">
<!--电影标题-->
<text class="movie-title">{{item.title}}</text>
<!--电影年份-->
<text class="time">{{item.year}}</text>
</view>
<!--电影评分-->
<view class="posts-title">
<text>评分:{{item.rating.average}}</text>
</view>
<!--电影导演-->
<view class="bar-info-item-number">导演:{{item.directors[0][\'name\']}}</view>
<!--电影主演-->
<view class="bar-info-item-number">
主演:{{item.casts[0].name}}{{item.casts[1].name}}</view>
</view>
</view>
</view>
</navigator>
</block>
5.高效调试代码
在进行开发过程中,程序出现bug是再正常不过的事,所以快速解决bug也是能力的体现,这里我在开发的过程中,遇到bug的解决办法一般的步骤是,首先在控制台查看报错信息,如果一眼就能反映过来最好,但如果看不懂意思,可以将报错信息复制粘贴到百度,查看解决办法,如果再不行的话,可以通过之前介绍的console.log()进行调试。一般做多了之后,只要一看报错就知道问题出在哪儿,所以多做多练是个不错的选择。