前言
本文将介绍如何通过uniapp+uniCloud开发一个简单的壁纸小程序,以下内容均使用阿里云版本的unicloud。
源码下载地址:ext.dcloud.net.cn/plugin?id=1…
实现的主要功能
- 分类切换
- 壁纸列表 - 一个壁纸包含多个分类
- 上拉加载
- 下拉刷新
项目搭建
准备工作
创建uniapp项目
打开HBuilderX
- 创建项目
- 填写项目名称、启用unicloud、选择阿里云
- 关联服务空间
- 新建服务空间
- 在dcloud创建服务空间
- 开通服务空间,测试时可以选择阿里云的免费版本
- 返回HBuilderX选择服务空间,点击管理
运行项目
- 点击运行 -> 运行到浏览器 -> 选择浏览器
- 运行结果
至此我们就完成了项目的基础搭建,并成功运行了项目,下面我们将正式开发壁纸项目。
开始开发
最终效果
创建数据库
根据需求,需要分类和壁纸两个表
- 分类表 在database目录右键新建DB Schema
{
"bsonType": "object",
"required": ["name"],
"permission": {
"read": true,
"create": false,
"update": false,
"delete": false
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"icon": {
"description": "分类图标",
"bsonType": "string"
},
"name": {
"description": "分类名称",
"bsonType": "string"
},
"desc": {
"description": "描述",
"bsonType": "string"
},
"status": {
"description": "状态 0-停用 1-可用",
"bsonType": "int",
"defaultValue": 1
},
"sort": {
"description": "排序",
"bsonType": "int",
"defaultValue": 1
}
}
}
- 壁纸表
{
"bsonType": "object",
"description": "壁纸",
"required": ["url", "categoryIds"],
"permission": {
"read": true,
"create": false,
"update": false,
"delete": false
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"title": {
"description": "分类",
"bsonType": "string"
},
"desc": {
"description": "描述",
"bsonType": "string"
},
"url": {
"description": "图片地址",
"bsonType": "string"
},
"categoryIds": {
"description": "分类id数组[1,2,3]",
"bsonType": "array",
"arrayType": "string",
"defaultValue": []
},
"status": {
"description": "状态 0-停用 1-可用",
"bsonType": "int",
"defaultValue": 1
}
}
}
关联的分类id设置为数组类型,就可以关联多个分类。
- 右键database->点击上传所有DB Schema
- 上传成功后可以在服务空间查看新建的表
接下来开发云函数
开发云函数
-
云数据库使用文档 doc.dcloud.net.cn/uniCloud/he…
-
云对象使用文档 doc.dcloud.net.cn/uniCloud/cl…
-
右键cloudfunctions -> 点击新建云函数/云对象 -> 选择创建云对象
云对象目录结构
- 开发分类云对象 category/index.obj.js
获取云对象
const db = uniCloud.database(); //代码块为cdb
通过API获取数据表对象
db.collection("category")
完整代码
module.exports = {
/**
* 获取分类列表
* @@return {Object}
*/
async list() {
const db = uniCloud.database();
// 使用云数据库查询status位1的分类
const {
data: list
} = await db.collection("category").where({
status: 1
}).orderBy('sort', 'asc').get()
return {
errorCode: 0,
data: list
}
}
}
- 使用相同方法开发壁纸云对象
完整代码
module.exports = {
/**
* 获取分类列表
* @param {Object} params
* @param {number} params.page
* @param {number} params.pageSize
* @param {any} params.categoryId
* @@return {Object}
*/
async page(params) {
const {
page = 1, pageSize = 20, categoryId
} = params
const db = uniCloud.database();
const whereQuery = {
status: 1,
}
// 当没有传categoryId时查询所有状态为1的分类的壁纸
if (categoryId) {
whereQuery.categoryIds = db.command.in([categoryId])
} else {
const {
data: categoryList
} = await db.collection('category').where({
status: 1
}).get()
whereQuery.categoryIds = db.command.in(categoryList.map(v => v._id))
}
// 查询
const queryBuilder = db.collection('wallpaper').where(whereQuery)
// 获取总条数
const {
total
} = await queryBuilder.count()
// 获取当前页列表
const {
data: list
} = await queryBuilder.limit(pageSize).skip((page - 1) * pageSize).get()
return {
errorCode: 0,
data: {
list: list,
total: total
}
}
}
}
至此,云函数和云数据库相关的开发就完成了。
添加测调试数据
因为现在还没有开发管理端,所以我们可以直接在数据库中添加数据
- 添加category数据
点击云数据库 -> 选择表 -> 点击添加记录 -> 添加数据 -> 点击保存
{
"name": "动漫",
"sort": 1,
"status": 1
}
- 添加wallpaper壁纸数据
{
"title": "可爱风",
"desc": "可爱风的头像",
"categoryIds": [
"6625de52c3b5c9650200b415"
],
"status": 1,
"url": "实际的图片地址"
}
壁纸数据中的url需要填写图片的地址,我们可以使用云储存进行添加
点击云储存,可以新建一个文件夹也可以直接上传
点击详情获取下载地址
点击复制链接
将地址填入到数据中进行保存即可
{
"title": "可爱风",
"desc": "可爱风的头像",
"categoryIds": [
"6625de52c3b5c9650200b415"
],
"status": 1,
"url": "实际的图片地址"
}
接下来开始开发前端页面
开发前端页面
-
因为页面需要使用分类tabs和list组件,我们可以在uniapp的插件市场查找相关的组件,也可以直接使用uviews
-
直接修改pages/index/index.vue
-
修改page.json
在style下添加"enablePullDownRefresh": true,是页面可以进行下拉刷新
- index.vue完整代码如下
使用了uviews-puls组件库中的up-tabs组件展示分类、up-list组件实现上拉加载、up-loadmore组件展示加载状态
<template>
<view class="page--home">
<view class="tabs-wrap">
<up-tabs :list="categoryList" @change="changeCate"></up-tabs>
</view>
<view class="list-wrap">
<up-list height="100%" @scrolltolower="scrolltolower">
<view class="list-contaner">
<view v-for="item in wallpaperList" :key="item.id" class="list-item">
<image :src="item.url" mode="aspectFill" class="wallpaper-img"></image>
</view>
</view>
<view class="loadmore-wrap">
<up-loadmore :status="loadingStauts" />
</view>
</up-list>
</view>
</view>
</template>
<script setup>
import {
onPullDownRefresh
} from '@dcloudio/uni-app'
import {
reactive,
ref
} from 'vue';
const category = uniCloud.importObject('category', {
customUI: true
});
const wallpaper = uniCloud.importObject('wallpaper', {
customUI: true
});
// 分类列表
const categoryList = ref([{
name: '全部',
_id: null
}])
// 壁纸列表
const wallpaperList = ref([])
// 分页数据
const pagination = reactive({
page: 1,
pageSize: 10,
})
const query = reactive({
categoryId: null
})
const loadingStauts = ref('loading') // loading - 加载中, nomore - 没有更多了, loadmore - 加载更多
getCategoryList()
refresh()
onPullDownRefresh(() => {
uni.stopPullDownRefresh()
refresh()
})
/**
* 滑动到最底部
*/
function scrolltolower() {
console.log('滑动到最底部了');
loadmore()
}
/**
* 加载更多
*/
function loadmore() {
if (loadingStauts.value == 'nomore') return
pagination.page++
getPageList()
}
function refresh() {
wallpaperList.value = []
pagination.page = 1
getPageList()
}
/**
* 获取分类列表
*/
async function getCategoryList() {
const {
data
} = await category.list()
categoryList.value = [
...categoryList.value, ...data
]
}
/**
* 选择分类
* @param {Object} e
*/
function changeCate(e) {
//
query.categoryId = e._id
refresh()
}
/**
* 获取壁纸列表
*/
async function getPageList() {
loadingStauts.value = 'loading'
const {
data
} = await wallpaper.page({
...pagination,
...query
})
const {
list,
total
} = data
// 判断是否还有
if (total > pagination.page * pagination.pageSize) {
loadingStauts.value = 'loadmore'
} else {
loadingStauts.value = 'nomore'
}
wallpaperList.value = [...wallpaperList.value, ...list]
}
</script>
<style lang="scss">
page {
height: 100%;
}
.page--home {
display: flex;
flex-direction: column;
height: 100%;
.tabs-wrap {}
.list-wrap {
flex: 1;
overflow: hidden;
padding-top: 10rpx;
.list-contaner {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 10px;
}
.list-item {
display: flex;
flex-direction: column;
width: 340rpx;
margin-bottom: 20rpx;
align-items: center;
border-radius: 12rpx;
overflow: hidden;
.wallpaper-img {
width: 100%;
}
.wallpaper-name {
margin-top: 10rpx;
}
}
}
.loadmore-wrap {
padding-bottom: 10rpx;
}
}
</style>
至此,一个简单的壁纸用户端小程序就完成了,以后将分享管理后台的开发方式。