網(wǎng)站首頁 編程語言 正文
1,input設(shè)置type為file類型的問題
首先所有的組件庫包括element,ant等,自動(dòng)默認(rèn)capture屬性為false,這會(huì)導(dǎo)致手機(jī)端用該組件庫打開會(huì)直接彈出攝像頭拍攝,而無法調(diào)用相冊(cè)的問題,即便用自定義指令刪除該屬性,第一次進(jìn)入后第二次屬性依然存在的問題
如果只是用一次,不會(huì)回來重新上傳,使用ele,ant組件可以使用自定義指令解決
<Upload
v-removeCaptrue //自定義指令
type="file"
:file-list="item.fileList"
class="upload"
accept="image/*"
:onRemove="(file,fileLists)=>{onRemove(file,fileLists, index)}"
:disabled="uploading"
:maxCount="Number(item.keyAndvalueList[5].showValue)"
:before-upload="fileBeforeUpload"
>
<Button type="primary" :disabled="uploading" @click="uploadBtn(index)"> 上傳文件</Button>
</Upload>
js
自定義指令
directives:{
removeCaptrue:{ //這里創(chuàng)建自定義指令,里面的生命周期的回調(diào)參數(shù)會(huì)拿到所有配置這個(gè)v-指令的dom元素,可以在這里進(jìn)行操作
mounted(e) {
const f = e.querySelector("input") //拿到上傳文件的元素
f.removeAttribute("capture") //刪除屬性
console.log(f,111111111)
},
updated(e) {
const f = e.querySelector("input")
f.removeAttribute("capture")
console.log(f,111111111)
}
}
},
2,如果是上傳完了回來依然會(huì)是1情況,直接打開攝像頭,說明元素回顯了,刪除的屬性出現(xiàn)了,所以用input解決這個(gè)問題把
<div class="main">
<div>
<span>上傳文件
<input
id="upload"
accept="image/*"
class="img-input"
type="file"
@change="(file)=>fileBeforeUploadchange(file,index)"
/>
</span>
</div>
<ul>
<li v-for="(v,i) in item.fileList"><span>{{ v.name }}</span><img src="@/assets/img/刪除.svg" alt="" @click="onRemovefile(i)"/></li>
</ul>
</div>
js上傳交互+校驗(yàn)
const fileBeforeUploadchange= async (e,index) => {
console.log(e,e.target.files[0])
let file = e.target.files[0]
const types = ['image/jpg', 'image/jpeg', 'image/png']
if (!types.includes(file.type)) {
message.destroy()
message.error('圖片格式不符合要求,請(qǐng)重新上傳')
return
}
//校驗(yàn)上傳文件數(shù)量,后臺(tái)配置
if (fileList.length >= 100)) {
message.destroy()
message.error(`只能上傳${xxx}個(gè)文件`)
return
}
// 校驗(yàn)大小
if (file.size / 1024 / 1024 >50M) {
message.destroy()
message.error(`圖片上傳超過${baseForm.value[index].keyAndvalueList[4].showValue}M,請(qǐng)重新上傳`)
return
}
let formData = new FormData();
formData.append('image', file);
try {
const res = await API.upfile(formData); //掉上傳接口
if (res?.code === 0 && res?.data) {
value.push(res?.data) //表單提交時(shí)候的數(shù)據(jù)
fileList.push(file) //展示上傳成功的list列表
message.success('上傳成功')
} else {
message.config({
content: res?.msg || '上傳失敗,請(qǐng)重試',
top: 200,
duration: 3
})
}
return uploading.value = false
} catch (error) {
console.log(error, '上傳失敗')
uploading.value = false
}
return false
}
//上傳成功之后刪除對(duì)應(yīng)文件按鈕
const onRemovefile = (i)=>{
fileList.splice(i,1)
}
3,如果是for循環(huán)出來的按鈕,多個(gè)上傳表單
<template>
<div class="form" id="form" ref="form">
<div class="form-item" v-for="(item, index) in baseForm" :key="item.sort">
<!-- 輸入框 -->
<div v-if="item.type == 1">
<div class="title">{{ `${index + 1} 、 ${item.keyAndvalueList[0].showValue}` }}
<img src="@/assets/img/必填.svg" alt="" v-if="item.keyAndvalueList[3].showValue == '1'">
</div>
<!-- 提示 -->
<div class="hint">
<div>{{ item.keyAndvalueList[1].showValue }}</div>
<img :src="item.keyAndvalueList[2].showValue" alt="" v-if="item.keyAndvalueList[2].showValue">
</div>
<Input :disabled="item.keyAndvalueList[4].showValue == '0'" v-model:value="item.value" :maxlength="200"
:type="item.keyAndvalueList[4].showValue == '2' ? 'number' : 'text'"
:placeholder="`請(qǐng)輸入${item.keyAndvalueList[0].showValue}`"></Input>
</div>
<!-- 單選 -->
<div v-if="item.type == 3">
<div class="title">{{ `${index + 1} 、 ${item.keyAndvalueList[0].showValue}` }}
<img src="@/assets/img/必填.svg" alt="" v-if="item.keyAndvalueList[2].showValue == '1'">
</div>
<div class="hint">
<div>{{ item.keyAndvalueList[1].showValue }}</div>
</div>
<RadioGroup v-model:value="item.index">
<Radio :value="v.lable" v-for="(v, i) in item.keyAndvalueList[3].showValue" :key="i">{{ v.value }}</Radio>
</RadioGroup>
</div>
<!-- 多選 -->
<div v-if="item.type == 4">
<div class="title">{{ `${index + 1} 、 ${item.keyAndvalueList[0].showValue}` }}
<img src="@/assets/img/必填.svg" alt="" v-if="item.keyAndvalueList[2].showValue == '1'">
</div>
<div class="hint">
<div>{{ item.keyAndvalueList[1].showValue }}</div>
</div>
<CheckboxGroup v-model:value="item.value">
<Checkbox v-for="v in item.keyAndvalueList[3].showValue" :value="v" :key="v.key">{{ v }}</Checkbox>
</CheckboxGroup>
</div>
<!-- 附件上傳 -->
<div v-if="item.type == 2">
<div class="title">{{ `${index + 1} 、 ${item.keyAndvalueList[0].showValue}` }}
<img src="@/assets/img/必填.svg" alt="" v-if="item.keyAndvalueList[3].showValue == '1'">
</div>
<div class="hint">
<div>{{ item.keyAndvalueList[1].showValue }}</div>
<img :src="item.keyAndvalueList[2].showValue" alt="" v-if="item.keyAndvalueList[2].showValue">
</div>
<!-- <Upload v-removeCaptrue type="file" :file-list="item.fileList" class="upload"
accept="image/*"
:onRemove="(file,fileLists)=>{onRemove(file,fileLists, index)}"
:disabled="uploading" :maxCount="Number(item.keyAndvalueList[5].showValue)" :before-upload="fileBeforeUpload"
>
<Button type="primary" :disabled="uploading" @click="uploadBtn(index)"> 上傳文件</Button>
</Upload> -->
<div class="main">
<div>
<span>上傳文件
<input
:id="`upload${index}`"
accept="image/*"
class="img-input"
type="file"
@change="(file)=>fileBeforeUploadchange(file,index)"
/>
</span>
</div>
<ul>
<li v-for="(v,i) in item.fileList"><span>{{ v.name }}</span><img src="@/assets/img/刪除.svg" alt="" @click="onRemovefile(item,i)"/></li>
</ul>
</div>
</div>
</div>
<div class="submitBtn" @click="submitBtn" v-if="baseForm.length > 0">提交</div>
</div>
</template>
<script>
import API from '@/api/questionnaire.js'
import { ref, toRefs, reactive, watch, defineComponent, onMounted, nextTick } from 'vue'
import { Button, message, Input, Upload, Checkbox, RadioGroup, Radio, CheckboxGroup, Row, Col } from 'ant-design-vue'
import { ngx, obj, isPc } from '../views/mock'
import 'ant-design-vue/es/message/style/css'
import 'ant-design-vue/es/button/style/css'
import 'ant-design-vue/es/modal/style/css'
import 'ant-design-vue/es/checkbox/style/css'
import 'ant-design-vue/es/input/style/css'
import 'ant-design-vue/es/upload/style/css'
import 'ant-design-vue/es/radio/style/css'
import 'ant-design-vue/es/row/style/css'
export default defineComponent({
components: {
Button,
Input,
Radio,
RadioGroup,
Upload,
Checkbox,
CheckboxGroup,
Row,
Col
},
props: {
baseForm: {
type: Array,
default: () => {
return []
}
}
},
setup(props, { attrs, slots, emit, expose }) {
console.log(props)
const uploadRefs = ref([])
const { baseForm } = toRefs(props)
// const baseForm = ref(obj.data.fieldList)
//假數(shù)據(jù)處理
const change = () => {
baseForm.value.forEach((item, index) => {
console.log(item)
if (item.type == '1' || item.type == '3') {
baseForm.value[index].value = ''
} else {
baseForm.value[index].value = []
}
if (item.type == '4') {
item.keyAndvalueList[3].showValue = item.keyAndvalueList[3].showValue.split(',')
}
if (item.type == '3') {
item.index = -1
item.keyAndvalueList[3].showValue = item.keyAndvalueList[3].showValue.split(',')
console.log(item.keyAndvalueList[3].showValue, item)
item.keyAndvalueList[3].showValue.forEach((v, i) => {
item.keyAndvalueList[3].showValue.splice(i, 1, {
lable: i,
value: v
})
})
}
if(item.type == '2'){
// item.fileList = [{name: "question.png"},{name: "question.png"},{name: "question.png"}]
item.fileList = []
}
})
console.log(baseForm)
}
const uploading = ref(false)
let form = ref({})
watch(() => baseForm, async (newVal, oldVal) => {
console.log(newVal, oldVal)
}, { deep: true, immediate: true })
const submitBtn = () => {
console.log(baseForm, baseForm.value)
// 這里要處理校驗(yàn)
for (let i = 0; i < baseForm.value.length; i++) {
// 輸入框做校驗(yàn)
if (baseForm.value[i].type == "1" && baseForm.value[i].keyAndvalueList[3].showValue == '1') {
if (baseForm.value[i].keyAndvalueList[4].showValue == '1' && !baseForm.value[i].value) {
baseForm.value[i].value = ''
message.destroy()
message.error(`請(qǐng)正確輸入第${i + 1}個(gè)問題:${baseForm.value[i].keyAndvalueList[0].showValue}`)
return
}
if (baseForm.value[i].keyAndvalueList[4].showValue == '3' && !ngx.mobile().test(Number(baseForm.value[i].value))) {
baseForm.value[i].value = ''
message.destroy()
return message.error(`第${i + 1}個(gè)問題:請(qǐng)正確輸入手機(jī)號(hào)`)
}
if (baseForm.value[i].keyAndvalueList[4].showValue == '4' && !ngx.email().test(baseForm.value[i].value)) {
baseForm.value[i].value = ''
message.destroy()
message.error(`第${i + 1}個(gè)問題:請(qǐng)正確輸入郵箱`)
return
}
}
//處理上傳文檔TODO
if (baseForm.value[i].type == "2") {
if (baseForm.value[i].keyAndvalueList[3].showValue == '1' && (baseForm.value[i].value == "" || baseForm.value[i].value == [])) {
message.destroy()
message.error(`第${i + 1}個(gè)問題,請(qǐng)上傳${baseForm.value[i].keyAndvalueList[0].showValue}的圖片`)
return
}
}
//單選
if (baseForm.value[i].type == "3") {
console.log(baseForm.value[i].keyAndvalueList[2].showValue == '1', !baseForm.value[i].index < 0, baseForm.value[i].index)
if (baseForm.value[i].keyAndvalueList[2].showValue == '1' && baseForm.value[i].index < 0) {
console.log(333)
message.destroy()
message.error(`第${i + 1}個(gè)問題,請(qǐng)選擇${baseForm.value[i].keyAndvalueList[0].showValue}`)
return
}
// 處理選項(xiàng)
if(baseForm.value[i].index>=0){
baseForm.value[i].value = baseForm.value[i].keyAndvalueList[3].showValue[baseForm.value[i].index].value
}
}
//多選
if (baseForm.value[i].type == "4") {
console.log(baseForm.value[i].keyAndvalueList[2].showValue == '1', baseForm.value[i].value.length < 1, baseForm.value[i].value)
if (baseForm.value[i].keyAndvalueList[2].showValue == '1' && baseForm.value[i].value < 1) {
message.destroy()
message.error(`第${i + 1}個(gè)問題,請(qǐng)選擇${baseForm.value[i].keyAndvalueList[0].showValue}`)
return
}
}
}
console.log('submit', baseForm)
emit('submit', baseForm)
}
/**
* 上傳相關(guān)
*/
// 刪除文件按鈕
const onRemovefile = (item,i)=>{
item.value.splice(i,1)
item.fileList.splice(i,1)
let inp = document.getElementById(`upload${index}`)
inp.value = null // 一定要?jiǎng)h除掉上傳儲(chǔ)存得value元素,不然回上傳不了,這邊都展示到list數(shù)組里了,所以這里全部為空就行
}
const fileBeforeUploadchange= async (e,index) => {
console.log(e,e.target.files[0])
let file = e.target.files[0]
const types = ['image/jpg', 'image/jpeg', 'image/png']
if (!types.includes(file.type)) {
message.destroy()
message.error('圖片格式不符合要求,請(qǐng)重新上傳')
return
}
console.log(baseForm.value[index])
if (baseForm.value[index].fileList.length >= Number(baseForm.value[index].keyAndvalueList[5].showValue)) {
message.destroy()
message.error(`只能上傳${baseForm.value[index].keyAndvalueList[5].showValue}個(gè)文件`)
return
}
if (file.size / 1024 / 1024 > Number(baseForm.value[index].keyAndvalueList[4].showValue)) {
message.destroy()
message.error(`圖片上傳超過${baseForm.value[index].keyAndvalueList[4].showValue}M,請(qǐng)重新上傳`)
return
}
let formData = new FormData();
formData.append('image', file);
try {
const res = await API.imagefile(formData);
if (res?.code === 0 && res?.data) {
baseForm.value[index].value.push(res?.data)
console.log(baseForm.value[index].value)
baseForm.value[index].fileList.push(file)
message.success('上傳成功')
} else {
message.config({
content: res?.msg || '上傳失敗,請(qǐng)重試',
top: 200,
duration: 3
})
}
return uploading.value = false
} catch (error) {
console.log(error, '上傳失敗')
uploading.value = false
}
return false
}
onMounted(() => {
nextTick(() => {
change()
if (isPc) {
form.value.style.width = '90%'
} else {
form.value.style.width = '40%'
}
})
})
return {
baseForm,
uploading,
form,
submitBtn,
fileBeforeUploadchange,
onRemovefile,
uploadRefs
}
},
});
</script>
<style lang="less" scoped>
.form {
width: 70%;
font-size: 16px;
margin: 0 auto;
padding: 0px 20px;
height: 100%;
&-item {
margin: 0 auto;
padding-top: 10px;
border-radius: 8px;
.title {
font-weight: 550;
margin: 20px 0 10px;
img {
width: 14px;
}
}
.hint {
div{
color: #999;
}
img {
margin: 10px 0;
width: 100px;
}
}
}
.main{
span{
padding: 8px 10px;
background-color: #456fff;
color: #fff;
line-height: 10px;
position: relative;
}
input{
width: 80px;
height: 30px;
position: absolute;
top: 10px;
left: 0px;
border: 1px solid red;
opacity: 0;
}
ul{
margin-top: 15px;
li{
list-style-type:none;
transform: translateX(-40px);
font-size: 14px;
display: flex;
justify-content: space-between;
span{
background-color: #fff;
color: #a09e9e;
}
img{
width: 14px;
height: 14px;
margin-top: 5px;
}
}
}
}
.submitBtn {
width: 200px;
padding: 10px 20px;
background-color: #456fff;
border-radius: 6px;
text-align: center;
color: #fff;
margin: 20px auto;
cursor: pointer;
}
}
</style>
后臺(tái)返回的mock數(shù)據(jù)以及正則
export const obj = {
"code": 0,
"msg": "成功",
"data": {
"id": 7,
"type": 1,
"filteFlag": 1,
"title": "rocks問卷標(biāo)題更新",
"questionnaireDesc": "普通問卷,不根據(jù)過濾用戶,狀態(tài)未發(fā)布",
"state": 1,
"fieldList": [
{
"sort": 1,
"type": 1,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "數(shù)字"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:xx歲"
},
{
"questionnaireFieldKeyId": 3,
"showKey": "添加圖片說明"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "1"
},
{ //輸入框1是不限制,2是數(shù)字類型,3是手機(jī),4是郵箱,5是長度
"questionnaireFieldKeyId": 5,
"showKey": "輸入限制",
"showValue": "2"
}
]
},
{
"sort": 1,
"type": 1,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "手機(jī)號(hào)"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:xx歲"
},
{
"questionnaireFieldKeyId": 3,
"showKey": "添加圖片說明"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "0"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "輸入限制",
"showValue": "3"
}
]
},
{
"sort": 1,
"type": 1,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "郵箱4"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:xx歲"
},
{
"questionnaireFieldKeyId": 3,
"showKey": "添加圖片說明"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "0"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "輸入限制",
"showValue": "4"
}
]
},
{
"sort": 2,
"type": 2,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "上傳"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:李xx"
},
{
"questionnaireFieldKeyId": 3,
"showKey": "添加圖片說明",
"showValue":"http://fsvivofsimagestatic-test.vivo.com.cn/NmIfgynmX27oVimD/defaultimage/20220829152440/60649caa6274962b20077ece50c14a56b.png"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "1"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "文件大小",
"showValue": "50"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "文件個(gè)數(shù)",
"showValue": "2"
}
]
},
{
"sort": 2,
"type": 2,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "上傳"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:李xx"
},
{
"questionnaireFieldKeyId": 3,
"showKey": "添加圖片說明",
"showValue":"http://fsvivofsimagestatic-test.vivo.com.cn/NmIfgynmX27oVimD/defaultimage/20220829152440/60649caa6274962b20077ece50c14a56b.png"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "1"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "文件大小",
"showValue": "50"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "文件個(gè)數(shù)",
"showValue": "2"
}
]
},
{
"sort": 2,
"type": 3,
// index:-1,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "您的姓名"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:李xx"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "0"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "選項(xiàng)",
"showValue": "抖音,快手,西瓜視頻,小紅書,B站,微博,微視,知乎,微信視頻號(hào),愛奇藝,QQ小世界,好看視頻,ACfun,騰訊視頻,其他"
}
]
},
{
"sort": 2,
"type": 4,
"keyAndvalueList": [
{
"questionnaireFieldKeyId": 1,
"showKey": "標(biāo)題",
"showValue": "多選"
},
{
"questionnaireFieldKeyId": 2,
"showKey": "提示",
"showValue": "例如:李xx"
},
{
"questionnaireFieldKeyId": 4,
"showKey": "是否必填",
"showValue": "0"
},
{
"questionnaireFieldKeyId": 5,
"showKey": "選項(xiàng)",
"showValue": "抖音,快手,西瓜視頻,小紅書,B站,微博,微視,知乎,微信視頻號(hào),愛奇藝,QQ小世界,好看視頻,ACfun,騰訊視頻,其他"
}
]
},
]
}
}
export const ngx = {
// 郵箱
email: () => /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
// 手機(jī)號(hào)
mobile:() => /^[1]\d{10}$/,
number:() => /^[0-9]*/,
}
export const isPc = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(window.navigator.userAgent)
原文鏈接:https://blog.csdn.net/m0_64207574/article/details/131113506
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2023-04-08 python如何實(shí)現(xiàn)數(shù)組反轉(zhuǎn)_python
- 2022-10-16 Ant?Design?組件庫之步驟條實(shí)現(xiàn)_React
- 2022-11-30 Cenots7?離線安裝部署PostgreSQL?的詳細(xì)過程_PostgreSQL
- 2021-12-06 Windows下在CMD下執(zhí)行Go出現(xiàn)中文亂碼的解決方法_Golang
- 2022-09-10 Python遞歸實(shí)現(xiàn)猴子吃桃問題及解析_python
- 2022-06-04 Qt實(shí)現(xiàn)自定義驗(yàn)證碼輸入框控件的方法_C 語言
- 2022-06-08 Android即時(shí)通訊設(shè)計(jì)(騰訊IM接入和WebSocket接入)_Android
- 2022-04-15 C語言各種操作符透徹理解下篇_C 語言
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支