<think>根据问题描述,用户希望将user(从userStore中获取的用户名)添加到ruleForm中,但要求不使用element(可能指不使用Element UI组件库)。我们之前已经给出了解决方案,现在需要按照用户要求的格式进行回答,并避免提及Element UI。
解决方案核心:在调用API之前,将用户名赋值给ruleForm的相应字段。
修改后的代码:</think># 不使用 Element UI 的表单提交解决方案
我将为您提供一个不使用 Element UI 的完整表单提交解决方案,包含用户信息添加到表单数据的功能。这个方案使用原生 Vue 3 和 Pinia 实现。
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品管理表单</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/pinia@2/dist/pinia.js"></script>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
width: 100%;
max-width: 800px;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 30px;
}
h1 {
color: #2c3e50;
margin-bottom: 10px;
font-size: 2.5rem;
}
.subtitle {
color: #7f8c8d;
font-size: 1.1rem;
}
.card {
background-color: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
padding: 30px;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #2c3e50;
}
input, select, textarea {
width: 100%;
padding: 12px 15px;
border: 2px solid #e1e5eb;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s;
}
input:focus, select:focus, textarea:focus {
border-color: #3498db;
outline: none;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
}
.error-message {
color: #e74c3c;
font-size: 14px;
margin-top: 5px;
height: 20px;
}
.btn-group {
display: flex;
gap: 15px;
margin-top: 30px;
}
button {
flex: 1;
padding: 14px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.btn-submit {
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
color: white;
}
.btn-submit:hover {
background: linear-gradient(135deg, #2980b9 0%, #3498db 100%);
transform: scale(1.02);
}
.btn-reset {
background-color: #f1f2f6;
color: #2c3e50;
}
.btn-reset:hover {
background-color: #dfe4ea;
}
.mode-indicator {
display: inline-block;
padding: 5px 12px;
border-radius: 20px;
font-size: 14px;
font-weight: bold;
margin-left: 10px;
}
.edit-mode {
background-color: #f39c12;
color: white;
}
.add-mode {
background-color: #2ecc71;
color: white;
}
.user-info {
position: absolute;
top: 20px;
right: 20px;
background: rgba(255, 255, 255, 0.9);
padding: 10px 15px;
border-radius: 30px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
font-weight: 600;
color: #3498db;
}
.response-panel {
margin-top: 25px;
padding: 20px;
border-radius: 10px;
background-color: #f8f9fa;
border-left: 4px solid #3498db;
}
.response-title {
font-weight: 600;
margin-bottom: 10px;
color: #2c3e50;
}
.response-content {
font-family: monospace;
white-space: pre-wrap;
word-break: break-all;
background-color: white;
padding: 15px;
border-radius: 8px;
max-height: 200px;
overflow-y: auto;
}
.success {
border-left-color: #2ecc71;
}
.error {
border-left-color: #e74c3c;
}
@media (max-width: 768px) {
.card {
padding: 20px;
}
.btn-group {
flex-direction: column;
}
h1 {
font-size: 2rem;
}
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<header>
<h1>产品管理表单 <span class="mode-indicator" :class="pageMode === 'edit' ? 'edit-mode' : 'add-mode'">
{{ pageMode === 'edit' ? '编辑模式' : '新增模式' }}
</span></h1>
<p class="subtitle">请填写产品信息并提交</p>
</header>
<div class="user-info">
当前用户: {{ userStore.employeeName }}
</div>
<div class="card">
<form @submit.prevent="submitForm">
<div class="form-group">
<label for="productName">产品名称 *</label>
<input type="text" id="productName" v-model="ruleForm.productName" placeholder="输入产品名称">
<div class="error-message">{{ errors.productName }}</div>
</div>
<div class="form-group">
<label for="productCategory">产品分类 *</label>
<select id="productCategory" v-model="ruleForm.productCategory">
<option value="">请选择分类</option>
<option value="electronics">电子产品</option>
<option value="clothing">服装</option>
<option value="books">图书</option>
<option value="home">家居用品</option>
<option value="food">食品</option>
</select>
<div class="error-message">{{ errors.productCategory }}</div>
</div>
<div class="form-group">
<label for="price">价格 *</label>
<input type="number" id="price" v-model.number="ruleForm.price" placeholder="输入产品价格" min="0" step="0.01">
<div class="error-message">{{ errors.price }}</div>
</div>
<div class="form-group">
<label for="stock">库存数量 *</label>
<input type="number" id="stock" v-model.number="ruleForm.stock" placeholder="输入库存数量" min="0">
<div class="error-message">{{ errors.stock }}</div>
</div>
<div class="form-group">
<label for="description">产品描述</label>
<textarea id="description" v-model="ruleForm.description" rows="4" placeholder="输入产品描述"></textarea>
</div>
<div class="btn-group">
<button type="submit" class="btn-submit">提交表单</button>
<button type="button" class="btn-reset" @click="resetForm">重置表单</button>
</div>
</form>
<div class="response-panel" :class="responseStatus">
<div class="response-title">API 响应:</div>
<div class="response-content">{{ responseData }}</div>
</div>
</div>
</div>
</div>
<script>
const { createApp, reactive, ref } = Vue;
const { defineStore, createPinia } = Pinia;
// 创建 Pinia 实例
const pinia = createPinia();
// 用户状态管理 (Pinia)
const useUserStore = defineStore('user', {
state: () => ({
employeeName: '张明',
role: '管理员',
department: '产品部'
})
});
// 模拟 API 服务
const productApi = {
addItem: async (formData) => {
// 模拟 API 延迟
await new Promise(resolve => setTimeout(resolve, 1000));
return {
status: 201,
data: {
success: true,
message: '产品添加成功',
data: formData,
timestamp: new Date().toISOString()
}
};
},
updateItem: async (formData) => {
// 模拟 API 延迟
await new Promise(resolve => setTimeout(resolve, 1000));
return {
status: 200,
data: {
success: true,
message: '产品更新成功',
data: formData,
timestamp: new Date().toISOString()
}
};
}
};
const app = createApp({
setup() {
// 使用用户状态存储
const userStore = useUserStore();
// 页面模式(新增/编辑)
const pageMode = ref('add'); // 可切换为 'edit'
// 表单数据
const ruleForm = reactive({
productName: '',
productCategory: '',
price: null,
stock: null,
description: '',
operator: '', // 操作人
createdBy: '', // 创建人
lastUpdatedBy: '' // 最后更新人
});
// 表单错误信息
const errors = reactive({
productName: '',
productCategory: '',
price: '',
stock: ''
});
// API 响应数据
const responseData = ref('');
const responseStatus = ref('');
// 表单验证
const validateForm = () => {
let isValid = true;
// 重置错误信息
Object.keys(errors).forEach(key => errors[key] = '');
// 验证产品名称
if (!ruleForm.productName.trim()) {
errors.productName = '产品名称不能为空';
isValid = false;
}
// 验证产品分类
if (!ruleForm.productCategory) {
errors.productCategory = '请选择产品分类';
isValid = false;
}
// 验证价格
if (ruleForm.price === null || ruleForm.price === '') {
errors.price = '价格不能为空';
isValid = false;
} else if (ruleForm.price < 0) {
errors.price = '价格不能为负数';
isValid = false;
}
// 验证库存
if (ruleForm.stock === null || ruleForm.stock === '') {
errors.stock = '库存不能为空';
isValid = false;
} else if (ruleForm.stock < 0) {
errors.stock = '库存不能为负数';
isValid = false;
} else if (!Number.isInteger(ruleForm.stock)) {
errors.stock = '库存必须是整数';
isValid = false;
}
return isValid;
};
// 提交表单
const submitForm = async () => {
if (!validateForm()) return;
try {
// 添加用户信息到表单数据
ruleForm.operator = userStore.employeeName;
if (pageMode.value === 'edit') {
ruleForm.lastUpdatedBy = userStore.employeeName;
} else {
ruleForm.createdBy = userStore.employeeName;
}
let response;
if (pageMode.value === 'edit') {
// 更新操作
responseStatus.value = 'pending';
response = await productApi.updateItem({...ruleForm});
responseStatus.value = 'success';
} else {
// 新增操作
responseStatus.value = 'pending';
response = await productApi.addItem({...ruleForm});
responseStatus.value = 'success';
}
console.log('API 响应:', response.data);
responseData.value = JSON.stringify(response.data, null, 2);
} catch (error) {
console.error('API 请求失败:', error);
responseStatus.value = 'error';
responseData.value = '提交失败,请检查网络或输入内容';
}
};
// 重置表单
const resetForm = () => {
ruleForm.productName = '';
ruleForm.productCategory = '';
ruleForm.price = null;
ruleForm.stock = null;
ruleForm.description = '';
// 重置错误信息
Object.keys(errors).forEach(key => errors[key] = '');
responseData.value = '';
responseStatus.value = '';
};
// 初始化表单数据(模拟编辑模式)
const initEditMode = () => {
if (pageMode.value === 'edit') {
ruleForm.productName = '高性能笔记本电脑';
ruleForm.productCategory = 'electronics';
ruleForm.price = 8999;
ruleForm.stock = 50;
ruleForm.description = '配备最新处理器的高性能笔记本电脑';
}
};
// 初始化
initEditMode();
return {
userStore,
pageMode,
ruleForm,
errors,
responseData,
responseStatus,
submitForm,
resetForm
};
}
});
// 使用 Pinia
app.use(pinia);
app.mount('#app');
</script>
</body>
</html>
```
## 核心功能说明
1. **用户状态管理**:
- 使用 Pinia 创建用户状态存储 (`useUserStore`)
- 存储用户信息(姓名、角色、部门)
2. **表单数据处理**:
- 在 `submitForm` 方法中将用户信息添加到表单数据:
```javascript
ruleForm.operator = userStore.employeeName;
if (pageMode.value === 'edit') {
ruleForm.lastUpdatedBy = userStore.employeeName;
} else {
ruleForm.createdBy = userStore.employeeName;
}
```
3. **表单验证**:
- 实现完整的客户端验证逻辑
- 显示详细的错误信息
4. **API 模拟**:
- 创建模拟的 API 服务 (`productApi`)
- 模拟添加和更新操作
5. **响应展示**:
- 显示 API 调用的响应结果
- 根据成功/失败显示不同样式
6. **模式切换**:
- 支持新增和编辑两种模式
- 根据不同模式显示不同的用户操作信息
## 设计特点
1. **完全原生实现**:不依赖 Element UI 或其他 UI 框架
2. **响应式设计**:适配各种屏幕尺寸
3. **现代UI风格**:使用渐变、阴影和动画效果
4. **直观的用户反馈**:实时显示验证错误和API响应
5. **清晰的用户信息展示**:当前用户始终可见