最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue批量文件上傳并發(fā)的踩坑指南

 更新時(shí)間:2026年04月30日 08:25:13   作者:前端那點(diǎn)事  
本文詳細(xì)探討了Vue批量文件上傳中的并發(fā)問題,并提出了四種解決方案:基礎(chǔ)版(固定并發(fā)數(shù))、進(jìn)階版、高級(jí)版(和極簡(jiǎn)版,每種方案針對(duì)不同場(chǎng)景和需求進(jìn)行了優(yōu)化,旨在平衡上傳效率與服務(wù)器壓力,同時(shí)提高上傳的穩(wěn)定性和成功率,需要的朋友可以參考下

Vue批量文件上傳中,并發(fā)問題是高頻痛點(diǎn)——直接同時(shí)上傳多個(gè)文件,會(huì)導(dǎo)致瀏覽器同域連接數(shù)耗盡、服務(wù)器被瞬時(shí)請(qǐng)求壓垮、上傳進(jìn)度混亂、部分請(qǐng)求被限流或失敗,尤其在文件較大、數(shù)量較多時(shí),問題更突出。核心解決思路是 “控制并發(fā)數(shù)量、優(yōu)化請(qǐng)求調(diào)度、增加容錯(cuò)機(jī)制” ,以下4種方案從簡(jiǎn)單到進(jìn)階,覆蓋不同場(chǎng)景,可直接復(fù)制到項(xiàng)目中使用,適配Vue2/Vue3(組合式API、選項(xiàng)式API均兼容)。

先明確核心并發(fā)痛點(diǎn):瀏覽器對(duì)同域并發(fā)請(qǐng)求數(shù)有默認(rèn)限制(通常為6個(gè)),超過限制會(huì)導(dǎo)致請(qǐng)求排隊(duì)阻塞;服務(wù)器一般會(huì)設(shè)置QPS限流,瞬時(shí)大量請(qǐng)求會(huì)被拒絕;無控制的并發(fā)會(huì)導(dǎo)致進(jìn)度統(tǒng)計(jì)混亂,失敗后難以重試。

方案一:基礎(chǔ)版——固定并發(fā)數(shù)(隊(duì)列調(diào)度,最常用)

核心邏輯:將所有待上傳文件放入隊(duì)列,設(shè)定最大并發(fā)數(shù)(如3-5個(gè)),通過“正在上傳計(jì)數(shù)+隊(duì)列調(diào)度”,確保同時(shí)上傳的文件數(shù)不超過設(shè)定值,上傳完成一個(gè)就從隊(duì)列中取出下一個(gè),循環(huán)執(zhí)行,平衡上傳效率和服務(wù)器壓力。

適配場(chǎng)景:中小批量文件(10-50個(gè))、文件大小適中(<100MB),無需復(fù)雜容錯(cuò),追求簡(jiǎn)單易實(shí)現(xiàn)。

實(shí)操代碼(Vue3組合式API,Element Plus適配)

<template>
  <!-- 批量上傳組件 -->
  <el-upload
    ref="uploadRef"
    multiple
    accept="*"
    :auto-upload="false"
    :on-change="handleFileChange"
    :file-list="fileList"
    class="upload-demo"
  >
    <el-button type="primary">選擇批量文件</el-button>
  </el-upload>
  <el-button type="success" @click="startBatchUpload" style="margin-top: 10px;">
    開始上傳
  </el-button>
  <!-- 上傳進(jìn)度顯示 -->
  <div v-for="file in uploadStatus" :key="file.uid" style="margin-top: 10px;">
    <span>{{ file.name }}</span>
    <el-progress :percentage="file.progress" :status="file.status" style="width: 300px; margin-left: 10px;" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { ElUpload, ElButton, ElProgress, ElMessage } from 'element-plus';
import axios from 'axios';
// 已選擇的文件列表
const fileList = ref([]);
// 上傳狀態(tài)(存儲(chǔ)每個(gè)文件的進(jìn)度、狀態(tài))
const uploadStatus = ref([]);
// 上傳隊(duì)列(待上傳的文件)
let uploadQueue = [];
// 當(dāng)前正在上傳的文件數(shù)
let currentUploads = 0;
// 最大并發(fā)數(shù)(根據(jù)服務(wù)器性能調(diào)整,建議3-5)
const maxConcurrent = 3;
// 上傳接口地址(替換為你的實(shí)際接口)
const uploadApi = '/api/upload/file';
// 選擇文件時(shí),加入隊(duì)列和狀態(tài)管理
const handleFileChange = (uploadFile) => {
  // 去重(避免重復(fù)選擇同一文件)
  const isRepeat = uploadQueue.some(item => item.uid === uploadFile.uid);
  if (isRepeat) return;
  // 加入上傳隊(duì)列
  uploadQueue.push(uploadFile);
  // 初始化上傳狀態(tài)
  uploadStatus.value.push({
    uid: uploadFile.uid,
    name: uploadFile.name,
    progress: 0,
    status: 'ready' // ready: 待上傳, uploading: 上傳中, success: 成功, error: 失敗
  });
};
// 單個(gè)文件上傳函數(shù)
const uploadSingleFile = async (file) => {
  // 更新當(dāng)前文件狀態(tài)為上傳中
  const statusItem = uploadStatus.value.find(item => item.uid === file.uid);
  statusItem.status = 'uploading';
  const formData = new FormData();
  formData.append('file', file.raw); // 原生文件對(duì)象
  try {
    const response = await axios.post(uploadApi, formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      // 監(jiān)聽上傳進(jìn)度,更新進(jìn)度條
      onUploadProgress: (progressEvent) => {
        const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100);
        statusItem.progress = progress;
      }
    });
    // 上傳成功
    statusItem.status = 'success';
    statusItem.progress = 100;
    ElMessage.success(`${file.name} 上傳成功`);
    return response.data;
  } catch (error) {
    // 上傳失敗
    statusItem.status = 'error';
    ElMessage.error(`${file.name} 上傳失敗,請(qǐng)重試`);
    throw error; // 拋出錯(cuò)誤,便于后續(xù)重試
  }
};
// 隊(duì)列調(diào)度函數(shù):控制并發(fā)數(shù),循環(huán)執(zhí)行上傳
const processQueue = async () => {
  // 循環(huán)條件:當(dāng)前上傳數(shù) < 最大并發(fā)數(shù),且隊(duì)列不為空
  while (currentUploads < maxConcurrent && uploadQueue.length > 0) {
    // 從隊(duì)列頭部取出一個(gè)文件
    const file = uploadQueue.shift();
    currentUploads++; // 正在上傳數(shù)+1
    try {
      await uploadSingleFile(file);
    } catch (error) {
      // 失敗后可選擇重新加入隊(duì)列(可選,根據(jù)需求調(diào)整)
      // uploadQueue.unshift(file); // 失敗后放回隊(duì)列頭部,重新上傳
    } finally {
      currentUploads--; // 上傳完成(成功/失敗),正在上傳數(shù)-1
      processQueue(); // 遞歸調(diào)用,繼續(xù)處理下一個(gè)文件
    }
  }
};
// 開始批量上傳
const startBatchUpload = () => {
  if (uploadQueue.length === 0) {
    ElMessage.warning('請(qǐng)先選擇文件');
    return;
  }
  // 啟動(dòng)隊(duì)列調(diào)度
  processQueue();
};
</script>

核心要點(diǎn)

  • 通過currentUploads計(jì)數(shù)控制并發(fā)數(shù),uploadQueue存儲(chǔ)待上傳文件,確保同時(shí)上傳數(shù)量不超標(biāo);
  • 每個(gè)文件上傳完成(無論成功/失?。?,都要釋放并發(fā)槽位(currentUploads--),并遞歸調(diào)用調(diào)度函數(shù);
  • 可根據(jù)服務(wù)器性能調(diào)整maxConcurrent,服務(wù)器性能弱則設(shè)3,性能強(qiáng)可設(shè)5,避免瞬時(shí)壓垮服務(wù)器;
  • Vue2選項(xiàng)式API可直接將代碼遷移到methods中,data中定義響應(yīng)式數(shù)據(jù),邏輯完全一致。

方案二:進(jìn)階版——并發(fā)控制+失敗重試(容錯(cuò)優(yōu)化)

核心邏輯:在方案一的基礎(chǔ)上,增加失敗重試機(jī)制(避免網(wǎng)絡(luò)波動(dòng)導(dǎo)致的偶發(fā)失?。┖?strong>指數(shù)退避策略(重試間隔逐漸延長(zhǎng),減少服務(wù)器壓力),同時(shí)優(yōu)化進(jìn)度統(tǒng)計(jì),確保進(jìn)度不混亂,適配批量上傳的穩(wěn)定性需求。

適配場(chǎng)景:批量文件較多(50-200個(gè))、網(wǎng)絡(luò)環(huán)境不穩(wěn)定、對(duì)上傳成功率要求高的場(chǎng)景。

核心優(yōu)化點(diǎn)(新增代碼)

// 1. 新增重試配置(可自定義)
const retryConfig = {
  maxRetry: 3, // 最大重試次數(shù)
  retryDelay: 1000 // 基礎(chǔ)重試間隔(ms),指數(shù)退避:1s、2s、4s...
};
// 2. 優(yōu)化單個(gè)文件上傳函數(shù),增加重試邏輯
const uploadSingleFile = async (file, retryCount = 0) => {
  const statusItem = uploadStatus.value.find(item => item.uid === file.uid);
  statusItem.status = 'uploading';
  const formData = new FormData();
  formData.append('file', file.raw);
  try {
    const response = await axios.post(uploadApi, formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      onUploadProgress: (progressEvent) => {
        const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100);
        statusItem.progress = progress;
      }
    });
    statusItem.status = 'success';
    statusItem.progress = 100;
    ElMessage.success(`${file.name} 上傳成功`);
    return response.data;
  } catch (error) {
    // 重試邏輯:未達(dá)到最大重試次數(shù),繼續(xù)重試
    if (retryCount < retryConfig.maxRetry) {
      const delay = retryConfig.retryDelay * Math.pow(2, retryCount); // 指數(shù)退避
      statusItem.status = `retry(${retryCount + 1}/${retryConfig.maxRetry})`;
      ElMessage.warning(`${file.name} 上傳失敗,${delay}ms后重試(${retryCount + 1}/${retryConfig.maxRetry})`);
      // 延遲重試
      await new Promise(resolve => setTimeout(resolve, delay));
      return uploadSingleFile(file, retryCount + 1);
    }
    // 達(dá)到最大重試次數(shù),標(biāo)記失敗
    statusItem.status = 'error';
    ElMessage.error(`${file.name} 上傳失敗,已達(dá)到最大重試次數(shù)`);
    throw error;
  }
};
// 3. 可選:全局取消上傳(新增)
const cancelAllUpload = () => {
  uploadQueue = []; // 清空待上傳隊(duì)列
  currentUploads = 0; // 重置正在上傳計(jì)數(shù)
  // 更新所有文件狀態(tài)為取消
  uploadStatus.value.forEach(item => {
    if (item.status === 'uploading' || item.status.includes('retry')) {
      item.status = 'cancelled';
    }
  });
  ElMessage.info('已取消所有上傳任務(wù)');
};

核心要點(diǎn)

  • 采用指數(shù)退避策略,重試間隔隨次數(shù)增加翻倍(1s→2s→4s),避免頻繁重試給服務(wù)器造成額外壓力;
  • 通過retryCount記錄重試次數(shù),達(dá)到最大次數(shù)后停止重試,標(biāo)記為失??;
  • 新增全局取消功能,可應(yīng)對(duì)用戶主動(dòng)取消上傳的場(chǎng)景,提升用戶體驗(yàn);
  • 可結(jié)合接口響應(yīng)頭中的X-RateLimit-Remaining(服務(wù)器限流剩余次數(shù)),動(dòng)態(tài)調(diào)整重試間隔,進(jìn)一步適配服務(wù)器限流。

方案三:高級(jí)版——分片上傳+全局并發(fā)控制(大文件批量上傳)

核心邏輯:當(dāng)批量上傳大文件(單個(gè)>100MB)時(shí),即使控制并發(fā)數(shù),單個(gè)文件上傳也可能超時(shí)、卡頓,此時(shí)結(jié)合分片上傳(將大文件切割為小分片,如1MB/片),同時(shí)控制“所有分片的總并發(fā)數(shù)”,實(shí)現(xiàn)大文件批量上傳的高效、穩(wěn)定,還可支持?jǐn)帱c(diǎn)續(xù)傳(可選)。

適配場(chǎng)景:批量大文件上傳(單個(gè)>100MB)、對(duì)上傳速度和穩(wěn)定性要求高的場(chǎng)景(如視頻、壓縮包批量上傳)。

核心實(shí)現(xiàn)步驟(簡(jiǎn)化實(shí)操代碼)

// 1. 分片配置
const chunkConfig = {
  chunkSize: 1 * 1024 * 1024, // 分片大小(1MB)
  maxConcurrent: 3, // 全局分片最大并發(fā)數(shù)(所有文件的分片總并發(fā))
};
// 2. 并發(fā)限流器(全局控制所有分片的并發(fā))
class ConcurrencyLimiter {
  constructor(maxConcurrent) {
    this.maxConcurrent = maxConcurrent;
    this.activeCount = 0; // 當(dāng)前正在上傳的分片數(shù)
    this.pendingQueue = []; // 待上傳分片隊(duì)列
  }
  // 加入隊(duì)列并執(zhí)行
  enqueue(runTask, fileId) {
    return new Promise((resolve, reject) => {
      this.pendingQueue.push({ runTask, resolve, reject, fileId });
      this.tryStartNext();
    });
  }
  // 嘗試執(zhí)行下一個(gè)分片上傳
  tryStartNext() {
    while (this.activeCount < this.maxConcurrent && this.pendingQueue.length > 0) {
      const { runTask, resolve, reject, fileId } = this.pendingQueue.shift();
      this.activeCount++;
      Promise.resolve()
        .then(() => runTask())
        .then(res => {
          this.activeCount--;
          resolve(res);
          this.tryStartNext();
        })
        .catch(err => {
          this.activeCount--;
          reject(err);
          this.tryStartNext();
        });
    }
  }
}
// 初始化并發(fā)限流器
const limiter = new ConcurrencyLimiter(chunkConfig.maxConcurrent);
// 3. 生成文件唯一標(biāo)識(shí)(用于分片合并、斷點(diǎn)續(xù)傳)
const getFileIdentifier = (file) => {
  // 基于文件名、大小、最后修改時(shí)間生成唯一標(biāo)識(shí),避免重復(fù)上傳
  const originalFile = file._originalFile || file;
  return `${originalFile.name}_${originalFile.size}_${originalFile.lastModified}`;
};
// 4. 分片切割函數(shù)
const splitFileIntoChunks = (file) => {
  const chunks = [];
  const fileSize = file.size;
  let start = 0;
  while (start < fileSize) {
    const end = Math.min(start + chunkConfig.chunkSize, fileSize);
    chunks.push(file.slice(start, end)); // 切割分片
    start = end;
  }
  return chunks;
};
// 5. 單個(gè)分片上傳函數(shù)
const uploadChunk = async (chunk, fileId, chunkIndex, totalChunks) => {
  const formData = new FormData();
  formData.append('chunk', chunk);
  formData.append('fileId', fileId);
  formData.append('chunkIndex', chunkIndex);
  formData.append('totalChunks', totalChunks);
  const response = await axios.post('/api/upload/chunk', formData, {
    headers: { 'Content-Type': 'multipart/form-data' }
  });
  return response.data;
};
// 6. 單個(gè)大文件上傳(分片+并發(fā))
const uploadLargeFile = async (file) => {
  const fileId = getFileIdentifier(file);
  const chunks = splitFileIntoChunks(file.raw);
  const totalChunks = chunks.length;
  const statusItem = uploadStatus.value.find(item => item.uid === file.uid);
  statusItem.status = 'uploading';
  // 所有分片上傳任務(wù),加入并發(fā)限流器
  const chunkTasks = chunks.map((chunk, index) => {
    return limiter.enqueue(() => uploadChunk(chunk, fileId, index, totalChunks), fileId)
      .then(() => {
        // 更新當(dāng)前文件進(jìn)度(已上傳分片數(shù)/總分片數(shù))
        const progress = Math.round(((index + 1) / totalChunks) * 100);
        statusItem.progress = progress;
      });
  });
  // 所有分片上傳完成后,請(qǐng)求服務(wù)器合并分片
  try {
    await Promise.all(chunkTasks);
    await axios.post('/api/upload/merge', { fileId, fileName: file.name });
    statusItem.status = 'success';
    statusItem.progress = 100;
    ElMessage.success(`${file.name} 上傳成功`);
  } catch (error) {
    statusItem.status = 'error';
    ElMessage.error(`${file.name} 上傳失敗,請(qǐng)重試`);
    throw error;
  }
};
// 7. 修改隊(duì)列調(diào)度函數(shù),適配大文件分片上傳
const processQueue = async () => {
  while (uploadQueue.length > 0) {
    const file = uploadQueue.shift();
    // 判斷文件大小,決定是否分片上傳
    if (file.size > chunkConfig.chunkSize) {
      await uploadLargeFile(file);
    } else {
      await uploadSingleFile(file);
    }
  }
};

核心要點(diǎn)

  • 通過ConcurrencyLimiter類實(shí)現(xiàn)全局分片并發(fā)控制,確保所有文件的分片總并發(fā)不超標(biāo),避免服務(wù)器壓力過大;
  • 分片大小建議設(shè)為1-5MB,太小會(huì)增加請(qǐng)求次數(shù),太大易導(dǎo)致超時(shí),可根據(jù)服務(wù)器帶寬調(diào)整;
  • 生成文件唯一標(biāo)識(shí)(getFileIdentifier),用于服務(wù)器合并分片,還可基于該標(biāo)識(shí)實(shí)現(xiàn)斷點(diǎn)續(xù)傳(記錄已上傳分片,中斷后無需重新上傳);
  • 需配合后端接口(分片上傳、分片合并),前端負(fù)責(zé)切割分片、并發(fā)上傳,后端負(fù)責(zé)接收分片、合并文件。

方案四:極簡(jiǎn)版——使用成熟插件(快速落地,無需手寫)

核心邏輯:如果不想手寫并發(fā)控制、分片上傳邏輯,可直接使用Vue生態(tài)成熟的上傳插件,插件已內(nèi)置并發(fā)控制、失敗重試、分片上傳等功能,只需簡(jiǎn)單配置即可落地,節(jié)省開發(fā)時(shí)間。

推薦插件(Vue2/Vue3通用):

1. vue-upload-component(輕量、靈活)

// 1. 安裝
// npm install vue-upload-component --save
// 2. 全局注冊(cè)(main.js)
import Vue from 'vue';
import UploadComponent from 'vue-upload-component';
Vue.component('file-upload', UploadComponent);
// 3. 頁(yè)面使用(自動(dòng)控制并發(fā))
<template>
  <file-upload
    v-model="files"
    url="/api/upload/file"
    :multiple="true"
    :concurrency="3" // 最大并發(fā)數(shù)
    :retry="3" // 最大重試次數(shù)
    @input-file="handleFile"
  >
    <el-button type="primary">批量上傳</el-button>
  </file-upload>
</template>
<script>
export default {
  data() {
    return {
      files: []
    };
  },
  methods: {
    handleFile(file) {
      // 上傳狀態(tài)監(jiān)聽
      console.log(file.progress, file.status);
    }
  }
};
</script>

2. element-plus Upload(Vue3,自帶并發(fā)控制)

Element Plus的Upload組件已內(nèi)置并發(fā)控制,通過limit(最大文件數(shù))和http-request(自定義請(qǐng)求)結(jié)合,可快速實(shí)現(xiàn)批量上傳并發(fā)控制,無需額外手寫隊(duì)列。

四種方案對(duì)比與選型建議

方案核心優(yōu)勢(shì)適配場(chǎng)景開發(fā)成本
方案一(固定并發(fā)+隊(duì)列)簡(jiǎn)單易實(shí)現(xiàn)、無依賴、兼容性好中小批量、中等大小文件
方案二(并發(fā)+失敗重試)穩(wěn)定性高、容錯(cuò)性強(qiáng)批量較多、網(wǎng)絡(luò)不穩(wěn)定
方案三(分片+全局并發(fā))支持大文件、上傳高效穩(wěn)定批量大文件、高要求場(chǎng)景
方案四(插件實(shí)現(xiàn))快速落地、無需手寫復(fù)雜邏輯快速開發(fā)、無需定制化需求極低

核心優(yōu)化補(bǔ)充(必看)

  • 前端優(yōu)化:上傳前對(duì)文件進(jìn)行校驗(yàn)(大小、格式),過濾不符合要求的文件,減少無效請(qǐng)求;利用Web Worker進(jìn)行文件壓縮、分片切割,避免阻塞主線程,確保頁(yè)面流暢不卡頓;
  • 后端配合:服務(wù)器需開啟文件上傳大小限制(如Nginx、Tomcat),配置合適的QPS限流,提供分片合并接口,同時(shí)支持文件去重(基于文件唯一標(biāo)識(shí)),避免重復(fù)上傳;
  • 進(jìn)度優(yōu)化:批量上傳時(shí),可增加“全局進(jìn)度”(所有文件的平均進(jìn)度),提升用戶體驗(yàn);單個(gè)文件進(jìn)度基于上傳字節(jié)數(shù)或分片數(shù)計(jì)算,確保進(jìn)度準(zhǔn)確;
  • 跨域處理:若前后端跨域,需在后端配置CORS,允許multipart/form-data類型請(qǐng)求,避免跨域攔截導(dǎo)致上傳失敗。

總結(jié)

Vue批量文件上傳的并發(fā)問題,核心是“控制并發(fā)數(shù)量、優(yōu)化請(qǐng)求調(diào)度”:簡(jiǎn)單場(chǎng)景用方案一(隊(duì)列調(diào)度)快速落地,穩(wěn)定需求用方案二(增加重試),大文件場(chǎng)景用方案三(分片+全局并發(fā)),快速開發(fā)用方案四(插件)。實(shí)際開發(fā)中,可根據(jù)文件大小、數(shù)量、服務(wù)器性能,選擇合適的方案,也可結(jié)合多種方案(如“并發(fā)控制+分片上傳+失敗重試”),實(shí)現(xiàn)高效、穩(wěn)定的批量文件上傳。

以上就是Vue批量文件上傳并發(fā)的踩坑指南的詳細(xì)內(nèi)容,更多關(guān)于Vue批量文件上傳并發(fā)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue.js實(shí)現(xiàn)格式化時(shí)間并每秒更新顯示功能示例

    vue.js實(shí)現(xiàn)格式化時(shí)間并每秒更新顯示功能示例

    這篇文章主要介紹了vue.js實(shí)現(xiàn)格式化時(shí)間并每秒更新顯示功能,結(jié)合實(shí)例形式分析了vue.js時(shí)間格式化顯示與基于定時(shí)器進(jìn)行實(shí)時(shí)更新的相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • Vue利用ref屬性更改css樣式的操作方法

    Vue利用ref屬性更改css樣式的操作方法

    在Vue.js的應(yīng)用開發(fā)中,我們經(jīng)常會(huì)遇到需要?jiǎng)討B(tài)修改DOM元素樣式的情況,Vue提供了多種方式來實(shí)現(xiàn)這一目標(biāo),其中ref是一個(gè)非常有用且靈活的工具,本文將深入探討如何在Vue項(xiàng)目中利用ref屬性來更改CSS樣式,并通過多個(gè)實(shí)例演示其具體用法,需要的朋友可以參考下
    2024-10-10
  • Vue2.0基于vue-cli+webpack Vuex的用法(實(shí)例講解)

    Vue2.0基于vue-cli+webpack Vuex的用法(實(shí)例講解)

    下面小編就為大家?guī)硪黄猇ue2.0基于vue-cli+webpack Vuex的用法(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • vue如何使用element組件自定義v-loading

    vue如何使用element組件自定義v-loading

    這篇文章主要介紹了vue如何使用element組件自定義v-loading問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • vue3+vite+TS中使用element-plus按需引入ElLoading、ElMessage樣式失效解決

    vue3+vite+TS中使用element-plus按需引入ElLoading、ElMessage樣式失效解決

    在項(xiàng)目中使用elementui確實(shí)是很方便的一件事,下面這篇文章主要給大家介紹了關(guān)于vue3+vite+TS中使用element-plus按需引入ElLoading、ElMessage樣式失效解決的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • vue解決this.$refs.xx在mounted中獲取DOM元素為undefined問題

    vue解決this.$refs.xx在mounted中獲取DOM元素為undefined問題

    這篇文章主要介紹了vue解決this.$refs.xx在mounted中獲取DOM元素為undefined問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • vue3+ts vite打包結(jié)構(gòu)控制通過rollup進(jìn)行配置方式

    vue3+ts vite打包結(jié)構(gòu)控制通過rollup進(jìn)行配置方式

    這篇文章主要介紹了vue3+ts vite打包結(jié)構(gòu)控制通過rollup進(jìn)行配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • 淺談Vue3的幾個(gè)優(yōu)勢(shì)

    淺談Vue3的幾個(gè)優(yōu)勢(shì)

    這篇文章主要給大家分享的是Vue3的幾個(gè)優(yōu)勢(shì),Vue3仍然在源碼、性能和語(yǔ)法 API 三個(gè)大的方面進(jìn)行了優(yōu)化,下面我們一起進(jìn)入文章看看具體詳情吧
    2021-10-10
  • 詳解Vue 單文件組件的三種寫法

    詳解Vue 單文件組件的三種寫法

    這篇文章主要介紹了詳解Vue 單文件組件的三種寫法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 用vue封裝插件并發(fā)布到npm的方法步驟

    用vue封裝插件并發(fā)布到npm的方法步驟

    本篇文章主要介紹了用vue封裝插件并發(fā)布到npm的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10

最新評(píng)論

土默特左旗| 治多县| 隆化县| 农安县| 原阳县| 于都县| 日喀则市| 盘锦市| 绥江县| 视频| 文水县| 读书| 乌恰县| 德昌县| 乐业县| 荆门市| 绩溪县| 法库县| 泾阳县| 永年县| 乐山市| 澎湖县| 措勤县| 松桃| 岑巩县| 潍坊市| 保德县| 昭平县| 奎屯市| 上犹县| 平邑县| 沙湾县| 克什克腾旗| 扎囊县| 双柏县| 瓮安县| 乌什县| 共和县| 乌兰浩特市| 固安县| 靖宇县|