改造之前的项目articleDemo
,增加图片上传功能
在添加页面add.vue文件中写一个盒子导入文件选择上传组件
文档在uniapp
组件
扩展组件
uni-file-picker
在页面中引入组件,把变量值双向绑定到data
<template>
<view class="add">
<form @submit="onSubmit">
<view class="item">
<!-- 标题输入框 -->
<input v-model="formValue.title" type="text" name="title" placeholder="请输入标题"></input>
</view>
<view class="item">
<!-- 作者输入框 -->
<input v-model="formValue.author" type="text" name="author" placeholder="请输入作者"></input>
</view>
<view class="item">
<!-- 多行输入框 -->
<textarea v-model="formValue.content" name="content" placeholder="请输入内容"></textarea>
</view>
<view class="item">
<uni-file-picker
v-model="imageValue"
fileMediatype="image"
mode="grid"
@success="success"
/>
</view>
<view class="item">
<button form-type="reset">重置</button>
<!-- 对按钮进行双向绑定,这样用户每次输入值才能动态的调用判断方法 判断按钮 -->
<button form-type="submit" type="primary" :disabled="inDisabled(formValue)">提交</button>
</view>
</form>
</view>
</template>
<script>
export default {
data() {
return {
imageValue:[],
formValue:{
title:"",
author:"",
content:""
}
};
},
现在虽然绑定的success方法还没有写,但是点击加号选图片,能成功上传到云存储了
保存图片url到数据库
<view class="item">
<uni-file-picker
v-model="imageValue"
fileMediatype="image"
mode="grid"
@success="uploadSuccess"
/>
</view>
// 图片上传成功
uploadSuccess(e){
console.log(e);
},
给上传成功写一个方法,下面就是返回值,第一个属性只有已经存到云存储的url,这个不是临时url,第二个有上传文件完整的属性
在data中定义一个变量picurls保存这个url,因为图片可能有多张,所以picurls的值是一个数组然后在图片上传成功方法中赋值给它 这里使用第一个,仅保存url不保存其他信息,现在,再在新增文章页面点击提交按钮,就可以把url地址保存到数据库了
// 图片上传成功
uploadSuccess(e){
this.picurls = e.tempFilePaths
},
提交: 分两步,一步是传递数据到云函数,二是在云函数中将数据保存到数据库 一、在提交方法中,把picurls变量加到data中进行传递
<script>
export default {
data() {
return {
imageValue:[],
formValue:{
title:"",
author:"",
content:""
},
picurls:[]
};
},
methods:{
// 图片上传成功
uploadSuccess(e){
this.picurls = e.tempFilePaths
},
// 判断按钮的是否禁用
// 这里是通过obj接收值所以不用写this,不传值也可以,写上this.一样
inDisabled(obj){
// 循环判断key的三个值是否为空,不为空就返回true,使按钮变为可用状态
for(let key in obj){
// obj[key]和obj.key一样的效果,打印出来的值就是用户输入的值
// console.log(obj[key]);
if(!obj[key]){
return true
}
}
},
// 点击提交触发此方法
onSubmit(e){
// 获取到用户输入并赋值
let detail=e.detail.value
// 接收云函数传过来的值
uniCloud.callFunction({
name:"art_add_row",
// 将获取到的用户输入传递到服务器
data:{
// detail:detail
detail,
picurls: this.picurls
}
}).then(res=>{
uni.showToast({
title:"发布成功"
}),
// 给跳转加一个延时,要不然看不到发布成功的提示框
setTimeout(()=>{
uni.reLaunch({
url:"/pages/index/index"
})
},800)
})
}
}
}
</script>
二、在云函数art_add_row中,接收并保存
'use strict';
const db=uniCloud.database();
exports.main = async (event, context) => {
let {detail, picurls} = event;
return await db.collection("article").add({
posttime:Date.now(),
picurls,
// detail是一个对象,不解构出来就存为一个对象了
...detail
})
};
现在添加页面的全部代码
<template>
<view class="add">
<form @submit="onSubmit">
<view class="item">
<!-- 标题输入框 -->
<input v-model="formValue.title" type="text" name="title" placeholder="请输入标题"></input>
</view>
<view class="item">
<!-- 作者输入框 -->
<input v-model="formValue.author" type="text" name="author" placeholder="请输入作者"></input>
</view>
<view class="item">
<!-- 多行输入框 -->
<textarea v-model="formValue.content" name="content" placeholder="请输入内容"></textarea>
</view>
<view class="item">
<uni-file-picker
v-model="imageValue"
fileMediatype="image"
mode="grid"
@success="uploadSuccess"
/>
</view>
<view class="item">
<button form-type="reset">重置</button>
<!-- 对按钮进行双向绑定,这样用户每次输入值才能动态的调用判断方法 判断按钮 -->
<button form-type="submit" type="primary" :disabled="inDisabled(formValue)">提交</button>
</view>
</form>
</view>
</template>
<script>
export default {
data() {
return {
imageValue:[],
formValue:{
title:"",
author:"",
content:""
},
picurls:[]
};
},
methods:{
// 图片上传成功
uploadSuccess(e){
this.picurls = e.tempFilePaths
},
// 判断按钮的是否禁用
// 这里是通过obj接收值所以不用写this,不传值也可以,写上this.一样
inDisabled(obj){
// 循环判断key的三个值是否为空,不为空就返回true,使按钮变为可用状态
for(let key in obj){
// obj[key]和obj.key一样的效果,打印出来的值就是用户输入的值
// console.log(obj[key]);
if(!obj[key]){
return true
}
}
},
// 点击提交触发此方法
onSubmit(e){
// 获取到用户输入并赋值
let detail=e.detail.value
// 接收云函数传过来的值
uniCloud.callFunction({
name:"art_add_row",
// 将获取到的用户输入传递到服务器
data:{
// detail:detail
detail,
picurls:this.picurls
}
}).then(res=>{
uni.showToast({
title:"发布成功"
}),
// 给跳转加一个延时,要不然看不到发布成功的提示框
setTimeout(()=>{
uni.reLaunch({
url:"/pages/index/index"
})
},800)
})
}
}
}
</script>
<style lang="scss" scoped>
.add {
padding: 30rpx;
.item {
padding-bottom: 20rpx;
input,
textarea {
border: 1rpx solid #eee;
height: 80rpx;
padding: 0 20rpx;
}
textarea {
height: 200rpx;
// 文本域有原生的宽度,所以设置这个属性
width: 100%;
// 这里有一个问题,原本在app.vue里是设置了怪异盒模型的
// 使添加的边距向父盒子内压缩
// 但是这里没有起效果,使得给文本域加了宽度为100%后
// 文本域的右边就顶到屏幕右边了
// 所以给他加一个标准盒模型,使父盒子的外边距再把它顶回来
// 但是只是右边顶到了屏幕上,左边没有,就不知道什么情况
box-sizing: border-box;
}
button {
margin-bottom: 20rpx;
}
}
}
</style>
现在数据库里已经有数据了,再把图片从数据库获取到前端渲染出来就行了,还有修改页面,也要添加图片