uniapp博客小程序开发--博客展示以及添加

昨天,已经完成了项目搭建已经完成首页轮播图。详情
今天,将完成首页博客内容展示,以及添加博客。

效果如下:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

安装MongoDB

MongoDB安装比较简单,一步next即可。
安装方法:

https://www.runoob.com/mongodb/mongodb-window-install.html

运行服务端

  • 项目进行之前,需要运行服务端,获取数据。
  • 打开项目,直接npm run start:dev启动项目。

链接:https://pan.baidu.com/s/1b5s7er5hA6Z3OR6G8Cr-Xw?pwd=hb39
提取码:hb39

在这里插入图片描述

请求接口,获取博客

components/list.vue

<template>
	<view>
		<view v-if="blogList">
			<u-swipe-action @click="del(item._id)" :options="options" v-for="item in blogList" :key="item._id">
				<u-card :title="item.blogTitle" :sub-title="subTitle" :full="true" :border="false" :padding="20"
					margin="10rpx" :footBorderTop="false" :footStyle="footStyle" @click="toDetail(item._id)">
					<view class="" slot="body">
						<view class="u-body-item u-flex u-border-bottom u-col-between u-p-t-0">
							<view class="u-body-item-title u-font-sm u-line-3" style="width: 550rpx;">{{item.blogContext}}</view>
							<image
								src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg"
								mode="aspectFill"></image>
						</view>
					</view>
					<view class="" slot="foot">
						<u-icon name="thumb-up-fill" size="32" color="#2BC3C8" label="30 点赞" labelSize="24"
							class="u-m-r-30"></u-icon>
						<u-icon name="eye-fill" size="32" color="#2BC3C8" label="30 浏览" labelSize="24"></u-icon>
					</view>
				</u-card>
			</u-swipe-action>
		</view>
		
		


		<u-gap bgColor="#ededed" height="20"></u-gap>

	</view>
</template>

<script>
	import {
		mapState
	} from 'vuex'
	export default {
		data() {
			return {
				footStyle: {
					'paddingTop': '0rpx'
				},
				title: '素胚勾勒出青花,笔锋浓转淡,笔锋浓转淡',
				subTitle: '2020-05-15',
				content: '瓶身描绘的牡丹一如你初妆,冉冉檀香透过窗心事我了然,宣纸上走笔至此搁一半瓶身描绘的牡丹一如你初妆,冉冉檀香透过窗心事我了然,宣纸上走笔至此搁一半',
				options: [
					{
						text: '删除',
						style: {
							backgroundColor: '#39c9c6'
						}
					}
				]
			}
		},
		computed: {
			...mapState(['blogList'])
		},
		onLoad() {

		},
		methods: {
			toDetail(_id) {
				console.log(_id);
				this.$router.push(`/pages/index/detail?_id=` + _id)
			},
			//删除博客
			async del(_id){
				const {data:res}=await this.$API.delBlog(_id)
				if(res.code!==200) return this.$common.errorToShow('删除失败')
				this.$common.successToShow('删除成功')
				this.$store.dispatch('getBlogs')
				
			}

		},
	}
</script>

<style lang="scss" scoped>
	.u-card-wrap {
		background-color: $u-bg-color;
		padding: 1px;
	}

	.u-body-item {
		font-size: 32rpx;
		color: #333;
		padding: 20rpx 10rpx;
	}

	.u-body-item image {
		width: 120rpx;
		flex: 0 0 120rpx;
		height: 120rpx;
		border-radius: 8rpx;
		margin-left: 12rpx;
	}
</style>

添加博客

pages目录下新建addblog文件夹
pages/addblog/addblog.vue

<template>
	<view class="container">
		<!-- 消息提示框 -->
		<u-toast ref="uToast" />
		<h1 class="text-center title">新增博客</h1>
		<view class="context">
			<u-form>
				<u-form-item label="标题">
					<u-input placeholder="请输入标题" v-model="blogForm.blogTitle"></u-input>
				</u-form-item>
				<u-form-item label="类型">
					<view  @click="show()">
						<text v-if="blogForm.blogType"  class="lighter" style="width: 550rpx;display: inline-block;">{{blogForm.blogType}}</text>
						<text v-else class="lighter" style="width: 550rpx;display: inline-block;">请选择所属类型</text>
						
						<u-icon name="arrow-right"></u-icon>
					</view>
					

				</u-form-item>

				<u-form-item label="内容">
					<textarea v-model="blogForm.blogContext" placeholder="请输入内容" focus />
				</u-form-item>
				<!-- <u-form-item label="上传图片">
					<u-upload :action="action" :before-upload="beforeUpload"></u-upload>
				</u-form-item> -->
			</u-form>
			<button class="getCaptcha" @click="addBlogs">提交</button>
		</view>
		<u-select v-model="showPop" mode="single-column" value-name="id" label-name="name" :list="blogCategory"
			@confirm="confirmSelect"></u-select>
	</view>
</template>

<script>
	import {
		mapState
	} from 'vuex'
	export default {
		data() {
			return {
				// action: 'http://localhost:3001/file',
				// fileList: [{
				// 	url: 'http://pics.sc.chinaz.com/files/pic/pic9/201912/hpic1886.jpg'
				// }],
				blogForm: {
					blogTitle: '',
					blogContext: '',
					blogType: '',
					typeId:'',
					flag: false,
					img: ''
				},
				showPop: false,
				blogCategory: [{
						id: 1,
						name: '前端'
					},
					{
						id: 2,
						name: '后端'
					},
					{
						id: 3,
						name: '移动开发'
					},
					{
						id: 4,
						name: 'Python'
					}
				]
			}
		},
		computed: {
			...mapState(['id'])
		},
		methods: {
			showToast() {
				this.$refs.uToast.show({
					title: '添加成功',
					type: 'success',
					url: '/pages/index/index'
				})
			},
			addBlogs() {
				this.$store.commit('setID')
				const {
					blogTitle,
					blogContext,
					blogType,
					typeId
				} = this.blogForm
				try {
					this.$store.dispatch('addBlogs', {
						_id: this.id,
						blogTitle,
						blogContext,
						blogType,
						typeId
					})
					this.$router.replace('/pages/index/index')
				} catch (e) {
					console.log(e.message)
					//TODO handle the exception
				}
			},
			// 图片上传
			// getImage(e) {
			// 	console.log('lx', e);
			// },
			// async beforeUpload(index, list) {
			// 	console.log('lx', list);
			// },
			confirmSelect(e) {
				
				const {
					value,
					label
				} = e[0]
				this.blogForm.typeId = value
				this.blogForm.blogType = label
				console.log(this.blogForm.typeId);
			},
			show(){
				this.showPop=true
			}
		}
	}
</script>

<style lang="scss" scoped>
	.container {
		padding: 20rpx;
	}

	.getCaptcha {
		background-color: #39cccc;
		color: #ffffff;
		border: none;
		font-size: 30rpx;
		margin: 60rpx 0;

		&::after {
			border: none;
		}
	}
</style>

修改pages/index/index.vue

<template>
	<view class="">
		<u-navbar :backTextStyle="backTextColor" backIconColor="#39CCCC" :background="background" :is-back="false">
			<view class="u-nav-slot" slot="right" @click="toAddBlog">
				<u-icon color="#fff" name="plus" size="50"></u-icon>
			</view>
			<!-- <view class="u-nav-slot" slot="left" @click="toAddBlog"><u-icon name="plus" size="50"></u-icon></view> -->
			<view class="flex row-center" style="width: 100rpx;">
				<u-icon name="scan" class="icon-md" color="#fff" size="50" @click="scanCode"></u-icon>
			</view>

			<view class="search-wrap" @click="toSearch">
				<!-- 如果使用u-search组件,必须要给v-model绑定一个变量 -->
				<u-search height="56" :showAction="false"></u-search>
			</view>
		</u-navbar>
		<view class="">
			<view class="toptem">
				<u-swiper :list="swiper" border-radius="0" :effect3d="true"></u-swiper>
			</view>
			<u-gap bgColor="#ededed" height="20"></u-gap>
			<!-- list -->
			<list v-if="blogList.length>0"></list>
			<view v-else class="flex-col col-center" style="margin-top: 200rpx;">
				<text>没有博客哦,亲~</text>
				<router-link to="/pages/addblog/addblog">去添加</router-link>
			</view>
		</view>
		<u-back-top :scrollTop="scrollTop" :mode="modeTop" :bottom="bottomTop" :right="rightTop" :top="top"
			:icon="iconTop" :custom-style="customStyle" :icon-style="iconStyleTop" :tips="tips"></u-back-top>
	</view>
</template>

<script>
	import list from '@/components/list';
	import {
		mapState
	} from 'vuex'
	export default {
		components: {
			list
		},
		data() {
			return {
				swiper: [],
				background: {
					'background-image': 'linear-gradient(45deg, #2BC3C8, #84E7B9)'
				},
				backTextColor: {
					color: '#ffffff'
				},
				// top
				scrollTop: 0,
				modeTop: 'circle',
				bottomTop: 200,
				rightTop: 40,
				top: 600,
				iconTop: 'arrow-up',
				iconStyleTop: {
					color: '#ffffff',
					fontSize: '30rpx'
				},
				customStyle: {
					backgroundColor: '#39CCCC',
					color: '#ffffff'
				},
				tips: '顶部',
				token:null
			};
		},
		onLoad() {
			this.getSwiper();
			this.$store.dispatch('getBlogs')
		},
		onShow() {
			this.$store.dispatch('getBlogs')
		},
		computed: {
			...mapState(['blogList'])
		},
		methods: {
			resetToken(){
				this.token=uni.getStorageSync('token')
			},
			toSearch() {
				this.$common.navigateTo('/pages/index/search');
			},
			back() {
				// 首页
				uni.navigateBack({
					delta: 2
				});
			},
			toDetail() {
				this.$common.navigateTo('/pages/index/detail');
			},
			// 回到顶部
			onPageScroll(e) {
				this.scrollTop = e.scrollTop;
			},
			toAddBlog() {
				this.$router.push('/pages/addblog/addblog');
			},
			async getSwiper() {
				const {
					data: res
				} = await this.$API.getSwiper();
				console.log(res);
				if (res.code !== 200) return;
				this.swiper = res.data;
			},
			scanCode() {
				// 允许从相机和相册扫码
				uni.scanCode({
					scanType: ["qrCode"],
					success: (res) => {
						console.log('条码类型:' + res.scanType);
						console.log('条码内容:' + res.result);
						if (res.result) {
							const val = res.result;
							console.log(val)
							// uni.navigateTo({
							// 	url: val
							// })
							void plus.runtime.openWeb(val);
						} else {
							console.log('请重新扫描');
							return false;
						}
					},
					fail: (res) => {
						console.log('未识别到二维码');
					}
				})
			},
		},
	};
</script>

<style lang="scss">
	.u-nav-slot {
		margin-right: 20rpx;
	}

	.search-wrap {

		margin: 0 30rpx 0 10rpx;
		flex: 1;
	}

	.u-body-item {
		font-size: 32rpx;
		color: #333;
		padding: 20rpx;
	}

	.u-body-item image {
		width: 180rpx;
		flex: 0 0 180rpx;
		height: 150rpx;
		border-radius: 6rpx;
		margin-right: 12rpx;
	}

	.height {
		height: 88rpx;
	}

	.toptem {
		padding: 20rpx 0;
	}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值