unicloud36-项目改造 文章管理系统导入filepick上传组件

47 阅读1分钟

改造之前的项目articleDemo,增加图片上传功能

在添加页面add.vue文件中写一个盒子导入文件选择上传组件

文档在uniapp \rightarrow 组件 \rightarrow 扩展组件 \rightarrow 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:""
          
        }
      };
    },

image.png

现在虽然绑定的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,第二个有上传文件完整的属性 image.png

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

现在数据库里已经有数据了,再把图片从数据库获取到前端渲染出来就行了,还有修改页面,也要添加图片