美文网首页前端开发让前端飞Web前端之路
基于nuxt和iview搭建OM后台管理系统实践(3)-阿里os

基于nuxt和iview搭建OM后台管理系统实践(3)-阿里os

作者: 小呆爱学习 | 来源:发表于2018-06-12 20:02 被阅读99次
    封面图,基于创客贴在线制作

    目录结构

    这是《基于nuxt和iview搭建OM后台管理系统实践》这一个系列文章的目录,大致思路如下:

    前言

    上一篇记录了quill富文本的封装过程,这一篇开始讲解上传组件(七牛、阿里云oss)的封装。

    看东西

    如动图所示,为上传组件演示,可以看到组件有上传、预览、删除重新上传、文件大小校验等功能。


    上传组件演示

    阿里oss上传组件实现过程

    实现原理:用input[type='file']标签,并绑定一个change事件实现选择本地电脑文件操作,同时通过其他button触发input的change事件,最终与阿里oss进行交互实现上传图片的功能。

    步骤1:引入阿里云osssdk代码,需要注意的是:框架使用的nuxt,引入sdk需要按照nuxt的规范在head方法里引入,附上head方法使用文档地址

    // 文件 components/upload.vue
    <template>
    <!--省略业务代码-->
    </template>
    <script>
    export default {
      head: {
        script: [{ src: "http://gosspublic.alicdn.com/aliyun-oss-sdk.min.js" }]//引入sdk
      },
    <script>
    <style>
    /*省略样式代码*/
    </style>
    

    步骤2:获取上传token,后端提供接口,因token有时效性故每次上传操作时需向后端请求;

    // 文件 components/upload.vue
    <template>
    <!--省略业务代码-->
    </template>
    <script>
    import axios from "~/plugins/axios";
    
    export default {
      head: {
        script: [{ src: "http://gosspublic.alicdn.com/aliyun-oss-sdk.min.js" }]//引入sdk
      },
      method:{
          doUpload() {
              const _this = this;
              const urls = [];
              this.loading = true;
              axios.get("/api/m/common/oss/getproperties") 
              .then(res=>{
                //向后端请求获取oss token等信息
                  _this.ossKey.AccessKeyId = res.data.data.AccessKeyId;
                  _this.ossKey.AccessKeySecret = res.data.data.AccessKeySecret;
                  _this.ossKey.BucketName = res.data.data.BucketName;
                  _this.ossKey.SecurityToken = res.data.data.SecurityToken;
                  
                //与阿里oss交互,上传文件到服务器并返回文件路径
              })
          }
      }
    <script>
    <style>
    /*省略样式代码*/
    </style>
    

    步骤3:与阿里oss交互,上传文件到服务器并返回文件路径;

    //
    postOss(){
        const _this = this;
        const client = new window.OSS.Wrapper({
            region: _this.region,
            accessKeyId: _this.ossKey.AccessKeyId,
            accessKeySecret: _this.ossKey.AccessKeySecret,
            stsToken: _this.ossKey.SecurityToken,
            bucket: _this.ossKey.BucketName
        });
        _this.percentage = 0;
        const files = document.getElementById(_this.id);
        if(files.files[0].size > _this.limitSize){//对文件大小进行校验超出弹出提示框
            _this.$Notice.warning({
                title: '温馨提示',
                desc:  '文件超出'+_this.limitSize/1024+'kb限制,请压缩一下图片再上传'
            });
            _this.loading = false;
            return false;
        }
        if (files.files) {
            const fileLen = document.getElementById(_this.id).files;
            let resultUpload = "";
            for (let i = 0; i < fileLen.length; i++) {
                const file = fileLen[i];
                 // 随机命名
                let random_name ="mapOm/" + random_string(6) + "_" + new Date().getTime() + "." + file.name.split(".").pop();
                  // 上传
                client.multipartUpload(random_name, file, {
                    progress: function*(percentage, cpt) {
                        // 上传进度
                        _this.percentage = percentage;
                    }
                })
                .then(results => {
                    // 上传完成
                    _this.loading = false;
                     _this.show = true;
                     const url = "http://sinochem-agri-fr.oss-cn-beijing.aliyuncs.com/" + results.name;
                     _this.url = url;
                    _this.$emit('uploadedUrl',results.name);//把url传给父组件
                })
                .catch(err => {
                    _this.loading = false;
                    console.log(err);
                });
            }
        }
    }
    

    步骤4:引用并使用组件;

    import uploadImg from '~/components/upload';//引入组件
    
    <upload-img label="土壤温度" id="soilTemperature"
        @uploadedUrl="(url) => this.formItem.trend.soilTemperature = url"
        @remove="() => this.formItem.trend.soilTemperature = ''">
    </upload-img>
    

    阿里oss上传组件完整代码

    <template>
        <FormItem :label="label">
              <template  v-if="!edit">
                <input :id="id" ref="input" @change="doUpload" class="file" type="file">
                <div class="demo-upload-list" v-if="show">
                  <img :id="'img_'+id"  :src="url" width="50px" height="50px">
                  <div class="demo-upload-list-cover">
                    <Icon type="ios-eye-outline" @click.native="handleView"></Icon>
                    <Icon type="ios-trash-outline" @click.native="handleRemove"></Icon>
                  </div>
                </div>
                <Button v-if="!show" :loading="loading" type="ghost" icon="ios-cloud-upload-outline" @click="upload">{{placeholder}}</Button>
                <Modal :title="label+'预览'" v-model="visible">
                  <img :src="url" v-if="visible" style="width:100%;height:auto;">
                </Modal>
              </template>
        
              <!-- 预览 -->
              <template  v-else>
                <div class="demo-upload-list">
                  <img :id="'img_'+id"  :src="editUrl" width="50px" height="50px">
                  <div class="demo-upload-list-cover">
                    <Icon type="ios-eye-outline" @click.native="handleView"></Icon>
                    <Icon type="ios-trash-outline" @click.native="handleRemove"></Icon>
                  </div>
                </div>
                <Modal :title="label+'预览'" v-model="visible">
                  <img :src="editUrl" v-if="visible" style="width:100%;height:auto;">
                </Modal>
              </template>
        </FormItem>
    
    </template>
    
    <script>
    import axios from "~/plugins/axios";
    import { random_string } from "~/lib/utils";
    
    export default {
      head: {
        script: [{ src: "http://gosspublic.alicdn.com/aliyun-oss-sdk.min.js" }]
      },
      props: {
        editUrl: {
          default: ""
        },
        showUploadList: {
          type: Boolean,
          default: true
        },
        action: {
          default: ""
        },
        label: {
          default: "上传组件"
        },
        placeholder: {
          default: "上传图表"
        },
        id: {
          default: "upload"
        },
        limitSize: {
          default: 102400
        }
      },
      name: "upload",
      data() {
        return {
          loading: false,
          visible: false,
          show: false,
          region: "oss-cn-beijing",
          percentage: 0,
          url: "",
          urls: [],
          fileList: [],
          ossKey: {},
          edit: false
        };
      },
      created() {},
      mounted() {},
      methods: {
        doUpload() {
          const _this = this;
          const urls = [];
          this.loading = true;
    
          axios
            .get("/api/getproperties")
            .then(res => {
              _this.ossKey.AccessKeyId = res.data.data.AccessKeyId;
              _this.ossKey.AccessKeySecret = res.data.data.AccessKeySecret;
              _this.ossKey.BucketName = res.data.data.BucketName;
              // _this.ossKey.Endpoint = res.data.data.Endpoint;
              _this.ossKey.SecurityToken = res.data.data.SecurityToken;
    
              //上传
              const client = new window.OSS.Wrapper({
                region: _this.region,
                accessKeyId: _this.ossKey.AccessKeyId,
                accessKeySecret: _this.ossKey.AccessKeySecret,
                stsToken: _this.ossKey.SecurityToken,
                bucket: _this.ossKey.BucketName
              });
              _this.percentage = 0;
              const files = document.getElementById(_this.id);
              if (files.files[0].size > _this.limitSize) {
                _this.$Notice.warning({
                  title: "温馨提示",
                  desc:
                    "文件超出" +
                    _this.limitSize / 1024 +
                    "kb限制,请压缩一下图片再上传"
                });
                _this.loading = false;
                return false;
              }
    
              if (files.files) {
                const fileLen = document.getElementById(_this.id).files;
                let resultUpload = "";
                for (let i = 0; i < fileLen.length; i++) {
                  const file = fileLen[i];
                  // 随机命名
                  let random_name =
                    "mapOm/" +
                    random_string(6) +
                    "_" +
                    new Date().getTime() +
                    "." +
                    file.name.split(".").pop();
                  // 上传
                  client
                    .multipartUpload(random_name, file, {
                      progress: function*(percentage, cpt) {
                        // 上传进度
                        _this.percentage = percentage;
                      }
                    })
                    .then(results => {
                      // 上传完成
                      _this.loading = false;
                      _this.show = true;
                      const url =
                        "http://sinochem-agri-fr.oss-cn-beijing.aliyuncs.com/" +
                        results.name;
                      _this.url = url;
                      _this.$emit("uploadedUrl", results.name); //把url传给父组件
                    })
                    .catch(err => {
                      _this.loading = false;
                      console.log(err);
                    });
                }
              }
            })
            .catch(errro => {
              this.$Notice.error({
                title: "温馨提示",
                desc: "网络请求失败,请稍后再试"
              });
              _this.loading = false;
              console.log(errro);
            });
        },
        upload() {
          var av = document.getElementById(this.id);
          av.click();
        },
        handleView() {
        //预览
          this.visible = true;
        },
        handleRemove() {
        //删除图片
          const _this = this;
          if (_this.edit == true) {
            _this.edit = false;
            _this.$emit("remove");
          } else {
            _this.visible = false;
            _this.show = false;
            _this.$emit("remove");
          }
        }
      },
      watch: {
        url(val) {
          if (val) {
            this.urls.push(val);
          }
        },
        editUrl() {
          if (this.editUrl != null && this.editUrl != "") {
            this.edit = true;
          }
        }
      }
    };
    </script>
    
    <style scoped>
    .file {
      display: none;
    }
    .demo-upload-list {
      display: inline-block;
      width: 60px;
      height: 60px;
      text-align: center;
      line-height: 60px;
      border: 1px solid transparent;
      border-radius: 4px;
      overflow: hidden;
      background: #fff;
      position: relative;
      box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
      margin-right: 4px;
    }
    .demo-upload-list img {
      width: 100%;
      height: 100%;
    }
    .demo-upload-list-cover {
      display: none;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background: rgba(0, 0, 0, 0.6);
    }
    .demo-upload-list:hover .demo-upload-list-cover {
      display: block;
    }
    .demo-upload-list-cover i {
      color: #fff;
      font-size: 20px;
      cursor: pointer;
      margin: 0 2px;
    }
    </style>
    
    

    总结

    iview官方提供了一个上传组件,但是不符合我们实际需求,我查看了源码并在此基础上进行了二次封装最终实现了需求。现在再回过头去看写的代码发现有点乱,后续抽空会进行代码优化。同时要吐槽下阿里oss文档,都没有一个demo让开发者查看,显得很不友好。

    相关文章

      网友评论

      本文标题:基于nuxt和iview搭建OM后台管理系统实践(3)-阿里os

      本文链接:https://www.haomeiwen.com/subject/cfireftx.html