这个封装的是一个供整个项目使用的表格,可多次复用.放在一个全局使用的公共组件文件下.
大致功能介绍,封装自定义指令,点击获得焦点,显示输入框,失去焦点显示文本内容,类型是字典决定类型,图片可以显示图片名还是上传图片

子组件
- export default {
- props: {
- //生成表头
- fields: {
- type: Array,
- default: () => [],
- },
- //数据
- tableData: {
- type: Array,
- default: () => [],
- },
- },
- data() {
- return {};
- },
- created() {},
- // 自定义指令
- directives: {
- focus: {
- inserted: function (el) {
- el.querySelector("input").focus();
- },
- },
- },
- methods: {
- // 点击框 获取焦点 column列,row 行
- cellClick(column, row) {
- column.iseditor = true;
- row.isnameSelected = true;
- },
- //输入框失去焦点触发,此处用提示框提示修改
- blurEvent(column, row) {
- // console.log(column, row);
- column.iseditor = false;
- row.isnameSelected = false;
- },
-
- },
- };
- <template>
- <div>
- <el-table :data="tableData" border style="width: 100%">
- <el-table-column
- :prop="field.prop"
- :label="field.label"
- :min-width="field.minWidth || 140"
- v-for="(field, index) in fields"
- :key="index"
- show-overflow-tooltip
- >
- <template slot-scope="scope">
- <div v-if="field.slot">
- <slot :name="field.slot" :row="scope.row" />
- div>
- <div v-else>
- <div>
- <el-input
- v-if="field.iseditor && scope.row.isnameSelected"
- v-model="scope.row[field.prop]"
- @focus="cellClick(field, scope.row)"
- @blur="blurEvent(field, scope.row)"
- v-focus
- >
- el-input>
- <p @click="cellClick(field, scope.row)" v-else>
- {{ scope.row[field.prop] || "--" }}
- p>
- div>
- div>
- template>
- el-table-column>
- el-table>
- div>
- template>
- <style scoped>
- style>
- <style>
- .el-tooltip__popper {
- max-width: 1000px;
- }
- .disabled .el-upload--picture-card {
- display: none;
- }
- .avatar-uploader .el-upload {
- border: 1px dashed #d9d9d9;
- border-radius: 6px;
- cursor: pointer;
- position: relative;
- overflow: hidden;
- }
- .avatar-uploader .el-upload:hover {
- border-color: #409eff;
- }
- .avatar-uploader-icon {
- font-size: 28px;
- color: #8c939d;
- width: 178px;
- height: 178px;
- line-height: 178px;
- text-align: center;
- }
- .avatar {
- width: 178px;
- height: 178px;
- display: block;
- }
- style>
-
父组件
这里还有封装了一个文件上传的组件嵌套在表格中,算是拓展
- import editComponents from "../../components/editComponents";
- export default {
- components: { editComponents },
- data() {
- return {
- fields: [
- {
- prop: "industryCode",
- label: "产品",
- iseditor: false,
- },
- {
- prop: "id",
- label: "id",
- iseditor: false,
- },
- {
- prop: "paragraphType",
- label: "产品类型",
- iseditor: false,
- slot: "paragraphType",
- //根据这个slot来决定是否要使用插槽,让父组件可以更好地使用数据,不用传来传去,下面是一样的
- },
- {
- prop: "paragraphImage",
- label: "产品图片",
- slot: "paragraphImage",
- iseditor: false,
- },
- {
- prop: "action",
- label: "操作",
- slot: "action",
- },
- ],
- tableData: [
- {
- industryCode: "苹果",
- id: "15",
- paragraphType: "1",
- paragraphImage: "15.png",
- },
- {
- industryCode: "苹果",
- id: "16",
- paragraphType: "2",
- paragraphImage: "15.png",
- },
- {
- industryCode: "苹果",
- id: "17",
- paragraphType: "1",
- paragraphImage: "15.png",
- },
- ],
- fileList: [], //文件总数
- fileList1: [], //详情文件总数
- dialogImageUrl: "",
- dialogVisible: false,
- disabled: false,
- };
- },
- computed: {
- //文件上传地址
- upLoadUrl() {
- //process.env.VUE_APP_BASE_API 检测当前环境来决定接口路径
- //测试环境 VUE_APP_BASE_API = '/stage-api'
- if (process.env.VUE_APP_BASE_API == "/stage-api") {
- return "接口地址"; // 例如:'/minio/upload'
- // 生产
- } else if (process.env.VUE_APP_BASE_API == "生产接口") {
- return "接口地址";
- } else {
- // 本地
- return "接口地址";
- }
- },
- },
- created() {
- this.getlist();
- },
- methods: {
- //获取数据
- getlist() {
- // 发请求获取数据写在这里
- this.tableData = this.tableData.map((item) => {
- return { ...item, isnameSelected: false };
- });
- },
- // 添加
- hAdd() {
- const productObj1 = {
- industryCode: "",
- id: "",
- paragraphType: "",
- paragraphImage: "",
- iseditor: false,
- uuId: Math.random(),
- };
-
- this.tableData.push(productObj1);
- },
- // 删除
- del(row) {
- this.tableData = this.tableData.filter(
- (item) => item.uuId !== row.uuId || item.id !== row.id
- );
- },
- //图片上传===========================
- handleRemove(file) {
- console.log(file);
- console.log(this.$refs.upload);
- let uploadFiles = this.$refs.upload.uploadFiles;
- for (var i = 0; i < uploadFiles.length; i++) {
- if (uploadFiles[i]["url"] == file.url) {
- uploadFiles.splice(i, 1);
- }
- }
- },
- handlePictureCardPreview(file) {
- this.dialogImageUrl = file.url;
- this.dialogVisible = true;
- },
- handleDownload(file) {
- console.log(file);
- },
- // 文件上传成功-----------------
- async handleSuccess(response, row) {
- // 处理上传成功后的逻辑
- console.log("上传成功", response, row);
- this.fileName = response.data.fileName;
- row.paragraphImage = response.data.fileName;
- },
- handleError(err, file, fileList) {
- // 处理上传失败后的逻辑
- console.error("上传失败", err);
- },
- // selectedLabel(selectedValue) {
- // if (selectedValue === "1") {
- // return "选择一";
- // } else if (selectedValue === "2") {
- // return "选择二";
- // }
- // },
- async onSubmit() {
- // 删除不需要的属性
- this.tableData.forEach(function (obj) {
- if (obj.hasOwnProperty("iseditor")) {
- delete obj.iseditor;
- }
- if (obj.hasOwnProperty("uuId")) {
- delete obj.uuId;
- }
- if (obj.hasOwnProperty("isnameSelected")) {
- delete obj.isnameSelected;
- }
- });
- // 新增
- if (!this.industryCode) {
- // 新增请求写在这里
- console.log(res);
- if (res.message == "success") {
- this.$message({
- message: res.data,
- type: "success",
- duration: 1000,
- });
- } else {
- this.$message.error(res.data);
- }
- } else {
- // 修改请求写在这里
- console.log(res);
- if (res.message == "success") {
- this.$message({
- message: res.data,
- type: "success",
- duration: 1000,
- });
- this.goBack();
- } else {
- this.$message.error(res.data);
- }
- }
- },
- },
- };
- <template>
- <div>
- <el-button @click="hAdd" type="primary">添加el-button>
- <editComponents :fields="fields" :tableData="tableData">
- <template #action="{ row }">
- <el-button type="text" size="small" @click="del(row)">删除el-button>
- template>
- <template #paragraphImage="{ row }">
- <div>
- <p>{{ row.paragraphImage || "--" }}p>
- <el-upload
- ref="upload"
- :file-list="fileList1"
- :action="upLoadUrl"
- list-type="picture-card"
- :on-success="(e) => handleSuccess(e, row)"
- :on-error="handleError"
- >
- <i slot="default" class="el-icon-plus">i>
- <div slot="file" slot-scope="{ file }">
- <img
- class="el-upload-list__item-thumbnail"
- :src="file.url"
- alt=""
- />
- <span class="el-upload-list__item-actions">
- <span
- class="el-upload-list__item-preview"
- @click="handlePictureCardPreview(file)"
- >
- <i class="el-icon-zoom-in">i>
- span>
-
- <span
- v-if="!disabled"
- class="el-upload-list__item-delete"
- @click="handleRemove(file)"
- >
- <i class="el-icon-delete">i>
- span>
- span>
- div>
- el-upload>
- <el-dialog :visible.sync="dialogVisible">
- <img width="100%" :src="dialogImageUrl" alt="" />
- el-dialog>
- div>
- template>
- <template #paragraphType="{ row }">
- <div>
- <el-select v-model="row.paragraphType" placeholder="请选择">
- <el-option label="选择一" value="1">el-option>
- <el-option label="选择二" value="2">el-option>
- el-select>
-
- div>
- template>
- editComponents>
- <el-card>
- <div>
- <el-button type="primary" round @click="onSubmit">提交el-button>
- div>
- el-card>
- div>
- template>
- <style scoped>
- style>
-
-