<!--
* @Author: luoxianbo combatzone@163.com
* @Date: 2025-07-12 11:22:05
* @LastEditors: luoxianbo combatzone@163.com
* @LastEditTime: 2025-07-21 22:14:32
* @FilePath: \VUE3-PROJECT\vite-project\src\components\tecHigLin\tecHigLinAdd.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div>
<div class="form-group">
<span>标题</span>
<el-input
v-model="techigligAdd.name"
style="width: 240px"
placeholder="Pick a date"
:suffix-icon="Calendar"
/>
</div>
<div class="form-group">
<span>模块</span>
<el-select
v-model="techigligAdd.type"
filterable
clearable
placeholder
@change="xlxx"
>
<el-option
v-for="item in selectypeList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</div>
<div class="form-group-textarea">
<label for="pbimessage">问题内容</label>
<!-- 双向绑定的富文本编辑器 -->
<QuillEditor
ref="quillEditor"
v-model:content="techigligAdd.techigligmessage"
contentType="html"
:options="editorOptions"
@blur="onEditorBlur"
/>
</div>
<div>
子项目列表
<el-table :data="techigligAdd.smalltecList" border style="width: 100%">
<el-table-column
prop="title"
label="标题"
width="180"
show-overflow-tooltip
/>
<el-table-column
prop="easytitle"
label="简述"
width="180"
show-overflow-tooltip
/>
<el-table-column
prop="httpurl"
label="相关博客"
show-overflow-tooltip="false"
/>
<el-table-column fixed="right" label="操作" min-width="120">
<template #default>
<el-button type="success">修改</el-button>
<el-button type="primary">详情</el-button>
<el-button type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="add-button-container" @click="openDialog">新增子项目</div>
<div class="tjbut">
<el-button type="success" @click="addBut" round>提交</el-button>
<el-button type="info" @click="goback" round>返回</el-button>
</div>
<!-- 弹窗表单 -->
<el-dialog
v-model="dialogVisible"
title="添加新项目"
width="500px"
:before-close="handleClose"
>
<smallTecAdd
@smallTecAdd-Event="handleChildEvent"
@close-el-dialog-component="closeDialog"
/>
</el-dialog>
</div>
</template>
<script setup>
import { reactive, ref, onMounted } from "vue";
import tecApi from "../../api/tecHigLinIndex.js";
import { useRouter } from "vue-router";
import { QuillEditor } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import { useUserStore } from "../../../store/user.js";
import technologyTypeApi from "../../api/technologyTypeIndex.js";
import smallTecAdd from "../editor/SmallTecAdd.vue";
const isShowjsz = ref(false);
const router = useRouter();
// 用于保存 Quill 编辑器组件实例
const quillEditor = ref();
//表单引用
const formRef = ref(null);
//表单数据模型
const formData = reactive({
tecid: "",
title: "",
message: "",
httpurl: "",
easytitle: "",
});
//这里添加相关规则
const formRules = reactive([]);
//弹窗控制标识
const dialogVisible = ref(false);
const selectypeList = ref([
// { id: "1", name: "mysql" },
// { id: "2", name: "rabbitmq" },
// { id: "3", name: "springboot" },
// { id: "4", name: "nacos" },
]);
onMounted(() => {
dialogVisible.value = false;
getTecXiaLa();
});
//获取下拉列表接口
const getTecXiaLa = async () => {
const technologyTypeDTO = {};
const res = await technologyTypeApi.selectNoPage(technologyTypeDTO);
selectypeList.value = res.data.data;
};
//新增输入数据承接对象
const techigligAdd = reactive({
name: "",
techigligmessage: "",
type: "",
smalltecList: [],
});
//点击加号,展示输入项
const xlxx = () => {
isShowjsz.value = true;
};
// 图片上传处理函数
const imageHandler = async () => {
//创建一个隐藏的<input元素>
const input = document.createElement("input");
input.setAttribute("type", "file");
//且只接收图片
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
//获取选择的第一个文件
const file = input.files[0];
//如果文件不存在,即为null,undefined或者空值时,直接结束函数
if (!file) {
return;
}
try {
// ✅ 调用后端图片上传接口
const formData = new FormData();
formData.append("file", file);
formData.append("fileType", "1");
const response = await api.fileUpload(formData);
if (response.data.code == 200) {
// ✅ 使用组件 ref 获取 Quill 实例
const quill = quillEditor.value.getQuill();
const range = quill.getSelection(true);
// ✅ 插入图片
const wzpath = useUserStore.nginxBasePath + response.data.data.filePath;
console.log("完整访问路径:" + wzpath);
quill.insertEmbed(range.index, "image", wzpath);
quill.setSelection(range.index + 1);
}
} catch (error) {
console.error("图片上传失败:", error);
}
};
};
const addBut = () => {
tecApi.addTec(techigligAdd).then((res) => {
console.log(res.data);
});
};
const goback = () => {
router.push({
name: "TecHigligListName",
});
};
// 编辑器配置选项
const editorOptions = ref({
modules: {
toolbar: {
container: [
["bold", "italic", "underline", "strike"],
[{ list: "ordered" }, { list: "bullet" }],
["link", "image", "video"],
["clean"],
],
handlers: {
// 自定义图片上传处理
image: imageHandler,
},
},
},
placeholder: "请输入内容...",
theme: "snow",
});
// 编辑器失焦事件
const onEditorBlur = (event) => {
console.log("编辑器内容:", event.value);
};
//点击加号,打开一个弹窗
const openDialog = () => {
dialogVisible.value = true;
//如果表单有内容,则重置表单
if (formRef.value) {
formRef.value.resetFields();
}
};
//在关闭弹窗前确认,可以提供关闭拦截的作用
const handleClose = (done) => {
done();
};
//处理子组件传递的数据
const handleChildEvent = (smallFormData) => {
console.log(smallFormData);
//将数据添加到数组的末尾
techigligAdd.smalltecList.push(smallFormData);
};
const closeDialog = () => {
dialogVisible.value = false;
};
</script>
<style scoped lang="scss">
.ql-editor {
min-height: 300px;
}
.tjbut {
margin-top: 20px;
}
/* 下面这部分是加号按钮图标的css样式 */
.add-button-container {
display: flex;
align-items: left;
justify-content: center;
min-height: 50px;
border: 1px dashed #891818;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
}
.add-button-container:hover {
background-color: #54b34b;
}
/* 弹窗相关css */
.el-button {
margin: 10px;
}
/* 自定义弹窗样式 */
:deep(.el-dialog) {
border-radius: 12px;
width: 80%;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
:deep(.el-dialog__header) {
border-bottom: 1px solid #eee;
padding: 15px 20px;
}
:deep(.el-dialog__body) {
padding: 20px;
}
:deep(.el-form-item) {
margin-bottom: 18px;
}
</style>
这段代码有个问题,多次打开弹窗数据数据,最后展示在<el-table>的数据全部变成最后一次弹窗输入的内容,是什么原因,如何解决
最新发布