unicloud初级入门-新闻小案例

2023-12-26 11:25:46

这个案例,包含了unicloud中云数据库的增删改查,虽然案例小,但是该有的功能都有了。我把代码贴出来供大家参考学习哈。

项目截图

数据库

uniapp代码

AddNews

'use strict';
const db = uniCloud.database();
exports.main = async (event, context) => {
	let {news}  = event;
	let res = await db.collection("article").add({
		posttime: Date.now(),
		...news
	});
	return res;
};

?Delete

'use strict';
const db = uniCloud.database();
const dbCmd = db.command;
exports.main = async (event, context) => {
	//解析id
	let {id} = event;
	//根据条件删除
	let res = await db.collection("article").where({
		_id : dbCmd.eq(id)
	}).remove();
	//返回
	return res;
};

?GetAll

'use strict';
const db = uniCloud.database();
exports.main = async (event, context) => {
	//翻页需要过滤的的量,默认首次是0
	let {skip = 0 } = event;
	let res = await db.collection("article")
		.limit(6) //一次取6条
		.skip(skip) //过滤多少条,把前面已经展示的内容过滤掉
		.orderBy("posttime","desc") //按时间倒序排序
		.get(); 
	return res;
};


?GetById

'use strict';
const db = uniCloud.database();
const dbCmd = db.command;
exports.main = async (event, context) => {
	let {id} = event;
	//根据id获取新闻详情
	//let res = await db.collection("article").doc(id).get();
	//根据id获取新闻详情
	let res = await db.collection("article").where({
		_id : dbCmd.eq(id)
	}).get();
	
	return res;
};

UpdateNews?

'use strict';
const db = uniCloud.database();
const dbCmd = db.command;
exports.main = async (event, context) => {
	let {news} = event;
	let res = await db.collection("article").where({
		_id: dbCmd.eq(news._id)
	}).update({
		title: news.title,
		author: news.author,
		content: news.content
	});
	
	return res;
};

pages index index.vue

<template>
	<view class="home">
		<view class="content">
			<view class="item" v-for="item in newsList" :key="item._id" @tap="goDetail(item)">
				<view class="txt">
					<view class="title">
						{{item.title}}
					</view>
					<view class="info">
						<text class="t">{{item.author}}</text>
						<uni-dateformat
							:date="item.posttime"
							:threshold="[60000, 7200000]"
							format="MM-dd">
							</uni-dateformat>
					</view>
				</view>
				<view class="pic">
					<image src="../../static/logo.png" mode="scaleToFill"></image>
				</view>
			</view>
		</view>
		
		<view class="goAdd" @tap="goAdd">
			<uni-icons type="plusempty" size="30" color="#fff"></uni-icons>
		</view>
		
		<view v-if="isEnd">
			<uni-load-more status="noMore"></uni-load-more>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				newsList:[],
				isEnd: false
			}
		},
		onLoad() {
			//重置
			this.isEnd = false;
			//获取数据
			this.getData();
		},
		//触底加载
		onReachBottom() {
			this.getData();
		},
		//下拉刷新
		onPullDownRefresh(){
			//重置状态
			this.isEnd = false;
			this.newsList = [];
			this.getData();
		},
		methods: {
			//前往详情页
			goDetail(obj){
				//
				uni.navigateTo({
					url:"/pages/detail/detail?id=" + obj._id
				});
			},
			getData(){
				uniCloud.callFunction({
					name:"artGetAll",
					data:{
						//过滤的量就是,已经获取的数组长度
						skip: this.newsList.length
					}
				}).then(res=>{
					console.log(res)
					//新获取的数据,解析后,追加到数组中
					this.newsList.push(...res.result.data);
					//下拉刷新停止
					uni.stopPullDownRefresh();
					//判断是否到底了
					if(res.result.affectedDocs <= 0){
						this.isEnd = true;
					}
				})
				
			},
			goAdd(){
				uni.navigateTo({
					url:'/pages/add/add'
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	.home{
		.content{
			padding: 30rpx;
			
			.item{
				display: flex;
				justify-content: space-between;
				padding: 20rpx 0;
				border-bottom: 1rpx solid #eee;
				.txt{
					flex: 1;
					display: flex;
					flex-direction: column;
					justify-content: space-between;
					padding-right: 20rpx;
					.title{
						font-size: 40rpx;
						color: #333;
						text-align: justify;
						overflow: hidden;
						text-overflow: ellipsis;
						display: -webkit-box;
						-webkit-line-clamp: 2;
						-webkit-box-orient: vertical;
					}
					
					.info{
						font-size: 28rpx;
						color: #888;
						.t{
							padding-right: 20rpx;
						}
					}
				}
				
				.pic{
					width: 260rpx;
					height: 160rpx;
					image{
						width: 100%;
						height: 100%;
					}
				}
			}
		}
		
		.goAdd{
			width: 120rpx;
			height: 120rpx;
			background-color: #5B89FE;
			color: #fff;
			display: flex;
			justify-content: center;
			align-items: center;
			border-radius: 50%;
			position: fixed;
			right: 30rpx;
			bottom: 60rpx;
		}
	}
</style>

pages add add.vue

<template>
	<view class="add">
		<form @submit="onsubmit">
			<view class="item">
				<input type="text" name="title" placeholder="请输入标题" v-model="formValue.title" />
			</view>
			<view class="item">
				<input type="text" name="author" placeholder="请输入作者" v-model="formValue.author" />
			</view>
			<view class="item">
				<textarea value="" placeholder="请输入内容" name="content" v-model="formValue.content"/>
			</view>
			<view class="item">
				<button type="default" form-type="reset">重置</button>
				<button type="primary" form-type="submit" :disabled="isDisabled(formValue)">提交</button>
			</view>
		</form>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				formValue:{
					title: '',
					author:'',
					content:''
				}
			}
		},
		methods: {
			//判断按钮是否禁用
			isDisabled(obj){
				for(let key in obj){
					if(!obj[key]){
						return true;
					}
				}
			},
			onsubmit(e){
				let obj = e.detail.value;
				uniCloud.callFunction({
					name:"artAddNews",
					data:{
						news: obj
					}
				}).then(res=>{
					console.log(res);
					uni.showToast({
						title:"发布成功",
						icon:"success",
						mask:true,
						duration:1000
					});
					setTimeout(()=>{
						uni.reLaunch({
							url:'/pages/index/index'
						})
					},1200);
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
.add{
	padding: 30rpx;
	.item{
		padding-bottom: 20rpx;
		input,textarea{
			border: 1px solid #eee;
			height: 80rpx;
			padding: 0 20rpx;
		}
		
		textarea{
			height: 200rpx;
			width: 100%;
			box-sizing: border-box;
		}
		
		button{
			margin-bottom: 20rpx;
		}
	}
}
</style>

pages edit edit.vue

<template>
	<view class="add">
		<form @submit="onsubmit">
			<view class="item">
				<input type="text" name="title" placeholder="请输入标题" v-model="formValue.title" />
			</view>
			<view class="item">
				<input type="text" name="author" placeholder="请输入作者" v-model="formValue.author" />
			</view>
			<view class="item">
				<textarea value="" placeholder="请输入内容" name="content" v-model="formValue.content"/>
			</view>
			<view class="item">
				<button type="default" form-type="reset">重置</button>
				<button type="primary" form-type="submit" :disabled="isDisabled(formValue)">提交</button>
			</view>
		</form>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				id:null,
				formValue:{
					title: '',
					author:'',
					content:''
				}
			}
		},
		onLoad(options) {
			this.id = options.id;
			this.getDetail();
		},
		methods: {
			getDetail(){
				uniCloud.callFunction({
					name:"artGetById",
					data:{
						id: this.id
					}
				}).then(res=>{
					console.log(res)
					this.formValue = res.result.data[0];
				});
			},
			//判断按钮是否禁用
			isDisabled(obj){
				for(let key in obj){
					if(!obj[key]){
						return true;
					}
				}
			},
			onsubmit(){
				
				uniCloud.callFunction({
					name:"artUpdateNews",
					data:{
						news: this.formValue
					}
				}).then(res=>{
					console.log(res);
					uni.showToast({
						title:"更新成功",
						icon:"success",
						mask:true,
						duration:1000
					});
					setTimeout(()=>{
						uni.navigateBack({
							delta:1
						});
					},1200);
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
.add{
	padding: 30rpx;
	.item{
		padding-bottom: 20rpx;
		input,textarea{
			border: 1px solid #eee;
			height: 80rpx;
			padding: 0 20rpx;
		}
		
		textarea{
			height: 200rpx;
			width: 100%;
			box-sizing: border-box;
		}
		
		button{
			margin-bottom: 20rpx;
		}
	}
}
</style>

pages detail detail.vue

<template>
	<view class="detail">
		<view v-if="loading">
			<view class="title">
				{{detailData.title}}
			</view>
			<view class="info">
				<text class="txt">作者:{{detailData.author}}</text>
				<text>时间:</text>
				<uni-dateformat 
					:date="detailData.posttime" 
					format="yyyy年MM月dd hh:mm:ss"
					class="txt"/>
			</view>
			<view class="content">
				<rich-text :nodes="detailData.content"></rich-text>
			</view>
			
			<view class="btnGroup">
				<button type="default" size="mini" class="btn" @tap="onUpdate">
					<uni-icons type="compose" size="15"></uni-icons>
					修改
				</button>
				<button type="warn" size="mini" class="btn" @tap="onDelete">
					<uni-icons type="trash" size="15" color="#fff"></uni-icons>
					删除
				</button>
			</view>
		</view>
		<view v-else>
			<uni-load-more status="loading"></uni-load-more>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				id:null,
				detailData:{},
				loading: false
			};
		},
		onLoad(options) {
			this.id = options.id;
		},
		onShow() {
			this.getData();
		},
		methods:{
			//
			getData(){
				uniCloud.callFunction({
					name:"artGetById",
					data:{
						id: this.id
					}
				}).then(res=>{
					console.log(res)
					this.detailData = res.result.data[0];
					//加载完成,关闭提示
					this.loading = true;
					//修改导航栏的标题
					uni.setNavigationBarTitle({
						title: this.detailData.title
					});
				}).catch(()=>{
					uni.showToast({
						title:'参数有误',
						icon:'none'
					});
					setTimeout(()=>{
						uni.reLaunch({
							url:'/pages/index/index'
						})
					},800);
					
				})
			},
			//修改
			onUpdate(){
				uni.navigateTo({
					url:'/pages/edit/edit?id=' + this.id
				});
			},
			//调用云函数
			remove(){
				uniCloud.callFunction({
					name:"artDelete",
					data:{
						id: this.id
					}
				}).then(res=>{
					console.log(res);
					//
					uni.showToast({
						title:'删除成功',
						icon:'success',
						mask:true,
						duration:1000
					});
					//等待图标提示完毕,再跳转
					setTimeout(()=>{
						uni.reLaunch({
							url:'/pages/index/index'
						});
					},1500)
				})
			},
			//删除
			onDelete(){
				uni.showModal({
					title:'删除提示',
					content:'您确定要删除此篇文章吗?',
					confirmText:'删除',
					success: (res) => {
						//确认删除
						if(res.confirm){
							this.remove();
						}else{
							//不删除
							uni.showToast({
								title:'已取消删除',
								icon:'none'
							});
						}
					}
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.detail{
		padding: 30rpx;
		.title{
			font-size: 50rpx;
			color: #333;
			text-align: justify;
			line-height: 1.4em;
		}
		
		.info{
			font-size: 30rpx;
			color: #666;
			padding: 30rpx 0 60rpx;
			.txt{
				padding-right: 30rpx;
			}
		}
		
		.content{
			font-size: 36rpx;
			line-height: 1.7em;
			color: #333;
		}
		
		.btnGroup{
			margin-top: 50rpx;
			padding: 50rpx 0;
			border-top: 1px solid #ccc;
			.btn{
				margin-right: 30rpx;
			}
		}
	}
</style>

app.vue

<script>
	export default {
		onLaunch: function() {
			console.log('App Launch')
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style>
	/*每个页面公共css */
	:root{
		box-sizing: border-box;
	}
</style>

pages.json

{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path": "pages/index/index",
			"style": {
				"navigationBarTitleText": "文章列表",
				"enablePullDownRefresh": true
			}
		},
		{
			"path" : "pages/add/add",
			"style" : 
			{
				"navigationBarTitleText" : "新增文章",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/edit/edit",
			"style" : 
			{
				"navigationBarTitleText" : "修改文章",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/detail/detail",
			"style" : 
			{
				"navigationBarTitleText" : "新闻详情",
				"enablePullDownRefresh" : false
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "white",
		"navigationBarTitleText": "文章管理系统",
		"navigationBarBackgroundColor": "#2B9939",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {}
}

图示

首页

?新增

?详情

?修改

?删除

文章来源:https://blog.csdn.net/modern358/article/details/135050652
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。