【从0开始搭建壁纸小程序】- 用户端开发

242 阅读5分钟

前言

本文将介绍如何通过uniapp+uniCloud开发一个简单的壁纸小程序,以下内容均使用阿里云版本的unicloud。

源码下载地址:ext.dcloud.net.cn/plugin?id=1…

实现的主要功能

  • 分类切换
  • 壁纸列表 - 一个壁纸包含多个分类
  • 上拉加载
  • 下拉刷新

项目搭建

准备工作

创建uniapp项目

打开HBuilderX

  • 创建项目

创建项目.png

  • 填写项目名称、启用unicloud、选择阿里云

创建项目2.png

  • 关联服务空间

关联服务空间.png

  • 新建服务空间

新建服务空间.png

  • 在dcloud创建服务空间

web端-新建服务空间.png

  • 开通服务空间,测试时可以选择阿里云的免费版本

web端-新建服务空间-02.png

  • 返回HBuilderX选择服务空间,点击管理

选择空间.png

运行项目

  • 点击运行 -> 运行到浏览器 -> 选择浏览器

运行.png

  • 运行结果

demo运行结果.png

至此我们就完成了项目的基础搭建,并成功运行了项目,下面我们将正式开发壁纸项目。

开始开发

最终效果

运行结果.png

创建数据库

根据需求,需要分类和壁纸两个表

  • 分类表 在database目录右键新建DB Schema

新建db.png

{
	"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

上传db.png

  • 上传成功后可以在服务空间查看新建的表

查看数据库.png

接下来开发云函数

开发云函数

新建云对象2.png

云对象目录结构

新建云对象目录结构.png

  • 开发分类云对象 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
}

image.png

  • 添加wallpaper壁纸数据
{
    "title": "可爱风",
    "desc": "可爱风的头像",
    "categoryIds": [
        "6625de52c3b5c9650200b415"
    ],
    "status": 1,
    "url": "实际的图片地址"
}

壁纸数据中的url需要填写图片的地址,我们可以使用云储存进行添加

点击云储存,可以新建一个文件夹也可以直接上传

上传图片.png

点击详情获取下载地址

image.png

点击复制链接

image.png

将地址填入到数据中进行保存即可

{
    "title": "可爱风",
    "desc": "可爱风的头像",
    "categoryIds": [
        "6625de52c3b5c9650200b415"
    ],
    "status": 1,
    "url": "实际的图片地址"
}

接下来开始开发前端页面

开发前端页面
  • 因为页面需要使用分类tabs和list组件,我们可以在uniapp的插件市场查找相关的组件,也可以直接使用uviews

  • 直接修改pages/index/index.vue 前端页面-首页.png

  • 修改page.json

在style下添加"enablePullDownRefresh": true,是页面可以进行下拉刷新

前端page-json.png

  • 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>

至此,一个简单的壁纸用户端小程序就完成了,以后将分享管理后台的开发方式。

源码下载地址:ext.dcloud.net.cn/plugin?id=1…