TS使用Upload上传图片

主页面

图片回显
          <vxe-column field="icon" title="应用图标" align="center">
            <template slot-scope="scope">
              <el-image style="height: 40px;width: 40px;" :src="scope.row.icon"></el-image>
            </template>
          </vxe-column>

主界面打开dialog的form表单

//添加应用
  private addApplication() {
    ;(this.$refs.addUpdateApplication as any).dialogVisible = true
    ;(this.$refs.addUpdateApplication as any).editMode = false
  }

表单页面

form表单的upload写法

 public dialogVisible: Boolean = false
  public editMode: Boolean = false
 <el-form-item label="应用图标">
        <el-upload class="upload-demo" ref="upload" action="" :on-remove="handleRemove" :file-list="file_list" :on-change="getFile" :auto-upload="false" list-type="picture" :limit="1">
          <el-button size="small" type="primary">上传应用图标</el-button>
        </el-upload>
      </el-form-item>
    </el-form>

 file数据

fileList数据

//存图片
  private file_list: any[] = []

 // 移除上传的文件时的回调
  private handleRemove() {
    this.form.icon = ''
    this.$delete(this.file_list, 0)
  }

//清除表单数据
  private clearForm() {
    this.form = {}
    this.form.appPaltform = 'pc'
    this.$delete(this.file_list, 0)
  }

// 图片转base64
  private getBase64(file) {
    return new Promise(function(resolve, reject) {
      let reader = new FileReader()
      let imgResult = ''
      reader.readAsDataURL(file)
      reader.onload = function() {
        imgResult = reader.result as any
      }
      reader.onerror = function(error) {
        reject(error)
      }
      reader.onloadend = function() {
        resolve(imgResult)
      }
    })
  }



//文件变化事件
// 当文件状态改变、添加文件、上传成功和上传失败时调用
  private getFile(file, fileList) {
    //获取5.png的 png字符串
    let fileType = file.name.substring(file.name.lastIndexOf('.') + 1)
    //限制图片大小
    let fileSize = file.size / 1024 / 1024 < 5
    //如果图片格式不是png/jpg或者jpeg
    if (fileType !== 'png' && fileType !== 'jpg' && fileType !== 'jpeg') {
    //清空已上传的文件列表(该方法不支持在 before-upload 中调用)
      ;(this.$refs.upload as any).clearFiles()
      this.$message.warning('上传文件只能是 .png、.jpg、jpeg格式!')
      return false
        //如果尺寸不对
    } else if (!fileSize) {
      ;(this.$refs.upload as any).clearFiles()
      this.$message.warning('上传文件大小不能超过 5MB!')
      return false
    } else {
        //转base64
      this.getBase64(file.raw).then((res) => {
        //res就是图片的地址
        //把图片地址放到form里,调接口再传
        this.form.icon = res
      })
    }
  }

表单确认

  //编辑/添加应用
  private async upload() {
    ;(this.$refs['form'] as any).validate(async (valid) => {
      if (valid) {
        let res = await AddOrUpdateApplication(this.form)
        this.handleClose()
      } else {
        this.$message.warning('表单不符合要求')
        return false
      }
    })
  }

以下是全部代码

1.主页面

<template>
  <div style="height: 100%;width: 100%;position: relative;">
    <div class="table-frame showApp-list">
      <!-- 应用展示 -->
      <div class="showApp_title">
        <span style="display:inline-block;margin-left:0.5%">应用展示</span>
      </div>
      <div class="showApp_Container">
        <div class="appCard" v-for="item in tableData" :key="item.id">
          <div class="card-imgContainer">
            <img :src="item.icon" @click="clickImg(item.url)" class="card-img" />
          </div>
          <div class="card-text">
            {{ item.name }}
          </div>
        </div>
      </div>

      <!-- 应用图标 -->
    </div>

    <div style="height: calc(80% - 20px);width: 100%;">
      <xTable ref="xtable" :tableData="tableData" :tablePage="{}" :showSearchBtn="true" :showClearSearchInfoBtn="true" :isShowPage="false" :showSearchBox="true" :tableConfigure="tableConfigure" @onSearch="getAllApplication" @onClientSearchInfo="searchReset">
        <template v-slot:searchBox>
          <el-col :span="5">
            <div class="grid-content bg-purple">
              <p class="input-name">应用名称:</p>
              <el-input v-model="searchInput.appName" clearable></el-input>
            </div>
          </el-col>
          <el-col :span="5">
            <div class="grid-content bg-purple">
              <p class="input-name">应用链接:</p>
              <el-input v-model="searchInput.appUrl" clearable></el-input>
            </div>
          </el-col>
          <el-col :span="5">
            <div class="grid-content bg-purple">
              <p class="input-name">应用类型:</p>
              <el-select v-model="searchInput.appPaltform" clearable @change="selectChange" placeholder="请选择">
                <el-option key="pc" label="pc" value="pc"></el-option>
                <el-option key="app" label="app" value="app"></el-option>
              </el-select>
            </div>
          </el-col>
        </template>

        <template #optionBtns>
          <div class="operationBtnBox">
            <el-row>
              <el-button class="blueDelete_box" @click="removeUserMultiple">
                <div>
                  <svg-icon icon-class="blueDelete_small"></svg-icon>
                  <p>批量删除</p>
                </div>
              </el-button>
              <el-button class="add_box" @click="addApplication">
                <div>
                  <svg-icon icon-class="add_small"></svg-icon>
                  <p>添加</p>
                </div>
              </el-button>
            </el-row>
          </div>
        </template>

        <template v-slot:columns>
          <vxe-column type="checkbox" width="4%" align="center"></vxe-column>
          <vxe-column field="id" title="应用ID" align="center"></vxe-column>
          <vxe-column field="name" title="应用名称" align="center"></vxe-column>
          <vxe-column field="url" title="应用链接" align="center">
            <template slot-scope="scope">
              <el-link :href="scope.row.url" type="primary">{{ scope.row.url }}</el-link>
            </template>
          </vxe-column>
          <vxe-column field="webHost" title="应用IP地址" align="center"></vxe-column>
          <vxe-column field="webPort" title="应用端口" align="center"></vxe-column>
          <vxe-column field="webPathTemplate" title="应用地址通配符" align="center"></vxe-column>
          <vxe-column field="gateWayPathTemplate" title="网关地址通配符" align="center"></vxe-column>

          <vxe-column field="icon" title="应用图标" align="center">
            <template slot-scope="scope">
              <el-image style="height: 40px;width: 40px;" :src="scope.row.icon"></el-image>
            </template>
          </vxe-column>
          <vxe-column field="appPaltform" title="应用类型" align="center"></vxe-column>
          <vxe-column title="应用操作" width="10%" align="center">
            <template slot-scope="scope">
              <el-button type="text" class="edit-textButton" @click.stop="editApplication(scope.row)">编辑</el-button>
              <span class="dividerLine">|</span>
              <el-button type="text" class="remove-textButton" @click.stop="deleteApplication([scope.row.id])">删除</el-button>
            </template>
          </vxe-column>
        </template>
      </xTable>
    </div>

    <addUpdateApplication :formObject="formObject" ref="addUpdateApplication" />
  </div>
</template>

<script lang="ts">
import addUpdateApplication from './addUpdateApplication.vue'
import xTable from '@src/components/TableBase/baseTable.vue'
import PageBase from '@src/views/PageBase'
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator'
import { GetAllApplication, DeleteApplication } from '../../serviceAPIs/service'
@Component({
  components: {
    xTable,
    addUpdateApplication
  }
})
export default class Index extends PageBase {
  private formObject: {} = {}
  private searchInput: any = { appName: '', appUrl: '', appPaltform: '' }
  private tableData: any[] = []
  private tableDataCache: any[] = []
  // private tablePage: any = {
  //   total: 0,
  //   currentPage: 1,
  //   pageSize: 10
  // }
  // table设置
  private tableConfigure: any = {
    tableTitle: '应用列表',
    imgSrc: ''
  }
  @Watch('searchInput', { deep: true })
  private watchSearchInput(val) {
    if (!val.appName && !val.appUrl && !val.appPaltform) {
      this.getAllApplication()
    }
  }
  mounted() {
    this.getAllApplication()
  }
  private clickImg(url) {
    this.$confirm('确认进入应用?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(() => {
        window.location.href = url
      })
      .catch(() => {
        this.$message({
          type: 'info',
          message: '取消进入应用'
        })
      })
  }
  private selectChange(option) {
    this.searchInput.appPaltform = option
  }
  // 获取所有应用、查询
  public async getAllApplication() {
    let res = await GetAllApplication(this.searchInput)
    if (this.searchInput.appPaltform) {
      this.tableData = res.filter((item) => {
        return item.appPaltform == this.searchInput.appPaltform
      })
    } else {
      this.tableData = res
    }

    this.tableDataCache = JSON.parse(JSON.stringify(res))
  }
  public searchReset() {
    this.searchInput = {
      appName: '',
      appUrl: '',
      appPaltform: ''
    }
  }
  // private toApplicationPlatform() {
  //   this.$router.push('/systemSettings/application_platform')
  // }
  //添加应用
  private addApplication() {
    ;(this.$refs.addUpdateApplication as any).dialogVisible = true
    ;(this.$refs.addUpdateApplication as any).editMode = false
  }
  //批量删除
  private removeUserMultiple() {
    let selectedRows = (this.$refs.xtable as any).getChooseRows() as any[]
    let selectIds = selectedRows.map((o) => o.id)
    if (selectIds.length == 0) {
      this.$message.warning('至少选择一个应用')
    } else {
      this.deleteApplication(selectIds)
    }
  }
  //删除应用
  private deleteApplication(val) {
    this.$confirm('删除应用?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        let res = await DeleteApplication(val)
        this.$message.success('删除成功!')
        this.getAllApplication()
      })
      .catch(() => {
        this.$message('删除取消')
      })
  }
  //编辑应用
  private editApplication(val) {
    ;(this.$refs.addUpdateApplication as any).dialogVisible = true
    ;(this.$refs.addUpdateApplication as any).editMode = true
    // 将formObject传递给addApplication,val是当前行的信息
    this.formObject = val
  }
}
</script>

<style lang="less" scoped>
@import '@/assets/monitorStyle.less';
/deep/ .vxe-table--body-wrapper.body--wrapper {
  height: calc(98% - 33px);
}
/deep/.table-box .el-button {
  margin-right: 0px;
}
.showApp_Container {
  height: calc(100% - 26px);
  width: 100%;
  display: flex;
  flex-direction: row;
}
.appCard {
  height: 100%;
  width: 5.6%;
  margin-right: 20px;
  box-shadow: 0px 0px 4px rgba(22, 103, 255, 0.2);
  font-size: 12px;
  display: flex;
  flex-direction: column;
}
.showApp-list {
  height: 20%;
  width: 100%;
  display: flex;
  flex-direction: column;
  margin-bottom: 20px;
}
.card-imgContainer {
  height: 64%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: flex-end;
}
.card-text {
  height: 36%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.card-img {
  width: 40px;
  height: 40px;
}
// 搜素按钮颜色
// /deep/ .input-box[data-v-476658ad] .seachBtn {
//   padding: 7px 12px;
//   margin-left: 20px;
//   border: 1px solid #18aeb7;
//   color: #fff;
//   background: #18aeb7;
// }
// 应用平台展示
.showapp {
  width: 100%;
  height: 20%;
  margin-bottom: 20px;
  background-color: #fff;
  border-radius: 5px;
}
.showApp_title {
  border-left: 6px solid var(--lyl_sideDecoration);
  width: 100%;
  height: 26px;
  font-weight: bold;
  font-size: 20px;
  padding-right: 10px;
  margin-bottom: 15px;
}

::v-deep .table-box[data-v-476658ad] .vxe-header--row {
  background-size: cover;
  color: black;
  font-weight: bold;
}
</style>

2.表单页面

<template>
  <el-dialog :title="editMode ? '编辑一个应用' : '添加一个应用'" :close-on-click-modal="false" :visible.sync="dialogVisible" @close="dialogClose" width="30%">
    <el-form ref="form" :rules="rules" :model="form" label-width="80px">
      <el-form-item label="应用名称" prop="name">
        <el-input v-model="form.name" maxlength="60" :show-word-limit="false" clearable></el-input>
      </el-form-item>
      <el-form-item label="应用链接" prop="url">
        <el-input v-model="form.url" maxlength="2000" :show-word-limit="false" clearable></el-input>
      </el-form-item>
      <el-form-item label="应用IP地址" prop="webHost">
        <el-input v-model="form.webHost" maxlength="60" :show-word-limit="false" clearable></el-input>
      </el-form-item>
      <el-form-item label="应用端口" prop="webPort">
        <el-input-number :min="0" :max="80000" v-model="form.webPort" clearable :show-word-limit="false"></el-input-number>
      </el-form-item>
      <el-form-item label="应用地址通配符" prop="webPathTemplate">
        <el-input v-model="form.webPathTemplate" maxlength="60" :show-word-limit="false" clearable></el-input>
      </el-form-item>
      <el-form-item label="网关地址通配符" prop="gateWayPathTemplate">
        <el-input v-model="form.gateWayPathTemplate" maxlength="60" :show-word-limit="false" clearable></el-input>
      </el-form-item>
      <el-form-item label="应用类型">
        <el-select v-model="form.appPaltform" placeholder="请选择">
          <el-option key="pc" label="pc" value="pc" />
          <el-option key="app" label="app" value="app" />
        </el-select>
      </el-form-item>
      <el-form-item label="应用图标">
        <el-upload class="upload-demo" ref="upload" action="" :on-remove="handleRemove" :file-list="file_list" :on-change="getFile" :auto-upload="false" list-type="picture" :limit="1">
          <el-button size="small" type="primary">上传应用图标</el-button>
        </el-upload>
      </el-form-item>
    </el-form>
    <span slot="footer">
      <el-button size="small" @click="handleClose">取消</el-button>
      <el-button size="small" type="primary" @click="upload">提交</el-button>
    </span>
  </el-dialog>
</template>
<script lang="ts">
import ComponentBase from '@src/views/ComponentBase'
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator'
import { AddOrUpdateApplication } from '../../serviceAPIs/service'
@Component({})
export default class addUpdateApplication extends ComponentBase {
  @Watch('formObject')
  private watch_formObject(val: any) {
    this.form = val
    this.file_list = [{ url: val.icon }]
  }
  public dialogVisible: Boolean = false
  public editMode: Boolean = false
  // private isImage: Boolean = false
  private file_list: any[] = []
  private form: any = {
    name: '',
    url: '',
    icon: '',
    appPaltform: 'pc'
  }
  private rules: any = {
    name: [{ required: true, message: '请输入应用名', trigger: 'blur' }, { min: 1, max: 60, message: '应用名字数要在1到60之间', trigger: ['blur', 'change'] }],
    url: [
      { required: true, message: '请输入应用链接', trigger: 'blur' },
      { min: 1, max: 2000, message: '应用链接字数要在1到2000之间', trigger: ['blur', 'change'] },
      {
        message: '应用链接不合法',
        trigger: ['blur', 'change'],
        pattern: /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/
      }
    ]
  }
  //编辑/添加应用
  private async upload() {
    ;(this.$refs['form'] as any).validate(async (valid) => {
      if (valid) {
        let res = await AddOrUpdateApplication(this.form)
        this.handleClose()
      } else {
        this.$message.warning('表单不符合要求')
        return false
      }
    })
  }
  // 移除上传的文件时的回调
  private handleRemove() {
    this.form.icon = ''
    this.$delete(this.file_list, 0)
  }
  // 对话框关闭时重新调取数据
  private dialogClose() {
    this.clearForm()
    ;(this.$parent as any).getAllApplication()
  }
  // 关闭对话框,清除表单
  private handleClose() {
    this.dialogVisible = false
    // this.clearForm()
  }
  private clearForm() {
    this.form = {}
    this.form.appPaltform = 'pc'
    this.$delete(this.file_list, 0)
  }
  // 当文件状态改变、添加文件、上传成功和上传失败时调用
  private getFile(file, fileList) {
    let fileType = file.name.substring(file.name.lastIndexOf('.') + 1)
    let fileSize = file.size / 1024 / 1024 < 5
    if (fileType !== 'png' && fileType !== 'jpg' && fileType !== 'jpeg') {
      ;(this.$refs.upload as any).clearFiles()
      this.$message.warning('上传文件只能是 .png、.jpg、jpeg格式!')
      return false
    } else if (!fileSize) {
      ;(this.$refs.upload as any).clearFiles()
      this.$message.warning('上传文件大小不能超过 5MB!')
      return false
    } else {
      // this.isImage = true
      this.getBase64(file.raw).then((res) => {

        this.form.icon = res
      })
    }
  }
  // 图片转base64
  private getBase64(file) {
    return new Promise(function(resolve, reject) {
      let reader = new FileReader()
      let imgResult = ''
      reader.readAsDataURL(file)
      reader.onload = function() {
        imgResult = reader.result as any
      }
      reader.onerror = function(error) {
        reject(error)
      }
      reader.onloadend = function() {
        resolve(imgResult)
      }
    })
  }
  @Prop({
    default: {}
  })
  formObject: {}
}
</script>
<style scoped></style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值