代码目录
详细代码
//app.js
App({
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
// env: 'my-env-id',
traceUser: true,
})
}
}
})
package.json内容如下:
{
"name": "miniprogram",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@vant/weapp": "^1.6.2"
}
}
app.json内容如下:
{
"pages": [
"pages/movie/movie",
"pages/profile/profile",
"pages/comment/comment"
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#d81e06",
"navigationBarTitleText": "最新电影",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#707070",
"selectedColor": "#d81e06",
"list": [{
"pagePath": "pages/movie/movie",
"text": "电影",
"iconPath": "images/movie.png",
"selectedIconPath": "images/movie-actived.png"
},{
"pagePath": "pages/profile/profile",
"text": "我的",
"iconPath": "images/profile.png",
"selectedIconPath": "images/profile-actived.png"
}]
},
"sitemapLocation": "sitemap.json",
"style": "v2"
}
tabBar
如果小程序是一个多tab应用,也就是说,客户端底部或顶部有tab栏可以切换页面,就可以通过tabBar
配置项指定tab栏的表现,以及tab切换时显示的对应页面。
本例中,页面底部有2个tab栏。其中,
第一个tab栏用于"电影”,其对应路由是pages/movie/movie
;第二个tab栏用于“我的”,其对应路由是pages/profile/profile
。color
tab上文本的默认颜色,仅支持十六进制颜色,如#707070
selectedColor
tab上文本选中时的颜色,仅支持十六进制颜色,如#d81e06
list
tab列表中最少要有2个tab,最多只能由5个tab。
因此,数组list
最少包含2个元素,最多包含5个元素。
数组中的每个元素都是一个对象,该对象可具有以下属性:pagePath
页面路径,必须在pages
中先定义。
比如,“电影”这个tab栏对应的页面路径是pages/movie/movie
,“我的”这个tab栏对应的页面路径是pages/profile/profile
。text
tab上的文本iconPath
默认显示的图片。selectedIconPath
tab栏选中时显示的图片。
pages/movie
- 创建并上传云函数movielist
// movielist/index.js
const request = require("request");
exports.main = (event,context) => {
return new Promise(resolve => {
request(`https://movie.douban.com/j/search_subjects?type=${event.type}&tag=${event.tag}&page_limit=${event.limit}&page_start=${event.start}`,(err,res) => {
if(!err && res.statusCode===200){
const result = JSON.parse(res.body);
resolve(result);
}
})
})
}
- 在pages/movie/movie.js中调用云函数
movielist
获取豆瓣电影最新列表,点击评价将跳转至pages/comment/comment,即电影评价页面。
// pages/movie/movie.js
Page({
data:{
movieList:[]
},
getMovieList:function(){
wx.showLoading({
title:"加载中"
})
wx.cloud.callFunction({
name:"movielist",
data:{
type:"movie",
tag:encodeURIComponent("最新"),
limit:10,
start:this.data.movieList.length
}
}).then(res => {
this.setData({
movieList:this.data.movieList.concat(res.result.subjects)
},function(){
wx.hideLoading();
console.log(this.data.movieList)
});
}).catch(err => {
wx.hideLoading();
console.error(err);
})
},
onLoad:function(options){
this.getMovieList();
},
onReachBottom:function(){
this.getMovieList();
},
gotoComment:function(event){
const {id,dataset} = event.target
const {cover,title} = dataset;
wx.navigateTo({
url: `../comment/comment?id=${id}&cover=${cover}&title=${title}`
})
}
})
<!-- pages/movie/movie.wxml -->
<view class="movie" wx:for="{{movieList}}" wx:key="id">
<image class="movie-image" src="{{item.cover}}"></image>
<view class="movie-info">
<view class="movie-title">{{item.title}}</view>
<view>观众评分:<text class="movie-rate">{{item.rate}}</text></view>
<button size="mini" class="movie-comment" id="{{item.id}}" bindtap="gotoComment" data-title="{{item.title}}" data-cover="{{item.cover}}">评价</button>
</view>
</view>
/* pages/movie/movie.wxss */
.movie{
height: 280rpx;
display: flex;
padding: 10px 0 10px 20px;
border-bottom: 1px solid #ccc;
}
.movie-image{
width: 200rpx;
height: 100%;
margin-right: 30rpx;
}
.movie-info{
flex: 1;
}
.movie-title{
color:#666;
font-size: 36rpx;
font-weight: bolder;
}
.movie-rate{
color: #faaf00;
}
.movie-comment{
background-color:#d81e06;
color: #fff;
font-size: 20rpx;
font-weight: normal;
margin-top: 20rpx;
}
pages/comment
- 在电影评价页面,用户可以对电影进行评分,可以输入评价内容,可将图片上传至云存储;
- 点击提交,会将电影
movieId
、用户评分、评价内容和上传的所有图片的fileID
集合写入云数据库中的comment
集合。
// pages/comment/comment.js
const db = wx.cloud.database();
Page({
data: {
cover:"",
title:"",
score:0,
content:"",
images:[],
fileIds:[],
movieId:-1
},
onLoad: function (options) {
const {cover,title,id} = options;
this.setData({
title:title,
cover:cover,
movieId:id
})
},
submit:function(){
wx.showLoading({
title: '正在提交...',
})
console.log(this.data.content,this.data.score);
let promiseArr = this.data.images.map(item => new Promise(resolve => {
let suffix = /\.\w+/.exec(item)[0];
wx.cloud.uploadFile({
cloudPath:new Date().getTime()+suffix,
filePath:item,
success:res => {
const {fileID} = res;
this.setData({
fileIds:this.data.fileIds.concat(fileID)
});
resolve();
}
})
}))
Promise.all(promiseArr).then(res => {
const {movieId,score,content,fileIds} = this.data;
db.collection("comment").add({
data:{
movieId,
score,
content,
fileIds
}
}).then(res => {
wx.hideLoading();
wx.showToast({
title: "评价成功!"
})
}).catch(err => {
wx.hideLoading();
wx.showToast({
title: "评价失败!",
})
})
})
},
onContentChange:function(event){
this.setData({
content:event.detail
})
},
onScoreChange:function(event){
this.setData({
score:event.detail
})
},
uploadImage:function(){
wx.chooseImage({
count: 9,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success:res => {
const tempFilePaths = res.tempFilePaths;
this.setData({
images:this.data.images.concat(tempFilePaths)
},function(){
console.log(this.data.images);
})
}
})
}
})
<!--pages/comment/comment.wxml-->
<view class="container" style="background:url({{cover}});background-repeat:no-repeat;background-size:100%;">
</view>
<view class="detail">
<image src="{{cover}}"></image>
<view>{{title}}</view>
</view>
<view class="comment-score">
<text>电影评分</text><van-rate value="{{ score }}" bind:change="onScoreChange" />
</view>
<view class="comment-field">
<van-field
type="textarea"
autosize
value="{{ content }}"
left-icon="edit"
placeholder="感觉怎么样?跟大家分享一下吧~"
bind:change="onContentChange"
>
</van-field>
</view>
<view class="comment-button">
<van-button size="large" icon="photograph" bindtap="uploadImage">上传图片</van-button>
</view>
<view class="image-container">
<image class="comment-image" wx:for="{{images}}" wx:key="index" src="{{item}}"></image>
</view>
<view class="comment-button">
<van-button size="large" bindtap="submit">提交</van-button>
</view>
/* pages/comment/comment.wxss */
page{
background-color: #fbfbfb;
}
.container{
width: 100%;
height: 500rpx;
filter: blur(45px);
opacity: 0.6;
position: absolute;
z-index: -1;
}
.detail image{
width: 400rpx;
height: 500rpx;
}
.detail{
text-align: center;
}
.detail view{
font-weight: bolder;
}
van-field{
margin-top: 20rpx;
}
.comment-score{
margin-top: 50rpx;
display: flex;
}
.comment-score text{
margin-left: 32rpx;
margin-right: 20rpx;
color: #666;
}
.comment-field{
margin-top: 20rpx;
}
.comment-button{
margin-top: 20rpx;
}
.comment-button .van-button{
width: 100%;
}
.image-container{
margin: 10rpx;
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
.comment-image{
width: 150rpx;
height: 100rpx;
margin: 10rpx;
}
因为要用到vant/weapp的组件,所以在页面配置文件comment.json
中引入这些组件,comment.json
内容如下:
{
"usingComponents": {
"van-field": "@vant/weapp/field/index",
"van-rate": "@vant/weapp/rate/index",
"van-button": "@vant/weapp/button/index"
},
"navigationBarTitleText": "电影评价"
}
pages/profile
// pages/profile/profile.js
Page({
// onGotUserInfo:function(event){
// console.log(event);
// }
})
<!-- pages/profile/profile.wxml -->
<view class="profile">
<open-data type="userAvatarUrl" class="profile-image"></open-data>
<open-data type="userNickName"></open-data>
</view>
<!-- <button open-type='getUserInfo' bindgetuserinfo="onGotUserInfo">获取用户信息</button> -->
/* pages/profile/profile.wxss */
page{
display: flex;
justify-content: space-evenly;
}
.profile{
width: 200rpx;
height: 200rpx;
text-align: center;
}
pages/profile/profile.json的内容如下:
{
"usingComponents": {},
"navigationBarTitleText": "我的"
}
效果
参考
本文demo参考慕课网