首页 > 其他分享 >JS默认参数传递额外参数(多文件上传, uploading)

JS默认参数传递额外参数(多文件上传, uploading)

时间:2023-06-09 18:44:37浏览次数:36  
标签:formState ant const index uploading fileList JS 参数传递 file

<!--
  module name: 应用介绍
-->
<template>
  <div
    class="main-intro"
    :style="{
      padding: props.type === 'serviceType' ? '0' : '0 16px',
      margin: props.type === 'serviceType' ? '0 0' : '0  auto',
    }"
  >
    <div class="main-intro-form">
      <a-form :model="formState" :label-col="labelCol" >
        <a-form-item :label="props.appName" :rules="[{ required: true }]">
          <a-textarea
            v-model:value="formState.appIntro"
            style="width: 100%"
            :disabled="props.disabledType"
          />
        </a-form-item>
        <a-form-item label="功能介绍" name="funcIntros">
          <div
            v-for="(intro, index) in formState.funcIntros"
            :key="index"
            style="margin-top: 5px; display: flex"
          >
            <a-input
              v-model:value="intro.name"
              placeholder="输入功能名称"
              style="width: 45%; border-radius: 5px"
              autoclear
              :disabled="props.disabledType"
            >
            </a-input>
            <a-input
              v-model:value="intro.desc"
              style="width: 45%; margin-left: 20px; border-radius: 5px"
              placeholder="功能描述"
              autoclear
              :disabled="props.disabledType"
            >
            </a-input>
            <PlusOutlined
              style="font-size: 20px; margin-left: 10px; color: #cccccc"
              v-show="index === 0"
              type="plus"
              @click="addDomain"
            />
            <MinusOutlined
              v-show="index !== 0 && index >= state.initIntrosSize"
              :disabled="index === 1"
              style="font-size: 20px; margin-left: 10px; color: #cccccc"
              @click="removeDomain(intro)"
            />
          </div>
        </a-form-item>
        <a-form-item label="系统截图" name="osScreenshots">
          <div class="snapshot-container">
            <div class="img-box" v-for="(item, index) in formState.osFiles">
              <div v-if="item.response === undefined">
                <a-spin style="position: relative; top: 80px; left: 60px" />
              </div>
              <div v-if="item.response !== undefined">
                <div>
                  <img
                    alt="系统截图"
                    class="img"
                    :src="item.response.data.address"
                  />
                  <CloseCircleFilled
                    class="close-circle"
                    @click="delOsImg(index)"
                  />
                </div>
                <a-input
                  placeholder="截图名称"
                  v-model:value="item.response.data.name"
                  style="
                    width: 150px;
                    border: 1px solid #e9e9e9;
                    margin-top: 15px;
                  "
                  :disabled="props.disabledType"
                />
              </div>
            </div>
            <div class="upload-container">
              <a-upload
                v-model:file-list="formState.osFiles"
                action="/empower/attachment/upload"
                list-type="picture-card"
                :show-upload-list="false"
                :disabled="props.disabledType"
              >
                <plus-outlined />
                <div class="ant-upload-text">图片上传</div>
              </a-upload>
            </div>
          </div>
        </a-form-item>
        <a-form-item label="学习视频" name="learningVideos">
          <div class="videos-container">
            <div
              v-for="(item, index) in formState.learningVideos"
              class="video-box"
            >
              <div v-if="item.response === undefined">
                <a-spin style="position: relative; top: 80px; left: 60px" />
              </div>
              <div
                v-if="item.response !== undefined"
                style="margin-right: 20px"
              >
                <video
                  :src="item.response.data.address"
                  controls
                  class="video"
                />
                <CloseCircleFilled
                  class="close-circle"
                  @click="delVideo(index)"
                />
              </div>
              <a-input
                v-model:value="item.response.data.name"
                style="width: 285px"
                v-if="item.response !== undefined"
                placeholder="视频名称"
                :disabled="props.disabledType"
              />
            </div>
            <div class="upload-video">
              <a-upload
                v-model:file-list="formState.learningVideos"
                action="/empower/attachment/upload"
                list-type="picture-card"
                :show-upload-list="false"
                :disabled="props.disabledType"
              >
                <div v-if="formState.learningVideos.length < 8">
                  <plus-outlined />
                  <div class="ant-upload-text">视频上传</div>
                </div>
              </a-upload>
            </div>
          </div>
        </a-form-item>
        <a-form-item label="学习文档">
          <a-upload
            v-model:file-list="formState.learningFiles"
            name="file"
            :multiple="true"
            action="/empower/attachment/upload"
            @change="learningFilesChange"
            :disabled="props.disabledType"
            style="width: 350px"
          >
            <a-button
              style="background-color: #eaf2ff; border: none"
              :loading="fileLoading"
            >
              <upload-outlined />
              <span style="color: #2c79ff">上传</span>
            </a-button>
          </a-upload>
        </a-form-item>
      </a-form>
    </div>
  </div>
</template>

<script setup>
import {
  defineComponent,
  ref,
  reactive,
  watch,
  watchEffect,
  defineExpose,
  defineEmits,
  toRaw,
  onBeforeUnmount,
  onMounted,
} from "vue";
import { useRoute, useRouter } from "vue-router";
import { message } from "ant-design-vue";
import { nanoid } from "nanoid";
import mitt from "@/utils/mitt";
import {
  MinusOutlined,
  PlusOutlined,
  UploadOutlined,
  CloseCircleFilled,
} from "@ant-design/icons-vue";

const router = useRouter();
const route = useRoute();
const labelCol = { style: { width: "75px" } };
const state = reactive({
  fileLoading: false,
  initIntrosSize: 1,
});
const previewVisible = ref(false);
const previewImage = ref("");
const props = defineProps(["type", "disabledType", "appName"]);

const formState = reactive({
  appIntro: "", // 应用简介
  funcIntros: [
    {
      name: "",
      desc: "",
    },
  ], // 功能介绍
  osFiles: [], // 系统截图文件对象
  osScreenshots: [], // 系统截图
  learningVideos: [], // 学习视频
  learningFiles: [], // 学习文档
  fileList: [],
});

// ======================= 功能介绍 start ====================
const removeDomain = (intro) => {
  let index = formState.funcIntros.indexOf(intro);
  if (index !== -1) {
    formState.funcIntros.splice(index, 1);
  }
};
const addDomain = () => {
  formState.funcIntros.push({
    name: "", // 功能名称
    desc: "", // 功能描述
  });
};
// ======================= 功能介绍 end ====================

// ====================== 系统截图 start ===================
const handleCancel = () => {
  previewVisible.value = false;
};
const handlePreview = async (file) => {
  console.log("file 预览", file);
  if (!file.url && !file.preview) {
    file.preview = await getBase64(file.originFileObj);
  }
  previewImage.value = file.url || file.preview;
  previewVisible.value = true;
};
const handleChange = ({ fileList: newFileList }) => {
  fileList.value = newFileList;
};

const getBase64 = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
};
// ====================== 系统截图 end   ===================
const osFileChange = (e) => {
  console.log("e:::: ", e);
  let fileList = [...e.fileList];
  let formFiles = fileList.map((file) => {
    let resArr = [];
    if (file.response !== undefined) {
      resArr.push({
        snapshotName: "",
        ...file,
        address: file.response.data.address,
        id: file.response.data.id,
      });
    }
    return resArr;
  });
  if (formFiles.length > 0) {
    formState.osScreenshots = formFiles.map((formFile) => {
      return formFile;
    });
  }
};

const delOsImg = (index) => {
  formState.osFiles.splice(index, 1);
};
// ====================== 学习视频 start ===================
const delVideo = (index) => {
  formState.learningVideos.splice(index, 1);
};
// TODO videosChange
const videosChange = (e) => {
  let fileList = [...e.fileList];
  let formFiles = fileList.map((file) => {
    let resArr = [];
    if (file.response !== undefined) {
      resArr.push({
        name: "",
        ...file,
        address: file.response.data.address,
        id: file.response.data.id,
      });
    }
    return resArr;
  });
  if (formFiles.length > 0) {
    formState.osScreenshots = formFiles.map((formFile) => {
      return formFile;
    });
  }
};
// ====================== 学习视频 end   ===================

// ====================== 学习文档 start ===================
const learningFilesChange = (e) => {
  let fileList = [...e.fileList];
  console.log("fileList::: ", fileList);
  //read from response and show file link
  fileList = fileList.map((file) => {
    if (file.response) {
      // Component will show file.url as link
      file.url = file.response.address;
    }
    return file;
  });

  formState.fileList = fileList;
};

const delFiles = (index) => {
  formState.learningFiles.splice(index, 1);
};
// ====================== 学习文档 end   ===================
defineExpose({
  formState,
});
</script>

<style lang="scss" scoped>
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}

.main-intro {
  padding: 0 16px;
  width: 600px;
  text-align: left;
  margin: 0 auto;

  &-form {
    border-radius: 8px;
    padding: 0 24px;
    background-color: #fff;

    .snapshot-container {
      display: flex;
      flex-wrap: wrap;

      .img-box {
        width: 150px;
        margin-right: 15px;
        position: relative;

        .img {
          width: 100%;
          height: 150px;

          &:hover {
            border: 4px solid #4688f1;
          }
        }
        &:hover .close-circle {
          display: inline-block;
        }
        .close-circle {
          font-size: 20px;
          color: #4688f1;
          position: absolute;
          right: -13px;
          top: -10px;
          cursor: pointer;
          display: none;
        }
      }
    }

    .videos-container {
      display: flex;
      flex-wrap: wrap;

      .video-box {
        position: relative;
        width: 305px;
        margin-right: 8px;
        .video {
          width: 100%;
          height: 170px;
          border-radius: 5px;

          &:hover {
            border: 4px solid #4688f1;
          }
        }

        &:hover .close-circle {
          display: inline-block;
        }

        .close-circle {
          font-size: 20px;
          color: #4688f1;
          position: absolute;
          right: 6px;
          top: -7px;
          cursor: pointer;
          display: none;
        }
      }
    }

    .upload-video {
      height: 222px;
    }

    :deep(.ant-upload.ant-upload-select-picture-card) {
      width: 150px;
      height: 171px;
      border: 1px solid #d0d4da;
      background-color: #fff;
    }

    :deep(.anticon-plus) {
      color: #d7d7d7;
      font-size: 30px;
      font-weight: 900;
    }

    :deep(.ant-btn .anticon) {
      color: #2c79ff;
    }

    :deep(.ant-upload-list) {
      width: 40% !important;
    }
  }
}
:deep(.ant-upload-list-item) {
  width: 450px;
}
</style>

标签:formState,ant,const,index,uploading,fileList,JS,参数传递,file
From: https://www.cnblogs.com/openmind-ink/p/17470026.html

相关文章

  • js和native交互 互相调用
    必须这样写,如果用vue可以在app.vue里面写,先把WebViewJavascriptBridge弄到window下面functionsetupWebViewJavascriptBridge(callback){    if((windowasany).WebViewJavascriptBridge){returncallback((windowasany).WebViewJavascriptBridge);}   ......
  • 拥抱jsx,开启vue3用法的另一种选择
    ......
  • threejs-css2dObject操作之物体遮挡标签后应该隐藏,而不是出现透视效果
    先看coding之前的效果: 这些在背面的标签的,转到一定角度,被模型遮挡后,理论上就不应该被看到。这才是比较符合实际的coding之后(另一侧对称点就被隐藏): 具体代码(j借助于光线投影)://绑定鼠标事件,当用户移动视角后触发()functionbindRayShotEvent(){document.addEvent......
  • js 中 对 Array 的操作
    判断数组中是否包含指定的多个值1、every()方法的定义与用法:every()方法用于检测数组中的所有元素是否都满足指定条件(该条件为一个函数)。every()方法会遍历数组的每一项,如果有有一项不满足条件,则表达式返回false,剩余的项将不会再执行检测;如果遍历完数组后,每一项都符合条,则返......
  • Caused by: java.lang.ClassNotFoundException: com.alibaba.fastjson2.util.Wrap
    1.情景展示使用fastjson2,运行时报错:Causedby:java.lang.ClassNotFoundException:com.alibaba.fastjson2.util.Wrap2.具体分析出现这个问题,是因为pom.xml当中引用的有关fastjson的jar包冲突造成的。只要我们把冲突的jar包排除掉就可以了。3.解决方案在idea当中,使用插件......
  • 什么是JS中的闭包?
    摘抄自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/ClosuresClosuresA closure isthecombinationofafunctionbundledtogether(enclosed)withreferencestoitssurroundingstate(the lexicalenvironment).Inotherwords,aclosuregivesyou......
  • 关于EasyPlayer.js播放器检测m3u8视频是否为H.265的优化
    EasyPlayer是可支持H.264/H.265视频播放的流媒体播放器,性能稳定、播放流畅,可支持的视频流格式有RTSP、RTMP、HLS、FLV、WebRTC等,具备较高的可用性。EasyPlayer还拥有Windows、Android、iOS版本,其灵活的视频能力,极大满足了用户的多样化场景需求。在播放器EasyPlayer.js5.0.7版本......
  • 使用Animate和CreateJS设计H5页面
    Animate和CreateJS是常用于HTML5页面设计的工具,通过使用这些工具,可以创建各种动画特效,从而提高交互性和视觉效果。游戏:Animate和CreateJS可以用于创建精彩的网页游戏,比如跑酷类、动作类、益智类等众多不同类型的游戏。这些游戏通常需要丰富的场景设计、角色设定、音效、背景音......
  • 关于EasyPlayer.js播放器检测m3u8视频是否为H.265的优化
    EasyPlayer是可支持H.264/H.265视频播放的流媒体播放器,性能稳定、播放流畅,可支持的视频流格式有RTSP、RTMP、HLS、FLV、WebRTC等,具备较高的可用性。EasyPlayer还拥有Windows、Android、iOS版本,其灵活的视频能力,极大满足了用户的多样化场景需求。在播放器EasyPlayer.js5.0.7版本中,......
  • Nest.js + TypeOrm:原始SQL查询及其参数绑定
    上一篇Nest.js+TypeOrm:安装、编写实体类参数化原始SQL查询使用DataSource,注意,如果是PostgreSQL,则参数占位符不能使用问号?,只能使用$n,并且在没有表名的情况下需要指定类型:否则,会出现错误:PostgreSQL-ERROR:couldnotdeterminedatatypeofparameter$1,参见:https://b......