Vue項目_項目配置腳本代碼詳細講解

Vue項目代碼詳細講解

1. jsconfig.json - JavaScript配置文件

{"compilerOptions": {  // 編譯器選項配置"target": "es5",  // 編譯目標:將代碼編譯為ES5版本,確保更好的瀏覽器兼容性"module": "esnext",  // 模塊系統:使用最新的ES模塊系統"baseUrl": "./",  // 基礎路徑:設置為項目根目錄"moduleResolution": "node",  // 模塊解析策略:使用Node.js的模塊解析方式"paths": {  // 路徑映射配置"@/*": [  // 定義@符號作為src目錄的別名"src/*"  // @/xxx 會被解析為 src/xxx]},"lib": [  // 包含的類型定義庫"esnext",  // 包含最新的ES特性"dom",  // 包含DOM相關的類型定義"dom.iterable",  // 包含DOM可迭代對象的類型定義"scripthost"  // 包含Windows Script Host的類型定義]}
}

作用說明:

  • 這個文件為VSCode等IDE提供JavaScript項目的智能提示
  • 配置路徑別名讓導入更簡潔(使用@代替src)
  • 確保IDE能正確理解項目的模塊系統和語法特性

2. vue.config.js - Vue CLI配置文件

// vue.config.js
const { defineConfig } = require("@vue/cli-service");  // 導入Vue CLI的配置函數module.exports = defineConfig({  // 導出配置對象transpileDependencies: true,  // 轉譯所有依賴包(包括node_modules中的)// 開發服務器配置devServer: {port: 8081,  // 前端開發服務器端口host: '0.0.0.0',  // 允許任何主機訪問(不僅限localhost)open: false,  // 啟動時不自動打開瀏覽器allowedHosts: 'all',  // 允許所有主機名訪問(解決主機名驗證問題)proxy: {  // 代理配置,解決開發環境的跨域問題"/api": {  // 匹配所有以/api開頭的請求target: "http://localhost:8080",  // 代理目標:后端服務器地址changeOrigin: true,  // 改變請求頭中的origin(必要的跨域配置)pathRewrite: {  // 路徑重寫規則"^/api": "/api",  // 保持/api前綴不變},},},},// 生產環境配置productionSourceMap: false,  // 生產環境不生成source map(減小打包體積,提高安全性)// 開發環境生成 source map(用于調試)configureWebpack: {devtool: process.env.NODE_ENV === 'development' ? 'source-map' : false// 開發環境使用source-map便于調試,生產環境關閉},// CSS相關配置css: {loaderOptions: {  // CSS加載器選項scss: {  // SCSS配置// 全局引入scss變量文件(當前被注釋)// additionalData: `@import "@/styles/variables.scss";`// 如果啟用,會在每個組件的樣式中自動引入這個文件},},},
});

關鍵配置說明:

  • devServer.proxy:解決前后端分離開發時的跨域問題
  • host: ‘0.0.0.0’:允許局域網內其他設備訪問
  • productionSourceMap:生產環境關閉源碼映射,保護源代碼

3. .eslintrc.js - ESLint配置文件

module.exports = {root: true,  // 標識這是項目根目錄的ESLint配置,停止向上查找env: {  // 指定代碼運行環境node: true  // Node.js環境(支持require、module等)},extends: [  // 繼承的規則集'plugin:vue/vue3-essential',  // Vue3基本規則'eslint:recommended'  // ESLint推薦規則],parserOptions: {  // 解析器選項parser: '@babel/eslint-parser'  // 使用Babel解析器(支持最新JS語法)},rules: {  // 自定義規則'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',// console語句:生產環境警告,開發環境允許'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',// debugger語句:生產環境警告,開發環境允許'vue/multi-word-component-names': 'off'// 關閉Vue組件名必須多個單詞的規則(允許單詞組件名如Profile)}
}

規則說明:

  • 開發環境允許console和debugger便于調試
  • 生產環境對這些語句發出警告,提醒清理
  • 關閉組件命名限制,提高開發靈活性

4. babel.config.js - Babel配置文件

module.exports = {presets: ["@vue/cli-plugin-babel/preset"],  // 使用Vue CLI提供的Babel預設// 包含了Vue項目所需的所有Babel插件和配置
};

作用:

  • 將現代JavaScript轉譯為兼容性更好的版本
  • 支持Vue的JSX語法和其他特性

5. Profile.vue - 個人資料頁面組件

模板部分解析

<template><div class="profile">  <!-- 頁面根容器 --><el-card>  <!-- Element Plus卡片組件 --><template #header>  <!-- 卡片頭部插槽 --><div class="card-header"><span>個人信息</span><el-button type="primary" size="small" @click="isEdit = !isEdit"><!-- 切換編輯狀態的按鈕,根據狀態顯示不同文字 -->{{ isEdit ? "取消編輯" : "編輯信息" }}</el-button></div></template><el-formref="profileFormRef"  <!-- 表單引用,用于調用表單方法 -->:model="profileForm"  <!-- 綁定表單數據對象 -->:rules="rules"  <!-- 表單驗證規則 -->:disabled="!isEdit"  <!-- 非編輯狀態時禁用所有輸入 -->label-width="100px"  <!-- 標簽寬度 -->style="max-width: 600px"  <!-- 限制表單最大寬度 -->><!-- 用戶ID(始終禁用) --><el-form-item label="用戶ID"><el-input v-model="profileForm.id" disabled /></el-form-item><!-- 用戶名(始終禁用) --><el-form-item label="用戶名"><el-input v-model="profileForm.username" disabled /></el-form-item><!-- 郵箱(可編輯,帶驗證) --><el-form-item label="郵箱" prop="email"><el-input v-model="profileForm.email" /></el-form-item><!-- 手機號(可編輯,帶驗證) --><el-form-item label="手機號" prop="phone"><el-input v-model="profileForm.phone" /></el-form-item><!-- 分數顯示(使用標簽展示,顏色根據分數變化) --><el-form-item label="分數"><el-tag :type="getScoreType(profileForm.score)" size="large">{{ profileForm.score }} 分</el-tag></el-form-item><!-- 賬號狀態顯示 --><el-form-item label="賬號狀態"><el-tag :type="profileForm.status === 1 ? 'success' : 'danger'">{{ profileForm.status === 1 ? "正常" : "已禁用" }}</el-tag></el-form-item><!-- 時間戳顯示 --><el-form-item label="注冊時間"><el-input :value="formatDate(profileForm.createTime)" disabled /></el-form-item><el-form-item label="更新時間"><el-input :value="formatDate(profileForm.updateTime)" disabled /></el-form-item><!-- 編輯模式下的操作按鈕 --><el-form-item v-if="isEdit"><el-button type="primary" @click="saveProfile">保存修改</el-button><el-button @click="cancelEdit">取消</el-button></el-form-item></el-form></el-card><!-- 修改密碼卡片 --><el-card style="margin-top: 20px"><template #header><span>修改密碼</span></template><el-formref="passwordFormRef":model="passwordForm":rules="passwordRules"label-width="100px"style="max-width: 600px"><!-- 原密碼輸入 --><el-form-item label="原密碼" prop="oldPassword"><el-inputv-model="passwordForm.oldPassword"type="password"  <!-- 密碼類型輸入框 -->show-password  <!-- 顯示密碼切換按鈕 -->/></el-form-item><!-- 新密碼輸入 --><el-form-item label="新密碼" prop="newPassword"><el-inputv-model="passwordForm.newPassword"type="password"show-password/></el-form-item><!-- 確認密碼輸入 --><el-form-item label="確認密碼" prop="confirmPassword"><el-inputv-model="passwordForm.confirmPassword"type="password"show-password/></el-form-item><!-- 密碼表單操作按鈕 --><el-form-item><el-button type="primary" @click="handleChangePassword">修改密碼</el-button><el-button @click="resetPasswordForm">重置</el-button></el-form-item></el-form></el-card></div>
</template>

Script部分解析

<script setup>
// 使用Vue 3的Composition API + setup語法糖
import { ref, reactive, onMounted } from "vue";  // Vue核心響應式API
import { useStore } from "vuex";  // Vuex狀態管理
import { useRouter } from "vue-router";  // 路由
import { ElMessage } from "element-plus";  // 消息提示組件
import { getUser, updateUser, changePassword } from "@/api/user";  // API接口const store = useStore();  // 獲取Vuex store實例
const router = useRouter();  // 獲取路由實例
const currentUser = store.getters.user;  // 從store獲取當前用戶信息// 響應式數據定義
const isEdit = ref(false);  // 編輯狀態標志
const profileFormRef = ref();  // 個人信息表單引用
const passwordFormRef = ref();  // 密碼表單引用// 個人信息表單數據(響應式對象)
const profileForm = reactive({id: "",username: "",email: "",phone: "",score: 0,status: 1,createTime: "",updateTime: "",
});// 修改密碼表單數據
const passwordForm = reactive({oldPassword: "",newPassword: "",confirmPassword: "",
});// 表單驗證規則
const rules = {email: [{ required: true, message: "請輸入郵箱", trigger: "blur" },  // 必填{ type: "email", message: "請輸入正確的郵箱地址", trigger: "blur" },  // 郵箱格式],phone: [{pattern: /^1[3-9]\d{9}$/,  // 手機號正則:1開頭,第二位3-9,后面9位數字message: "請輸入正確的手機號",trigger: "blur",  // 失去焦點時觸發驗證},],
};// 密碼表單驗證規則
const passwordRules = {oldPassword: [{ required: true, message: "請輸入原密碼", trigger: "blur" }],newPassword: [{ required: true, message: "請輸入新密碼", trigger: "blur" },{ min: 6, max: 20, message: "密碼長度在 6 到 20 個字符", trigger: "blur" },],confirmPassword: [{ required: true, message: "請再次輸入新密碼", trigger: "blur" },{validator: (rule, value, callback) => {  // 自定義驗證器if (value !== passwordForm.newPassword) {callback(new Error("兩次輸入密碼不一致"));} else {callback();  // 驗證通過}},trigger: "blur",},],
};// 獲取分數標簽類型(根據分數返回不同顏色)
const getScoreType = (score) => {if (score >= 90) return "success";  // 綠色if (score >= 60) return "warning";  // 橙色return "danger";  // 紅色
};// 格式化日期時間
const formatDate = (dateStr) => {if (!dateStr) return "";return new Date(dateStr).toLocaleString("zh-CN");  // 轉換為中文格式
};// 加載用戶信息
const loadUserInfo = async () => {try {const res = await getUser(currentUser.id);  // 調用API獲取用戶信息Object.assign(profileForm, res.data);  // 將返回數據合并到表單對象} catch (error) {ElMessage.error("獲取用戶信息失敗");}
};// 保存個人信息
const saveProfile = async () => {const valid = await profileFormRef.value.validate();  // 表單驗證if (!valid) return;  // 驗證失敗則返回try {await updateUser(profileForm.id, {email: profileForm.email,phone: profileForm.phone,});// 更新store中的用戶信息store.commit("SET_USER", { ...currentUser, ...profileForm });ElMessage.success("保存成功");isEdit.value = false;  // 退出編輯模式} catch (error) {ElMessage.error("保存失敗");}
};// 取消編輯
const cancelEdit = () => {isEdit.value = false;  // 退出編輯模式loadUserInfo();  // 重新加載原始數據
};// 修改密碼
const handleChangePassword = async () => {const valid = await passwordFormRef.value.validate();if (!valid) return;try {// 調用修改密碼APIawait changePassword(currentUser.id, {oldPassword: passwordForm.oldPassword,newPassword: passwordForm.newPassword,});ElMessage.success("密碼修改成功,請重新登錄");// 清空密碼表單resetPasswordForm();// 1.5秒后退出登錄并跳轉到登錄頁setTimeout(async () => {await store.dispatch("logout");  // 調用store的logout actionrouter.push("/login");  // 跳轉到登錄頁}, 1500);} catch (error) {ElMessage.error(error.message || "密碼修改失敗");}
};// 重置密碼表單
const resetPasswordForm = () => {passwordFormRef.value?.resetFields();  // 使用可選鏈調用表單重置方法
};// 組件掛載時加載用戶信息
onMounted(() => {loadUserInfo();
});
</script>

樣式部分

<style scoped lang="scss">
.profile {  // 頁面容器樣式.card-header {  // 卡片頭部樣式display: flex;  // 彈性布局justify-content: space-between;  // 兩端對齊align-items: center;  // 垂直居中}
}
</style>

6. UserManagement.vue - 用戶管理頁面組件

模板部分詳解

<template><div class="user-management"><!-- 搜索和操作欄 --><el-card class="search-card"><el-row :gutter="20">  <!-- 柵格布局,列間距20px --><el-col :span="6">  <!-- 占6格(共24格) --><el-inputv-model="searchForm.username"  <!-- 雙向綁定搜索關鍵詞 -->placeholder="請輸入用戶名"clearable  <!-- 顯示清空按鈕 -->@clear="handleSearch"  <!-- 清空時觸發搜索 -->@keyup.enter="handleSearch"  <!-- 回車鍵觸發搜索 -->><template #prefix>  <!-- 前綴圖標插槽 --><el-icon><Search /></el-icon></template></el-input></el-col><el-col :span="6"><el-button type="primary" @click="handleSearch">搜索</el-button><el-button @click="resetSearch">重置</el-button></el-col><el-col :span="12" style="text-align: right">  <!-- 右對齊 --><el-button type="primary" @click="showAddDialog"><el-icon><Plus /></el-icon>新增用戶</el-button><el-button type="success" @click="handleExport"><el-icon><Download /></el-icon>導出CSV</el-button><!-- 文件上傳組件 --><el-upload:show-file-list="false"  <!-- 不顯示已上傳文件列表 -->:before-upload="handleImport"  <!-- 上傳前的鉤子函數 -->accept=".csv"  <!-- 只接受CSV文件 -->style="display: inline-block; margin-left: 10px"><el-button type="warning"><el-icon><Upload /></el-icon>導入CSV</el-button></el-upload></el-col></el-row></el-card><!-- 數據表格 --><el-card class="table-card"><el-table:data="tableData"  <!-- 綁定表格數據 -->v-loading="loading"  <!-- 加載狀態 -->stripe  <!-- 斑馬紋樣式 -->style="width: 100%"><!-- 表格列定義 --><el-table-column prop="id" label="ID" width="80" /><el-table-column prop="username" label="用戶名" /><el-table-column prop="email" label="郵箱" /><el-table-column prop="phone" label="手機號" /><!-- 分數列(自定義內容) --><el-table-column prop="score" label="分數" width="80"><template #default="{ row }">  <!-- 作用域插槽,row是當前行數據 --><el-tag :type="getScoreType(row.score)">{{ row.score }}</el-tag></template></el-table-column><!-- 狀態列(開關組件) --><el-table-column prop="status" label="狀態" width="100"><template #default="{ row }"><el-switchv-model="row.status"  <!-- 直接綁定行數據 -->:active-value="1"  <!-- 開啟時的值 -->:inactive-value="0"  <!-- 關閉時的值 -->@change="handleStatusChange(row)"  <!-- 狀態改變時觸發 -->/></template></el-table-column><!-- 創建時間列 --><el-table-column prop="createTime" label="創建時間" width="180"><template #default="{ row }">{{ formatDate(row.createTime) }}</template></el-table-column><!-- 操作列 --><el-table-column label="操作" width="200" fixed="right">  <!-- fixed="right"固定在右側 --><template #default="{ row }"><el-button type="primary" size="small" @click="showEditDialog(row)">編輯</el-button><el-button type="danger" size="small" @click="handleDelete(row)">刪除</el-button></template></el-table-column></el-table><!-- 分頁組件 --><el-paginationv-model:current-page="pagination.pageNum"  <!-- 當前頁 -->v-model:page-size="pagination.pageSize"  <!-- 每頁條數 -->:page-sizes="[10, 20, 50, 100]"  <!-- 可選的每頁條數 -->:total="pagination.total"  <!-- 總條數 -->layout="total, sizes, prev, pager, next, jumper"  <!-- 顯示的組件 -->@size-change="handleSizeChange"  <!-- 每頁條數改變 -->@current-change="handleCurrentChange"  <!-- 頁碼改變 -->style="margin-top: 20px"/></el-card><!-- 新增/編輯對話框 --><el-dialogv-model="dialogVisible"  <!-- 控制顯示隱藏 -->:title="dialogTitle"  <!-- 動態標題 -->width="500px"@close="resetForm"  <!-- 關閉時重置表單 -->><el-formref="userFormRef":model="userForm":rules="rules"label-width="80px"><el-form-item label="用戶名" prop="username"><el-inputv-model="userForm.username"placeholder="請輸入用戶名":disabled="isEdit"  <!-- 編輯時禁用用戶名 -->/></el-form-item><!-- 密碼項只在新增時顯示 --><el-form-item label="密碼" prop="password" v-if="!isEdit"><el-inputv-model="userForm.password"type="password"placeholder="請輸入密碼"show-password/></el-form-item><el-form-item label="郵箱" prop="email"><el-input v-model="userForm.email" placeholder="請輸入郵箱" /></el-form-item><el-form-item label="手機號" prop="phone"><el-input v-model="userForm.phone" placeholder="請輸入手機號" /></el-form-item><el-form-item label="分數" prop="score"><el-input-numberv-model="userForm.score":min="0"  <!-- 最小值 -->:max="100"  <!-- 最大值 -->placeholder="請輸入分數"/></el-form-item><el-form-item label="狀態" prop="status"><el-radio-group v-model="userForm.status"><el-radio :value="1">啟用</el-radio><el-radio :value="0">禁用</el-radio></el-radio-group></el-form-item></el-form><!-- 對話框底部按鈕 --><template #footer><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="submitForm">確定</el-button></template></el-dialog></div>
</template>

Script部分詳解

<script setup>
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {getUserList,createUser,updateUser,deleteUser,exportUsersCsv,importUsersCsv,
} from "@/api/user";  // 導入所有用戶相關API// ===== 響應式數據定義 =====
const loading = ref(false);  // 加載狀態
const tableData = ref([]);  // 表格數據
const dialogVisible = ref(false);  // 對話框顯示狀態
const isEdit = ref(false);  // 是否編輯模式
const userFormRef = ref();  // 表單引用// 搜索表單
const searchForm = reactive({username: "",  // 搜索關鍵詞
});// 分頁配置
const pagination = reactive({pageNum: 1,  // 當前頁pageSize: 10,  // 每頁條數total: 0,  // 總條數
});// 用戶表單數據
const userForm = reactive({id: null,username: "",password: "",email: "",phone: "",score: 0,status: 1,  // 默認啟用
});// 表單驗證規則
const rules = {username: [{ required: true, message: "請輸入用戶名", trigger: "blur" },{ min: 3, max: 20, message: "長度在 3 到 20 個字符", trigger: "blur" },],password: [{ required: true, message: "請輸入密碼", trigger: "blur" },{ min: 6, max: 20, message: "長度在 6 到 20 個字符", trigger: "blur" },],email: [{ required: true, message: "請輸入郵箱", trigger: "blur" },{ type: "email", message: "請輸入正確的郵箱地址", trigger: "blur" },],phone: [{pattern: /^1[3-9]\d{9}$/,message: "請輸入正確的手機號",trigger: "blur",},],
};// 動態計算的對話框標題
const dialogTitle = ref("新增用戶");// ===== 工具函數 =====// 獲取分數對應的標簽類型
const getScoreType = (score) => {if (score >= 90) return "success";if (score >= 60) return "warning";return "danger";
};// 格式化日期
const formatDate = (dateStr) => {if (!dateStr) return "";const date = new Date(dateStr);return date.toLocaleString("zh-CN");
};// ===== 業務邏輯函數 =====// 獲取用戶列表
const getList = async () => {loading.value = true;  // 開啟加載狀態try {const params = {pageNum: pagination.pageNum,pageSize: pagination.pageSize,};// 如果有搜索條件,添加到參數中if (searchForm.username) {params.username = searchForm.username;}const res = await getUserList(params);  // 調用APItableData.value = res.data.list;  // 設置表格數據pagination.total = res.data.total;  // 設置總條數} catch (error) {ElMessage.error("獲取用戶列表失敗");} finally {loading.value = false;  // 關閉加載狀態}
};// 搜索處理
const handleSearch = () => {pagination.pageNum = 1;  // 搜索時重置到第一頁getList();
};// 重置搜索
const resetSearch = () => {searchForm.username = "";  // 清空搜索條件handleSearch();  // 重新搜索
};// 分頁大小改變
const handleSizeChange = () => {pagination.pageNum = 1;  // 改變每頁條數時重置到第一頁getList();
};// 頁碼改變
const handleCurrentChange = () => {getList();  // 重新獲取數據
};// 顯示新增對話框
const showAddDialog = () => {isEdit.value = false;  // 設置為新增模式dialogTitle.value = "新增用戶";dialogVisible.value = true;
};// 顯示編輯對話框
const showEditDialog = (row) => {isEdit.value = true;  // 設置為編輯模式dialogTitle.value = "編輯用戶";Object.assign(userForm, row);  // 將行數據復制到表單dialogVisible.value = true;
};// 提交表單
const submitForm = async () => {const valid = await userFormRef.value.validate();  // 表單驗證if (!valid) return;try {if (isEdit.value) {// 編輯模式:調用更新APIawait updateUser(userForm.id, userForm);ElMessage.success("更新成功");} else {// 新增模式:調用創建APIawait createUser(userForm);ElMessage.success("創建成功");}dialogVisible.value = false;  // 關閉對話框getList();  // 刷新列表} catch (error) {ElMessage.error(error.message || "操作失敗");}
};// 重置表單
const resetForm = () => {userFormRef.value?.resetFields();  // 重置表單驗證狀態// 重置表單數據Object.assign(userForm, {id: null,username: "",password: "",email: "",phone: "",score: 0,status: 1,});
};// 狀態切換
const handleStatusChange = async (row) => {try {await updateUser(row.id, { status: row.status });  // 只更新狀態ElMessage.success("狀態更新成功");} catch (error) {// 失敗時恢復原狀態row.status = row.status === 1 ? 0 : 1;ElMessage.error("狀態更新失敗");}
};// 刪除用戶
const handleDelete = async (row) => {try {// 顯示確認對話框await ElMessageBox.confirm(`確定要刪除用戶 ${row.username} 嗎?`,"刪除確認",{confirmButtonText: "確定",cancelButtonText: "取消",type: "warning",});await deleteUser(row.id);  // 調用刪除APIElMessage.success("刪除成功");getList();  // 刷新列表} catch (error) {// 用戶取消操作不顯示錯誤if (error !== "cancel") {ElMessage.error("刪除失敗");}}
};// 導出CSV
const handleExport = async () => {try {const res = await exportUsersCsv();  // 調用導出API// 創建Blob對象(二進制大對象)const url = window.URL.createObjectURL(new Blob([res], { type: "text/csv;charset=utf-8;" }));// 創建臨時下載鏈接const link = document.createElement("a");link.href = url;link.download = `用戶數據_${new Date().getTime()}.csv`;  // 文件名帶時間戳document.body.appendChild(link);link.click();  // 觸發下載// 清理:移除鏈接并釋放URL對象setTimeout(() => {document.body.removeChild(link);window.URL.revokeObjectURL(url);}, 100);ElMessage.success("導出成功");} catch (error) {console.error("導出錯誤:", error);ElMessage.error("導出失敗: " + (error.message || "未知錯誤"));}
};// 導入CSV
const handleImport = async (file) => {// 創建FormData對象用于文件上傳const formData = new FormData();formData.append("file", file);try {const res = await importUsersCsv(formData);  // 調用導入APIconst { successCount, errorCount, errors } = res.data;// 根據導入結果顯示不同提示if (errorCount > 0) {ElMessage.warning(`導入完成:成功 ${successCount} 條,失敗 ${errorCount}`);console.error("導入錯誤:", errors);  // 控制臺輸出錯誤詳情} else {ElMessage.success(`導入成功:共 ${successCount} 條數據`);}getList();  // 刷新列表} catch (error) {ElMessage.error("導入失敗");}return false;  // 阻止el-upload的默認上傳行為
};// ===== 生命周期 =====
onMounted(() => {getList();  // 組件掛載時加載數據
});
</script>

樣式部分

<style scoped lang="scss">
.user-management {.search-card {margin-bottom: 20px;  // 搜索卡片底部間距}.table-card {.el-table {margin-bottom: 20px;  // 表格底部間距}}
}
</style>

總結

這個Vue 3項目展示了一個完整的用戶管理系統,主要特點:

  1. 技術棧

    • Vue 3 + Composition API
    • Element Plus UI框架
    • Vuex狀態管理
    • Vue Router路由
    • Axios HTTP請求
  2. 功能特性

    • 用戶的增刪改查
    • 分頁和搜索
    • CSV導入導出
    • 表單驗證
    • 權限狀態管理
    • 個人信息編輯
    • 密碼修改
  3. 最佳實踐

    • 組件化開發
    • 響應式數據管理
    • 統一的錯誤處理
    • 代碼注釋規范
    • 模塊化的API管理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921685.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921685.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921685.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第一節:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入門

Vben Admin vben5 系列文章目錄 &#x1f4bb; 基礎篇 ? 第一節&#xff1a;Vben Admin 最新 v5.0 (vben5) Python Flask 快速入門 ? 第二節&#xff1a;Vben Admin 最新 v5.0 (vben5) Python Flask 快速入門 - Python Flask 后端開發詳解(附源碼) ? 第三節&#xff1a;V…

Guava中常用的工具類

1. 集合工具類&#xff08;com.google.common.collect&#xff09;Guava 對 Java 集合框架進行了豐富擴展&#xff0c;解決了標準集合的諸多痛點。&#xff08;1&#xff09;Lists / Sets / Maps:用于簡化集合創建和操作&#xff1a;// 創建不可變集合&#xff08;線程安全&…

redission實現讀寫鎖的原理

Redisson 實現分布式讀寫鎖的核心原理是 ?基于 Redis 的 Lua 腳本原子操作? ?Pub/Sub 通知機制&#xff0c;在保證強一致性的同時實現高效的讀并發&#xff08;讀不阻塞讀&#xff0c;寫阻塞讀&#xff09;。以下是其核心設計&#xff1a;?一、核心數據結構?Redisson 使用…

【 ??SQL注入漏洞靶場】第二關文件讀寫

SQLi-Labs?它是一個開源的、專門為學習 ??Web安全?? 和 ??SQL注入技術?? 而設計的靶場項目。開發者故意在代碼中留下了各種不同類型的SQL注入漏洞&#xff0c;讓安全研究人員、學生和愛好者可以在一個合法、安全的環境中進行實戰練習&#xff0c;從而掌握發現和利用SQ…

設計藝術~緩存結構設計

背景 面對高QPS場景的業務&#xff0c;不得不考慮對一些數據做緩存設計&#xff0c;常見的緩存設計有這些&#xff1a;DB Proxy緩存、分布式緩存、Localcache緩存。 在考慮加緩存的背景下不考慮數據的一致性&#xff0c;都是瞎扯&#xff0c;所以我們再定義一下數據的一致性場景…

后端開發技術棧

后端開發技術棧核心技術內容平臺 (Content Platform)電商 (E-Commerce)金融科技 (FinTech) / 支付物聯網 (IoT - Internet of Things)游戲后端 (Game Backend)社交平臺搜索平臺企業級應用開發音視頻處理后端地圖與地理位置服務DevOps大數據開發大模型應用開發智能合約開發核心技…

【ICCV2025】計算機視覺|即插即用|ESC:顛覆Transformer!超強平替,ESC模塊性能炸裂!

論文地址&#xff1a;https://arxiv.org/pdf/2503.06671 代碼地址&#xff1a;https://github.com/dslisleedh/ESC 關注UP CV縫合怪&#xff0c;分享最計算機視覺新即插即用模塊&#xff0c;并提供配套的論文資料與代碼。 https://space.bilibili.com/473764881 摘要 本研究…

【面試場景題】如何進行高并發系統的性能測試?

文章目錄一、明確測試目標與指標二、測試環境搭建三、測試工具選型四、測試場景設計五、執行測試與監控六、瓶頸分析與調優七、測試報告與迭代總結高并發系統的性能測試是驗證系統在極限流量下是否能保持穩定運行的關鍵環節&#xff0c;需要結合場景設計、工具選型、指標監控、…

攻防世界ReverseMe-120

這道題比較經典&#xff0c;涉及三個知識點&#xff0c;所以記錄一下。首先給了一個文件&#xff0c;detect it easy看了下&#xff0c;是32位exe。放入ida中&#xff0c;找下main函數&#xff0c;F5反編譯看一下偽代碼。int __cdecl main(int argc, const char **argv, const …

小白也能看懂,HTTP中的文件上傳與下載到底發生了什么?

HTTP 文件傳輸協議解析&#xff1a;上傳與下載 這份文檔會用最簡單的方式&#xff0c;帶你了解 HTTP 協議是如何處理文件下載和上傳的。我們會專注于協議本身&#xff0c;看看客戶端&#xff08;比如你的瀏覽器&#xff09;和服務端&#xff08;網站服務器&#xff09;之間到底…

快速構建數據集-假數據(生成劃分)

快速構建數據集-假數據1、torch.randn&#xff08;?&#xff09;2、HuggingFace Datasets&#xff08;?&#xff09;&#x1f539;1. 從字典生成&#x1f539;2. 從 pandas.DataFrame 生成&#x1f539;3. 批量生成“業務型”假數據&#xff08;配合 Faker&#xff09;&#…

[修訂版]Xenomai/IPIPE源代碼情景解析

[修訂版]Xenomai/IPIPE源代碼情景解析 第一章&#xff1a;Interrupt Pipeline介紹 1.1 I-pipe與Xenomai1.2 I-pipe核心概念1.3 拉取I-pipe代碼 第二章&#xff1a;I-pipe對ARM64異常的改造 2.1 ARM64中斷機制與異常處理2.2 EL0_IRQ 中斷改造之入口2.3 EL0_IRQ 中斷改造之中斷處…

【Qt開發】按鈕類控件(三)-> QCheckBox

目錄 1 -> 概述 2 -> 核心特性 2.1 -> 狀態管理 2.2 -> 信號機制 2.3 -> 外觀與文本 3 -> 應用場景 4 -> 代碼示例 5 -> 總結 1 -> 概述 QCheckBox 是 Qt 框架中提供的一個基礎控件&#xff0c;用于實現復選框功能。它允許用戶在兩種或三種…

在新發布的AI論文中 pytorch 和tensorflow 的使用比例

根據 2025 年最新的學術動態和行業報告&#xff0c;PyTorch 在 AI 論文中的使用比例已占據絕對主導地位&#xff0c;而 TensorFlow 的占比持續下降。以下是基于多個權威來源的綜合分析&#xff1a; 一、頂級會議中的框架分布 在 NeurIPS、ICML、CVPR 等頂級學術會議中&#xff…

3DXML格式是什么?用什么軟件可以打開?

3DXML 是一種開放標準的數據交換格式&#xff0c;主要用于三維 CAD&#xff08;計算機輔助設計&#xff09;模型的存儲和交換。它是由 Dassault Systmes 開發的一種文件格式&#xff0c;常用于 CATIA V6 和其他支持該格式的應用程序中。3DXML 文件可以包含完整的 3D 模型數據&a…

9月8日星期一今日早報簡報微語報早讀

9月8日星期一&#xff0c;農歷七月十七&#xff0c;早報#微語早讀。1、中國火箭與月亮同框&#xff0c;遙感四十號03組衛星發射成功&#xff1b;2、湖南郴州開發區改革&#xff1a;編制數由815名減至680名&#xff0c;精簡16.6%&#xff1b;3、水利部對廣東、廣西啟動洪水防御Ⅳ…

windows系統搭建MQTT服務器

1、MQTT 協議 MQTT協議&#xff1a;實現MQTT協議需要客戶端和服務器端通訊完成。 三種身份: 發布者(Publish)、代理(Broker)(服務器)、訂閱者(Subscribe)。 消息的發布者和訂閱者都是客戶端&#xff0c;消息代理是服務器&#xff0c;消息發布者可以同時是訂閱者。 MQTT&am…

從 GPT 到 LLaMA:解密 LLM 的核心架構——Decoder-Only 模型

&#x1f525;從 GPT 到 LLaMA&#xff1a;解密 LLM 的核心架構——Decoder-Only 模型 “為什么所有大模型&#xff08;LLM&#xff09;都長一個樣&#xff1f;” 因為它們都有一個共同的“基因”——Decoder-Only 架構。 在前面兩節中&#xff0c;我們學習了&#xff1a; BER…

Codeforces Round 1047 (Div. 3)

由于最近這三天的數學建模&#xff0c;讓我這個精力本來就不多的AI手更加力竭了&#xff0c;沒注意到昨晚的cf&#xff0c;所以今天來補題了。 比賽連接&#xff1a;比賽傳送門 A題&#xff1a; You are doing a research paper on the famous Collatz Conjecture. In your e…

C++經典的數據結構與算法之經典算法思想:貪心算法(Greedy)

貪心算法&#xff08;Greedy Algorithm&#xff09;&#xff1a;通過局部最優達成全局最優的決策策略 貪心算法是一種通過每次選擇局部最優解來期望全局最優解的算法思想。它不考慮未來的影響&#xff0c;僅根據當前信息做出最優選擇&#xff0c;適用于具有貪心選擇性質和最優子…