动态文件夹+动态表格+动态表单 vue

您所在的位置:网站首页 el-select可编辑 动态文件夹+动态表格+动态表单 vue

动态文件夹+动态表格+动态表单 vue

2023-03-13 18:43| 来源: 网络整理| 查看: 265

动态文件夹+动态表格+表单(DynaActionForm)

使用技术 :Vue2 + element UI

01动态文件夹

过滤查询文件夹,动态添加文件夹,可修改文件名,添加子文件夹,删除文件夹

template                            添加 文件                                                                     {{ node.label }}             ​                          保存                            取消                                                                                                                                                                                                                                                               复制代码 css ::v-deep .el-tree-node__content {  padding: 10px 0;  height: auto; } ​ .treeSortList {  width: calc(100% - 30px);  display: flex;  align-items: center;  justify-content: space-between; } ​ .treeSortList .doBtn {  padding-right: 10px; } ​ .treeSortList .doBtn .el-button--text {  color: rgb(61, 61, 61);  padding: 5px; } ​ .treeSortList .doBtn .el-button--text i {  color: rgb(80, 80, 80); } ​ .treeSortList .doBtn .el-button--text i.el-icon-delete {  color: #f3a68e; } 复制代码 js data(){ return{ filterText: "", treeList: [], defaultProps: { children: "children", label: "label", }, showTree: false, //是否点击节点展开树,false 只能点前面三角图标展开 showBtn: [], showEdit: [], editData: [], newAddData: false, } } watch: {   filterText(val) {     this.$refs.tree.filter(val);   }, }, methods:{ filterNode(value, data) {     if (!value) return true;     return data.label.indexOf(value) !== -1;   },   handleCheckChange(data, checked, indeterminate) {     console.log(data, checked, indeterminate);   },   handlerAppend() {     let i = 0;     if (this.data) {       const newChild = {         id: id++,         label: "文件" + (Number(this.data.length) + 1),         children: [],       };       this.treeList.push(newChild);     } else {       const newChild = {         id: id++,         label: "文件" + (i + 1),         children: [],       };       this.treeList.push(newChild);     }     this.$message({       message: "添加成功,开始编写吧~",       type: "success",     });   },   //点击树节点   handleNodeClick(data) {     if (!this.ifEdit()) {       return;     }     this.showBtn = [];     this.$set(this.showBtn, data.id, true);   },   append(data) {     if (!this.ifEdit()) {       return;     }     const newChild = { id: id++, label: "", children: [] };     if (!data.children) {       this.$set(data, "children", []);     }     data.children.push(newChild); ​     this.newAddData = true;     this.$set(this.showEdit, newChild.id, true);   },   edit(data) {     var localEdit = localStorage.getItem("treeEdit");     var id = data.id;     var newlocalData = { [data.id]: data.label };     if (localEdit) {       var localData = JSON.parse(localEdit);       Object.assign(localData, newlocalData);       localData = JSON.stringify(localData);       localStorage.setItem("treeEdit", localData);     } else {       newlocalData = JSON.stringify(newlocalData);       localStorage.setItem("treeEdit", newlocalData);     }     // console.log(localStorage.getItem("treeEdit"));     this.showEdit = [];     this.$set(this.showEdit, data.id, true);   },   remove(node, data) {     const parent = node.parent;     const children = parent.data.children || parent.data;     const index = children.findIndex((d) => d.id === data.id);     children.splice(index, 1);   },   //保存   save(node, data) {     if (data.label == "") {       this.$message({         type: "error",         message: "请输入完整数据",         offset: 70,       });       return;     }     this.newAddData = "";     var localEdit = localStorage.getItem("treeEdit");     if (localEdit) {       var localData = JSON.parse(localEdit);       delete localData[data.id]; //删除已经取消项       localData = JSON.stringify(localData);       localStorage.setItem("treeEdit", localData); //重置缓存     }     this.$set(this.showEdit, data.id, false);   },   cancel(node, data) {     if (this.newAddData) {       this.remove(node, data);     }     var localEdit = localStorage.getItem("treeEdit");     if (localEdit) {       var localData = JSON.parse(localEdit);       data.label = localData[data.id];       delete localData[data.id]; //删除已经取消项       localData = JSON.stringify(localData);       localStorage.setItem("treeEdit", localData); //重置缓存     }     this.$set(this.showEdit, data.id, false);   },   //判断是否有编辑或增加的项   ifEdit() {     if (this.showEdit.indexOf(true) != -1) {       this.$message({         type: "error",         message: "先保存正在编辑的行",         offset: 70,       });       return false;     } else {       return true;     }   }, } 复制代码 效果展示

image.png

02动态表格 - Table/DynamicTable.vue

参考网址:blog.csdn.net/coralime/ar…

02-1使用展示 tableHeader 表头的数据 tableData 表格的数据 height 表格的高度 isSelection 是否添加勾选 isIndex 是否需要添加序号列 loading 加载 复制代码

tableHeader 表头的数据

--普通模式 tableHeader: [       {         label: '姓名',         prop: 'name',         module: 'text',         show: true       }, {         label: '地址',         prop: 'address',         module: 'text',         show: true,       }     ], 复制代码

image.png

--多级表头 tableHeader: [       {         label: '姓名',         prop: 'name',         module: 'text',         show: true       }, {         label: '地址',         prop: 'address',         module: 'text',         show: true,         children: [           {             label: '地址1',             prop: 'address1',             module: 'text',             show: true,             children: [               {                 label: '地址1',                 prop: 'address1',                 module: 'text',                 show: true,               },               {                 label: '地址2',                 prop: 'address2',                 module: 'text',                 show: true,               }             ]           },           {             label: '地址2',             prop: 'address2',             module: 'text',             show: true,           }         ]       }     ], 复制代码

image.png

02-2动态表文件 - componebts/Table/DynamicTable.vue                                                                                             import TableColumn from '@/components/Table/TableColumn' ​ export default {    name: 'DynamicTable',    components: {        TableColumn   },    props: {        // 表格的数据        tableData: {            type: Array,            required: true       },        // 多级表头的数据        tableHeader: {            type: Array,            required: true       },        // 表格的高度        height: {            type: String,            default: '300'       },        // 是否需要添加序号列        isIndex: {            type: Boolean       },        // 是否添加勾选        isSelection: {            type: Boolean       },        loading: {            type: Boolean,            default: false       }   },    data() {        return {            tableRefresh: 0       }   },    computed: {        bindTableColumns() {            this.tableRefresh++            return this.tableHeader.filter((column) => column.show);       },   },    methods: {        // 详情        handleClick(row) {            this.$emit('json-click', row)            //数据是string类型的需要用到JSON.parse(object)将string类型转换为JSON类型            //row.jsonData的jsonData是后台接口数据所提供的,this.jsonData是容器,用来实现数据绑定显示的:value="jsonData"       },        // 行点击事件        handleRowClick(row, column, event) {            // 通知调用父组件的row-click事件            // row作为参数传递过去            this.$emit('row-click', row)       },        handleSelectionChange(val) {            this.$emit('selection-change', val)       },        hIndex(index) {            // index索引从零开始,index +1即为当前数据序号            this.$options.parent.queryParams.pageNum                                                                         ​ import DynamicTable from "@/components/Table/DynamicTable.vue" import TrendsFrom from "./TrendsFrom.vue" import LeadingIn from "./LeadingIn.vue" ​ let id = 20; ​ export default {  components: { DynamicTable, TrendsFrom, LeadingIn },  data() {    return {      filterText: "",      treeList: [],      defaultProps: {        children: "children",        label: "label",     },      showTree: false, //是否点击节点展开树,false 只能点前面三角图标展开      showBtn: [],      showEdit: [],      editData: [],      newAddData: false,      // 表格数据      showQueryParams: true,      tableHeader: [],      loading: false,      tableData: [],      queryParams: {        pageNum: 1,        pageSize: 20     },      // 表头添加      ruleForm: {        label: '',        props: '',        value: '',        radio: false,        childrenArr: [],     },      selectShow: false,      modules: [{        value: 'text',        label: '文字'     }, {        value: 'textarea',        label: '文本域'     }, {        value: 'password',        label: '密码'     },        // {        //   value:'select',        //   label:'下拉框'        // }, {        //   value: 'image',        //   label: '图片'        // }     ],      rules: {        label: [         { required: true, message: '请填写表头字段', trigger: 'blur' }       ],        props: [         {            required: true,            validator: (rule, value, callback) => {              var rul = /(?![A-Z]*$)||(?![a-z]*$)/              if (!rul.test(value)) {                callback(                  new Error(                    '索引必须是大写字母或小写字母以上类型组成!'                 )               )             } else {                callback()             }           }, trigger: 'blur'         }       ],     },      visible: false,      selectionKeys: [],      checkedTableColumns: [],      total: 0,      showJson: false,      jsonData: ''   }; },  watch: {    filterText(val) {      this.$refs.tree.filter(val);   }, },  computed: {    tableDataList() {      return this.tableData.slice((this.queryParams.pageNum - 1) * this.queryParams.pageSize, this.queryParams.pageNum * this.queryParams.pageSize)   } },  mounted() { ​    this.treeList = [{      id: 1,      label: "文件1",      children: [       {          id: 11,          label: "文件1-01",          children: [],       },       {          id: 12,          label: "文件1-02",          children: [],       }     ],   }, {      id: 2,      label: "文件2",      children: [],   }, {      id: 3,      label: "文件3",      children: [],   }] ​ },  methods: {    filterNode(value, data) {      if (!value) return true;      return data.label.indexOf(value) !== -1;   },    handlerAppend() {      let i = 0;      if (this.data) {        const newChild = {          id: id++,          label: "文件" + (Number(this.data.length) + 1),          children: [],       };        this.treeList.push(newChild);     } else {        const newChild = {          id: id++,          label: "文件" + (i + 1),          children: [],       };        this.treeList.push(newChild);     }      this.$message({        message: "添加成功,开始编写吧~",        type: "success",     });   },    //点击树节点    handleNodeClick(data) {      if (!this.ifEdit()) {        return;     }      this.showBtn = [];      // 数组:第一个参数是要修改的数组, 第二个值是修改的下标或字段,第三个是要修改成什么值      // 对象:第一个参数是要修改的对象, 第二个值是修改属性字段,第三个是要修改成什么值      this.$set(this.showBtn, data.id, true);      this.getTableData(data.id)      // console.log(data)   },    append(data) {      if (!this.ifEdit()) {        return;     }      const newChild = { id: id++, label: "", children: [] };      if (!data.children) {        this.$set(data, "children", []);     }      data.children.push(newChild); ​      this.newAddData = true;      this.$set(this.showEdit, newChild.id, true);   },    edit(data) {      var localEdit = localStorage.getItem("treeEdit");      var id = data.id;      var newlocalData = { [data.id]: data.label };      if (localEdit) {        var localData = JSON.parse(localEdit);        Object.assign(localData, newlocalData);        localData = JSON.stringify(localData);        localStorage.setItem("treeEdit", localData);     } else {        newlocalData = JSON.stringify(newlocalData);        localStorage.setItem("treeEdit", newlocalData);     }      // console.log(localStorage.getItem("treeEdit"));      this.showEdit = [];      this.$set(this.showEdit, data.id, true);   },    remove(node, data) {      const parent = node.parent;      const children = parent.data.children || parent.data;      const index = children.findIndex((d) => d.id === data.id);      children.splice(index, 1);   },    //保存    save(node, data) {      if (data.label == "") {        this.$message({          type: "error",          message: "请输入完整数据",          offset: 70,       });        return;     }      this.newAddData = "";      var localEdit = localStorage.getItem("treeEdit");      if (localEdit) {        var localData = JSON.parse(localEdit);        delete localData[data.id]; //删除已经取消项        localData = JSON.stringify(localData);        localStorage.setItem("treeEdit", localData); //重置缓存     }      this.$set(this.showEdit, data.id, false);   },    cancel(node, data) {      if (this.newAddData) {        this.remove(node, data);     }      var localEdit = localStorage.getItem("treeEdit");      if (localEdit) {        var localData = JSON.parse(localEdit);        data.label = localData[data.id];        delete localData[data.id]; //删除已经取消项        localData = JSON.stringify(localData);        localStorage.setItem("treeEdit", localData); //重置缓存     }      this.$set(this.showEdit, data.id, false);   },    //判断是否有编辑或增加的项    ifEdit() {      if (this.showEdit.indexOf(true) != -1) {        this.$message({          type: "error",          message: "先保存正在编辑的行",          offset: 70,       });        return false;     } else {        return true;     }   },    getTableData(id) {      if (id == 11) {        this.tableHeader = [         {            id: Math.random(),            label: '数量(家)',            prop: 'number',            module: 'text',            show: true         }, {            id: Math.random(),            label: '名称',            prop: 'name',            module: 'text',            show: true,         }, {            id: Math.random(),            label: '详细地址',            prop: 'address',            module: 'textarea',            show: true,         }, {            id: Math.random(),            label: '负责人姓名、电话',            prop: 'name_phone',            module: 'text',            show: true,         }       ]        this.checkedTableColumns = this.tableHeader.map(column => column.prop)     } else if (id == 12) {        this.tableHeader = [         {            id: Math.random(),            label: '姓名',            prop: 'name',            module: 'text',            show: true,         }, {            id: Math.random(),            label: '账号',            prop: 'account',            module: 'text',            show: true,         }, {            id: Math.random(),            label: '部门',            prop: 'department',            module: 'text',            show: true,         }, {            id: Math.random(),            label: '职务',            prop: 'job',            module: 'text',            show: true,         }, {            id: Math.random(),            label: '所属规则',            prop: 'Owning_rule',            module: 'text',            show: true,         }, {            id: Math.random(),            label: '概括',            prop: 'generalize',            // module: 'text',            show: true,            children: [             {                id: Math.random(),                label: '应打卡天数(天)',                prop: 'day1',                module: 'text',                show: true,             }, {                id: Math.random(),                label: '实际打卡天数(天)',                prop: 'day2',                module: 'text',                show: true,             }, {                id: Math.random(),                label: '正常天数(天)',                prop: 'day3',                module: 'text',                show: true,             }, {                id: Math.random(),                label: '异常天数(天)',                prop: 'day4',                module: 'text',                show: true,             }, {                id: Math.random(),                label: '标准工作时长(小时)',                prop: 'day5',                module: 'text',                show: true,             }, {                id: Math.random(),                label: '实际工作时长(小时)',                prop: 'day6',                module: 'text',                show: true,             },           ]         }       ]        this.checkedTableColumns = this.tableHeader.map(column => column.prop)        this.tableData = [{          id: Math.random(),          name: '张三',          account: '23523',          department: '897',          job: 'nalvnl',          Owning_rule: '23',          generalize: '890',          day1: '1',          day2: '2',          day3: '3',          day4: '4',          day5: '5',          day6: '6',       }, {          id: Math.random(),          name: '李四',          account: '23523',          department: '897',          job: 'nalvnl',          Owning_rule: '23',          generalize: '890',          day1: '1',          day2: '2',          day3: '3',          day4: '4',          day5: '5',          day6: '6',       }]     } else {        this.tableHeader = []        this.tableData = []        this.checkedTableColumns = this.tableHeader.map(column => column.prop)     }   },    // 搜索    changeQueryParams(val) { ​   },    inputChildren(val) {      if (val) {        this.ruleForm.childrenArr.push({          key: Date.now(),          label: '',          prop: '',          value: '',       })     } else {        this.ruleForm.childrenArr = []     }   },    // 添加子项    removeDomain(index) {      // var index = this.ruleForm.childrenArr.indexOf(item => item.key == domain.key)      if (index !== 0) {        this.ruleForm.childrenArr.splice(index, 1)     }   },    addDomain() {      this.ruleForm.childrenArr.push({        key: Date.now(),        label: '',        prop: '',        value: '',     });   },    // 添加表头    submitForm(formName) {      this.$refs[formName].validate((valid) => {        if (valid) {          if (this.tableHeader.length == 0) {            if (this.ruleForm.label && this.ruleForm.props && this.ruleForm.value) {              this.tableHeader.push({                label: this.ruleForm.label,                prop: this.ruleForm.props,                module: this.ruleForm.value,                show: true,                radio: this.ruleForm.radio,                children: this.ruleForm.childrenArr             })              this.ruleForm = this.$options.data.call(this).ruleForm              this.visible = false           }         } else {            this.tableHeader.forEach(item => {              if (item.label == this.ruleForm.label || item.prop == this.ruleForm.props) {                if (item.prop == this.ruleForm.props) {                  this.$message.error('索引(prop)已存在,换一个索引(prop)填写!');               } else {                  this.$message.error('字段(label)已存在,换一个字段(label)填写!');               }             } else {                if (this.ruleForm.label && this.ruleForm.props && this.ruleForm.value) {                  this.tableHeader.push({                    label: this.ruleForm.label,                    prop: this.ruleForm.props,                    module: this.ruleForm.value,                    show: true,                    radio: this.ruleForm.radio,                    children: this.ruleForm.childrenArr                 })                  this.ruleForm = this.$options.data.call(this).ruleForm                  this.visible = false ​               }             } ​           })         }          this.checkedTableColumns = this.tableHeader.map(column => column.prop)       } else {          console.log('error submit!!');          return false;       }     });   },    changeModule(val) {      console.log(val)      if (val == 'select') {        this.selectShow = true     } else {        this.selectShow = false     }   },    resetForm(formName) {      this.$refs[formName].resetFields();   },    // 添加列表    handlerAddTable() {      this.$refs.TrendsFrom.init('添加', this.tableHeader);   },    // 修改列表    handlerEditTable() {      this.$refs.TrendsFrom.init('修改', this.tableHeader, this.selectionKeys[0]);   },    // 删除列表    handlerDelTable() {      this.$confirm('此操作将删除该条数据,是否继续?', '提示', {        confirmButtonText: '确定',        cancelButtonText: '取消',        type: 'warning'     })       .then(() => {          // 确定          this.selectionKeys.forEach((sItem, j) => {            let key = Object.keys(sItem)[0]            let indexKey = this.tableData.findIndex((el) => el[key] == sItem[key]);//找到下标            this.tableData.splice(indexKey, this.selectionKeys.length)         })          this.$refs.TableList.$refs.multipleTable.clearSelection()          this.total = this.tableData.length          // this.queryParams.pageNum = 1          this.$message({            showClose: true,            message: '成功'         });       })       .catch(() => {          // 取消          this.$message({            showClose: true,            message: '取消'         });       })   },    // 导入表格    handlerLeadingIn() {      this.$refs.LeadingIn.init('导入', this.tableHeader, this.tableData);   },    setDesc() {      // JS-获取到26个英文大写字母(A-Z)      const letterArr = []      Array(26).fill('').map((item, index) => {        letterArr.push(String.fromCharCode(index + 65))     })      return letterArr   },    /** 导出按钮操作 */    handleExport() {      let tHeader = [], multiHeader = [], header1 = [], filterPop = [], merges = [], merges1 = [], merges3 = [], merges2 = [], headerRowLength = 1;      let flag = this.tableHeader.some(column => {        if (column.children && column.children.length > 0) {          return true       }        return false     })      if (flag) {        const randomAbc = this.setDesc()        this.tableHeader.map((column, i) => {          if (column.show) {            if (column.children && column.children.length > 0) {              headerRowLength++              header1.push(column.label)              column.children.map((childColumn, j) => {                merges2.push(randomAbc[j] + headerRowLength)                tHeader.push(childColumn.label)                filterPop.push(childColumn.prop)                header1.push('') ​             })           } else {              merges1.push(randomAbc[i] + headerRowLength)              header1.push(column.label)              tHeader.push('')              filterPop.push(column.prop)           }         } ​       })        // 二维数组依次递增 表格头部 // tHeader 表格头部最后一级        multiHeader.push(header1)        // 合并的行        merges1.forEach(i => {          merges2.forEach(j => {            if (i.substring(0, 1) == j.substring(0, 1)) {              merges.push(i + ':' + j)           }         })       })        // 合并的列        let len = merges1.length        tHeader.forEach((item, o) => {          merges3.push(randomAbc[o])       })        merges3.splice(0, len)        merges.push(merges3.slice(0, 1)[0] + (headerRowLength - 1) + ':' + merges3.slice(-1)[0] + (headerRowLength - 1)) ​        this.$confirm('确定导出全部数据么?', '提示', {          confirmButtonText: '确定',          cancelButtonText: '取消',          type: 'warning'       })         .then(() => {            // 确定            this.getXlsxData_many(tHeader, multiHeader, filterPop, merges, this.tableData)            this.$message({              showClose: true,              message: '下载成功'           });         })         .catch(() => {            // 取消            this.$message({              showClose: true,              message: '取消下载'           });         })     } else {        this.tableHeader.map((column, i) => {          if (column.show) {            tHeader.push(column.label)            filterPop.push(column.prop)         }       })        this.$confirm('确定导出全部数据么?', '提示', {          confirmButtonText: '确定',          cancelButtonText: '取消',          type: 'warning'       })         .then(() => {            // 确定            this.getXlsxData(tHeader, filterPop, this.tableData)            this.$message({              showClose: true,              message: '下载成功'           });         })         .catch(() => {            // 取消            this.$message({              showClose: true,              message: '取消下载'           });         }) ​     } ​   },    // 多行表头下载    getXlsxData_many(tHeader, multiHeader, filterPop, merges, dataT = []) {      require.ensure([], () => {        const { export_json_to_excel_headerMany } = require('@/excel/Export2Excel.js');// 这里 require 写你的Export2Excel.js的绝对地址        const data = this.formatJson(filterPop, dataT);//格式化        // console.log(tHeader, multiHeader, filterPop, merges, dataT);        //这个得说明一下:网上得博客每个不一样,你那我的直接用也是没啥用得,你的理解这个合并是怎么写的:根据你的多级表头,如果没有合并得从上往下写,遇到开始合并单元格的,从左往右得单行写,从上到下,直到写完整        export_json_to_excel_headerMany({          multiHeader,          header: tHeader,          data,          filename: `user_${new Date().getTime()}`, merges,          autoWidth: true,       })     })   },    // 单行表头下载    getXlsxData(tHeader = [], filterVal = [], dataT = []) {      require.ensure([], () => {        const { export_json_to_excel } = require('@/excel/Export2Excel.js');// 这里 require 写你的Export2Excel.js的绝对地址        // const tHeader = []; //对应表格输出的title        // const filterVal = []; // 对应表格输出的数据        const data = this.formatJson(filterVal, dataT);        export_json_to_excel(tHeader, data, `user_${new Date().getTime()}`); //对应下载文件的名字     })   },    formatJson(filterVal, jsonData) {      return jsonData.map(v => filterVal.map(j => v[j]))   },    // 刷新列表    handlerUpdateTable() {      this.loading = true      setTimeout(() => {        this.tableData = this.$options.data.call(this).tableData        this.loading = false     }, 200);   },    // 显示隐藏列    handleCheckedCitiesChange(value) {      this.tableHeader.forEach(column => {        // 如果选中,则设置列显示        if (value.includes(column.prop)) {          column.show = true;       } else {          // 如果未选中,则设置列隐藏          column.show = false;       }     })   },    // 表格数据    handlerConfirm(data, keys) {      if (keys) {        let key = Object.keys(keys)[0]        let indexKey = this.tableData.findIndex((el) => el[key] == keys[key]);//找到下标        this.tableData[indexKey] = data //替换数据        this.$message({          message: '修改成功!',          type: 'success'       });     } else {        this.tableData.push(data)        this.$message({          message: '添加成功!',          type: 'success'       });     }      this.total = this.tableData.length   },    // 勾选    handlerSelectionChange(val) {      // console.log(val)      this.selectionKeys = val   },    // 分页    handleSizeChange(val) {      this.queryParams.pageNum = 1;      this.queryParams.pageSize = val;   },    handleCurrentChange(val) {      this.queryParams.pageNum = val;   },    // 日志    handlerJsonClick(row) {      this.showJson = true      this.jsonData = row   }, }, }; ​ ::v-deep .el-tree-node__content {  padding: 10px 0;  height: auto; } ​ .treeSortList {  width: calc(100% - 30px);  display: flex;  align-items: center;  justify-content: space-between; } ​ .treeSortList .doBtn {  padding-right: 10px; } ​ .treeSortList .doBtn .el-button--text {  color: rgb(61, 61, 61);  padding: 5px; } ​ .treeSortList .doBtn .el-button--text i {  color: rgb(80, 80, 80); } ​ .treeSortList .doBtn .el-button--text i.el-icon-delete {  color: #f3a68e; } ​ .container {  height: 100vh;  overflow: hidden;  display: flex;  box-sizing: border-box; ​  .left-con {    background-color: #d3dce6;    color: #333;   // text-align: center;   // line-height: 200px;    width: 320px;    box-sizing: border-box;    padding: 20px;    overflow-y: scroll; } ​  .right-con {    flex: 1;    display: flex;    flex-direction: column;    box-sizing: border-box; ​    .header-con {      position: sticky;      top: 0;      margin-bottom: 10px;      padding: 10px;   } ​    .content-con {      flex: 1;      overflow-y: scroll;      padding: 10px; ​      .content-con-top {        display: flex;        margin: 10px 0;        justify-content: space-between; ​        .content-con-l {} ​        .content-con-r {          display: flex;          width: 10%;          justify-content: space-between;       }     }   } } } ​ .header-con, .content-con {  background-color: #b3c0d1;  color: #333; // text-align: center; // line-height: 60px; } ​ .fromCss {  .el-form-item {    margin-bottom: 0;    margin-top: 10px; } } ​ .icon-btn {  width: 50px;  height: 50px;  border: 1px solid #cdcdcd;  background: white;  border-radius: 25px;  overflow: hidden;  position: relative;  transition: width 0.2s ease-in-out;  font-weight: 500;  font-family: inherit;  margin: 10px auto; } ​ .add-btn:hover {  width: 120px; } ​ .add-btn::before, .add-btn::after {  transition: width 0.2s ease-in-out, border-radius 0.2s ease-in-out;  content: "";  position: absolute;  height: 4px;  width: 10px;  top: calc(50% - 2px);  background: seagreen; } ​ .add-btn::after {  right: 14px;  overflow: hidden;  border-top-right-radius: 2px;  border-bottom-right-radius: 2px; } ​ .add-btn::before {  left: 14px;  border-top-left-radius: 2px;  border-bottom-left-radius: 2px; } ​ .icon-btn:focus {  outline: none; } ​ .btn-txt {  opacity: 0;  transition: opacity 0.2s; } ​ .add-btn:hover::before, .add-btn:hover::after {  width: 4px;  border-radius: 2px; } ​ .add-btn:hover .btn-txt {  opacity: 1; } ​ .add-icon::after, .add-icon::before {  transition: all 0.2s ease-in-out;  content: "";  position: absolute;  height: 20px;  width: 2px;  top: calc(50% - 10px);  background: seagreen;  overflow: hidden; } ​ .add-icon::before {  left: 22px;  border-top-left-radius: 2px;  border-bottom-left-radius: 2px; } ​ .add-icon::after {  right: 22px;  border-top-right-radius: 2px;  border-bottom-right-radius: 2px; } ​ .add-btn:hover .add-icon::before {  left: 15px;  height: 4px;  top: calc(50% - 2px); } ​ .add-btn:hover .add-icon::after {  right: 15px;  height: 4px;  top: calc(50% - 2px); } ​ 复制代码 TrendsFrom.vue 表单新增或修改                                                                                                                                                                                                 取 消           确 定         ​ export default {   props: {       parentThat: {}   },   data() {       return {           // 表格添加           title: '',           dialogFormVisible: false,           form: {},           headerData: null,           editKeys: null,       }   },   mounted() {   },   methods: {       init(title, headerData, keys) {           this.dialogFormVisible = true;           this.title = title           this.headerData = headerData           this.editKeys = null           // console.log(headerData);           if (keys) {               this.editKeys = keys               this.form = JSON.parse(JSON.stringify(keys))           }       },       submitForm(formName) {           this.$refs[formName].validate((valid) => {               if (valid) {                   if (this.editKeys) {                       this.$emit('handlerConfirm', this.form, this.editKeys)                   } else {                       this.$emit('handlerConfirm', this.form)                   }                   this.parentThat.$refs.TableList.$refs.multipleTable.clearSelection()                   this.form = this.$options.data.call(this).form                   this.dialogFormVisible = false;               } else {                   console.log('error submit!!');                   return false;               }           });       },       resetForm(formName) {           this.form = this.$options.data.call(this).form           this.dialogFormVisible = false;           this.$refs[formName].resetFields();       },   } } ​ .fromCss {   display: flex;   flex-wrap: wrap;   justify-content: space-between; } 复制代码 LeadingIn.vue 导入                             将文件拖到此处,或点击上传                         是否更新已经存在的数据               仅允许导入xls、xlsx格式文件。下载模板                                 确 定           取 消         ​ export default {   props: {       parentThat: {},   },   data() {       return {           // 表格添加           title: '',           dialogFormVisible: false,           upload: {               // 是否更新已数据               isUploading: false,               // 上传的地址               url: process.env.VUE_APP_BASE_API +                   "/efarmcloud-open-file/api/v1/files/upload"           },           XlsxData: [],           fileContent: null,           headerTable: [],           tableData: [],           loading:null,       }   },   methods: {       init(title, headerTable, tableData) {           this.dialogFormVisible = true;           this.title = title           this.headerTable = headerTable           this.tableData = tableData       },       setDesc() {           // JS-获取到26个英文大写字母(A-Z)           const letterArr = []           Array(26).fill('').map((item, index) => {               letterArr.push(String.fromCharCode(index + 65))           })           return letterArr       },       /** 下载模板操作 */       importTemplate() {           let tHeader = [], multiHeader = [], header1 = [], filterPop = [], merges = [], merges1 = [], merges3 = [], merges2 = [], headerRowLength = 1;           // 有69个元素是空的,所以直接进行了截取           let flag = this.headerTable.some(column => {               if (column.children && column.children.length > 0) {                   return true               }               return false           })           if (flag) {               const randomAbc = this.setDesc()               this.headerTable.map((column, i) => {                   if (column.show) {                       if (column.children && column.children.length > 0) {                           headerRowLength++                           header1.push(column.label)                           column.children.map((childColumn, j) => {                               merges2.push(randomAbc[j] + headerRowLength)                               tHeader.push(childColumn.label)                               filterPop.push(childColumn.prop)                               header1.push('') ​                           })                       } else {                           merges1.push(randomAbc[i] + headerRowLength)                           header1.push(column.label)                           tHeader.push('')                           filterPop.push(column.prop)                       }                   } ​               })               // 二维数组依次递增 表格头部 // tHeader 表格头部最后一级               multiHeader.push(header1)               // 合并的行               merges1.forEach(i => {                   merges2.forEach(j => {                       if (i.substring(0, 1) == j.substring(0, 1)) {                           merges.push(i + ':' + j)                       }                   })               })               // 合并的列               let len = merges1.length               tHeader.forEach((item, o) => {                   merges3.push(randomAbc[o])               })               merges3.splice(0, len)               merges.push(merges3.slice(0, 1)[0] + (headerRowLength - 1) + ':' + merges3.slice(-1)[0] + (headerRowLength - 1))               // console.log(filterPop, tHeader, multiHeader, headerRowLength, randomAbc, merges1, merges2, merges, merges3);               this.getXlsxData_many(tHeader, multiHeader, filterPop, merges)           } else {                 this.tableHeader.map((column, i) => {                   if (column.show) {                       tHeader.push(column.label)                       filterPop.push(column.prop)                   }               })               this.getXlsxData(tHeader, filterPop)           }       },       // 多行表头下载       getXlsxData_many(tHeader, multiHeader, filterPop, merges, dataT = []) {           require.ensure([], () => {               const { export_json_to_excel_headerMany } = require('@/excel/Export2Excel.js');// 这里 require 写你的Export2Excel.js的绝对地址               const data = this.formatJson(filterPop, dataT);//格式化               // console.log(tHeader, multiHeader, filterPop, merges, dataT);               //这个得说明一下:网上得博客每个不一样,你那我的直接用也是没啥用得,你的理解这个合并是怎么写的:根据你的多级表头,如果没有合并得从上往下写,遇到开始合并单元格的,从左往右得单行写,从上到下,直到写完整               export_json_to_excel_headerMany({                   multiHeader,                   header: tHeader,                   data,                   filename: `user_${new Date().getTime()}`, merges,                   autoWidth: true,               })           })       },       // 单行表头下载       getXlsxData(tHeader = [], filterVal = [], dataT = []) {           require.ensure([], () => {               const { export_json_to_excel } = require('@/excel/Export2Excel.js');// 这里 require 写你的Export2Excel.js的绝对地址               // const tHeader = []; //对应表格输出的title               // const filterVal = []; // 对应表格输出的数据               const data = this.formatJson(filterVal, dataT);               console.log(tHeader, data, filterVal, '下载');               export_json_to_excel(tHeader, data, `user_${new Date().getTime()}`); //对应下载文件的名字           })       },       formatJson(filterVal, jsonData) {           return jsonData.map(v => filterVal.map(j => v[j]))       },       // 核心部分代码(handleChange 和 importfile)       handleChange(file) {           this.fileContent = file.raw           const fileName = file.name           const fileType = fileName.substring(fileName.lastIndexOf('.') + 1)           if (this.fileContent) {               if (fileType === 'xlsx' || fileType === 'xls') {                   // 判断是否有子项                   let flag = this.headerTable.some(column => {                       if (column.children && column.children.length > 0) {                           return true                       }                       return false                   })                   this.loading = this.$loading({                       lock: true,                       text: 'Loading',                       spinner: 'el-icon-loading',                       background: 'rgba(0, 0, 0, 0.7)'                   });                   if (flag) {                       this.importFile(this.fileContent, flag)                       this.loading.close();                   } else {                       this.importFile(this.fileContent, flag)                       this.loading.close();                   } ​               } else {                   this.$message({                       type: 'warning',                       message: '附件格式错误,请重新上传!'                   })               }           } else {               this.$message({                   type: 'warning',                   message: '请上传附件!'               })           }       },       importFile(obj, bol) {           const reader = new FileReader()           const _this = this           reader.readAsArrayBuffer(obj)           reader.onload = function () {               const buffer = reader.result               const bytes = new Uint8Array(buffer)               const length = bytes.byteLength               let binary = ''               for (let i = 0; i < length; i++) {                   binary += String.fromCharCode(bytes[i])               }               const XLSX = require('xlsx')               const wb = XLSX.read(binary, {                   type: 'binary'               })               const outData = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])               // console.log(outData);               const arr = [...outData], newArr = []               arr.map((v, j) => {                   let list = _this.headerTable.map((s, i) => {                       let key = Object.keys(v)[i]                       if (key == s.label) {                           return { id: Math.random(), [s.prop]: v[key] }                       }                   })                   let newList = []                   list.forEach(item => {                       if (item) {                           if (bol) {                               // 手动填写子项的prop值与对应xlsx 对应的字段                               newList.push(item, {                                   day1: v.概括,                                   day2: v.__EMPTY,                                   day3: v.__EMPTY_1,                                   day4: v.__EMPTY_2,                                   day5: v.__EMPTY_3,                                   day6: v.__EMPTY_4,                               })                           } else {                               newList.push(item)                           }                       }                   })                   if (newList.length != 0) {                       newArr.push(Object.assign(...newList))                   } else {                       if (j < 1 && !bol) {                           _this.$notify.error({                               title: '错误',                               message: '上传的数据格式不匹配,请重新上传!'                           });                           _this.$refs.uploadRef.clearFiles();                       }                   }               })               _this.XlsxData = newArr           }       },       submitForm(uploadRef) {           // console.log(this.XlsxData, this.parentThat._data.tableData, this.upload.isUploading);           if (this.upload.isUploading) {               this.parentThat._data.tableData = this.XlsxData           } else {               this.parentThat._data.tableData = this.parentThat._data.tableData.concat(this.XlsxData)           }           this.parentThat._data.total = this.parentThat._data.tableData.length //数量           this.dialogFormVisible = false;           this.$refs[uploadRef].clearFiles();       },       resetForm(uploadRef) {           this.dialogFormVisible = false;           this.$refs[uploadRef].clearFiles();       },   } } ​ .el-upload__tip {   display: flex;   flex-direction: column;   align-items: center; } 复制代码 技术难点:

在已有表头已有数据的情况下,再次添加表头修改数据回显慢,切换页面数据才会显示(不明原因)。

使用前端分页,会导致表格勾选错乱或不显示(解决方案使用computed)

​ computed: {   tableDataList() {     return this.tableData.slice((this.queryParams.pageNum - 1) * this.queryParams.pageSize, this.queryParams.pageNum * this.queryParams.pageSize)   } }, 复制代码

删除删掉的永远是首条(由于没有id值,拿到的永远是第一条)(已修改)

表头过多的情况下加载会很慢,导入字符串建议一对一填写,数据缺失或表头样式复杂数据不准确

动态表单或动态表格内用使用或展示根据使用情况进行增减

弹窗样式(居中显示不超过屏幕内含滚动条)  // el-dialog高度自适应,内容超出时中间出现滚动条 .common-dialog {  display: flex;  justify-content: center;  align-items: Center;  overflow: hidden; ​ ​  .el-dialog:not(.is-fullscreen) {    margin-top: 0 !important; } ​  .el-dialog {    margin: 0 auto !important;    position: relative; ​ ​    .el-dialog__header {      position: absolute;      left: 0;      top: 0;      right: 0;      width: 100%;      height: 60px;      z-index: 1;      background-color: #fff;   } ​    .el-dialog__body {      width: 100%;      overflow: hidden;      overflow-y: auto;      max-height: 100vh; //最大高度为视口高度的90%      padding-top: 60px;      padding-bottom: 100px;      z-index: 1;   } ​    .el-dialog__footer {      position: absolute;      left: 0;      bottom: 0;      right: 0;      width: 100%;      height: 80px;      z-index: 1;      background-color: #fff;   } } } 复制代码


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3