zoukankan      html  css  js  c++  java
  • vue+elementui纯表格页面(左右结构布局,构成:表格和弹窗组件、左边目录)

    父页面(左右结构布局,构成:表格和弹窗组件、左边目录)

    <template>
      <div style="height:100%;display:flex">
        <div class="leftshuxing">
          <left-list @cliitem="handleitem" @reload="reload" class="leftlist"></left-list>
        </div>
        <div class="rightdrig">
          <div class="gr-datagrid-notitle">
            <data-grid ref="dataGrid" @editFun="editFun" @deleteFun="deleteFun" @addFun="addFun" />
          </div>
          <gr-dialog :dialogVisible.sync="dialogVisible" :dialogOptions="dialogOptions" :dialogContentComponent="dialogContentComponent" :data="dialogData" :show="show" />
        </div>
      </div>
    </template>
    <script>
    import dataGrid from '@/components/grid/zzqx-gn/index.vue'
    import grDialog from '@/components/common/dialog/index.vue'
    import leftList from '@/components/grid/zzqx-gn/leftList.vue'
    import { mapState } from 'vuex'
    export default {
      data() {
        return {
          dialogOptions: {},
          dialogVisible: false,
          dialogContentComponent: null,
          dialogData: {},
          show: true
        }
      },
      components: {
        dataGrid,
        grDialog,
        leftList
      },
      computed: mapState(['chooseId', 'chooseData']),
    
      methods: {
        reload(prame) {
          this.$refs.dataGrid.load(prame)
        },
        addFun(data) {
          this.show = true
          this.dialogVisible = true
          this.dialogOptions = {
             '700px',
            title: '增加功能',
            saveBtn: '提交'
          }
          this.dialogContentComponent = () =>
            import('@/components/dialog/zzqx-gn/add-gn.vue')
        },
        editFun() {
          if (this.chooseData.length !== 1) {
            this.$message.warning('请选择一个功能菜单后操作')
            return
          }
          this.data = this.chooseData[0]
          this.show = true
          this.dialogVisible = true
          this.dialogOptions = {
             '700px',
            title: '修改功能',
            saveBtn: '提交'
          }
          this.dialogContentComponent = () =>
            import('@/components/dialog/zzqx-gn/edit-gn.vue')
        },
        deleteFun(node, data) {
          if (!this.chooseData.length) {
            this.$message({
              message: '请选择数据进行操作',
              type: 'warning'
            })
            return
          }
          var prame = []
          this.chooseData.forEach((element) => {
            prame.push({ dxid: element.dxid })
          })
          this.$confirm('是否确定删除该数据?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            center: true
          })
            .then(() => {
              // 删除
              this.api.post(
                this,
                'delete_gn',
                () => {
                  this.$message.success('删除成功')
                  this.dialogVisible = false // 关闭弹窗
                  this.reload({ dxid: this.chooseId }) // 刷新数据
                },
                prame
              )
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '已取消删除'
              })
            })
        },
        handleitem(val) {
          this.$refs.dataGrid.load({ dxid: val.dxid })
        }
      }
    }
    </script>
    <style lang="scss">
    .general-wrap .rightdrig .gr-datagrid-notitle {
      border-bottom: none;
    }
    .gr-datagrid .gr-tag ::v-deep .el-collapse {
      margin: 0 22px 0 18px !important;
    }
    .leftshuxing {
       300px;
      background: #fff;
      margin: 3px 0 3px 5px;
    }
    .rightdrig {
      overflow: hidden;
      flex: 1;
      .gr-datagrid-notitle {
        height: 90%;
        height: calc(100% - 45px);
        background: #fff;
        margin: 3px 0 3px 5px;
        padding: 0 17px;
        border-bottom: solid 1px #d9d9d9;
        .gr-tag {
          line-height: 46px;
          .data-title {
            background: url('~@/assets/data-title.png') no-repeat center left;
            padding-left: 20px;
            font-size: 14px;
          }
          .el-button--primary {
            color: #fff;
            background: #409eff;
            border-color: #409eff;
            margin-left: 15px;
          }
          .el-button--primary:hover {
            background-color: rgb(193, 218, 243);
            border-color: rgb(121, 184, 248);
            color: #000;
          }
        }
      }
    }
    </style>
    
    

    目录

    
    <template>
    
      <ul :style="{height:heightstyle + 'px'}">
    
        <li v-for="(val, ind) of list" :key=ind @click="handlecli(val, ind)" :class="[ind == itemindex ? 'chose':null]">
          <span>{{val.mc}}</span>
        </li>
      </ul>
    </template>
    <script>
    export default {
      data() {
        return {
          heightstyle: 500,
          list: null,
          itemindex: 0
        }
      },
      created() {
        this.heightstyle = document.body.clientHeight - 100
        this.load()
      },
      methods: {
        handlecli(val, ind) {
          this.$emit('cliitem', val)
          this.$store.state.chooseId = this.list[ind].dxid
          this.itemindex = ind
        },
        load(param) {
          this.api.get(this, 'system_left_zxt', this.result, param)
        },
        result(data) {
          this.list = data
          this.$store.state.chooseId = this.list[0].dxid
          this.handlecli(this.list[0], 0)
        }
      }
    }
    </script>
    <style scoped lang="scss">
    ul {
      padding: 10px;
      overflow-y: auto;
      box-sizing: border-box;
      margin-top: 3px;
    }
    li {
      padding: 2px 4px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      cursor: pointer;
    }
    li:hover {
      color: #3083f2;
      background-color: #f5f7fa;
    }
    li.chose {
      color: #3083f2;
      background-color: #f5f7fa;
    }
    </style>
    
    

    表格

    <template>
    
      <div>
        <search @searchSubmit="searchSubmit"></search>  // 放在父页面一样
        <div class="gr-tag">
          <span class="data-title">功能管理</span>
          <el-button type="primary" size="mini" @click="addFun">增加</el-button>
          <el-button type="success" size="mini" @click="editFun">编辑</el-button>
          <el-button type="info" size="mini" @click="jiny" v-if="chooseData[0] && chooseData[0].sfjy === '1'">禁用</el-button>
          <el-button type="warning" size="mini" @click="kaiq" v-else>开启</el-button>
          <el-button type="danger" size="mini" @click="deleteFun">删除</el-button>
        </div>
        <el-table @selection-change="changeCheckbox"  ref="multipleTable" :data="tableData" stripe borders style="100%" :height="height" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" row-key="dxid">
          <el-table-column type="selection" width="42"/>
          <el-table-column prop="mc" label="功能名称" width="230"></el-table-column>
          <el-table-column prop="icon" show-overflow-tooltip  label="ICON">
            <template slot-scope="scope">
              {{scope.row.icon || '无'}}
            </template>
          </el-table-column>
          <el-table-column :formatter="changeLx" prop="lx" label="类型">
          </el-table-column>
          <el-table-column prop="sfjy" label="是否禁用">
            <template slot-scope="scope" >
              <span :style="{ color: scope.row.sfjy == 0 ? 'red' : '' }">
                {{scope.row.sfjy == 0 ? '是' : '否'}}
              </span>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="ms" label="描述">
            <template slot-scope="scope">
              {{scope.row.ms || '无'}}
            </template>
          </el-table-column>
          <el-table-column prop="cjsj" label="创建时间" show-overflow-tooltip></el-table-column>
        </el-table>
      </div>
    </template>
    <script>
    import index from './index.js'
    export default index
    </script>
    <style lang="scss">
    .el-checkbox__input.is-checked .el-checkbox__inner {
      background-color: #409eff;
      border-color: #409eff;
    }
    .el-checkbox__input.is-indeterminate .el-checkbox__inner {
      background-color: #409eff;
      border-color: #409eff;
    }
    .el-table td {
      padding: 8px 0;
    }
    .el-tooltip__popper {
      font-size: 14px;
      max- 50%;
    }
    </style>
    
    

    表格逻辑

    import { mapState } from 'vuex'
    export default {
    
      data() {
        return {
          dxid: '',
          currentPage: 1,
          pagePize: 15,
          tableData: [],
          height: 500,
          total: 0,
          canshu: {},
          currentRow: []
        }
      },
      computed: mapState(['chooseId', 'chooseData']),
      created() {
        this.height = document.body.clientHeight - 110
      },
      methods: {
        changeCheckbox(val) {
          this.$store.state.chooseData = val
        },
        addFun() {
          this.$emit('addFun')
        },
        editFun() {
          this.$emit('editFun')
        },
        kaiq() {
          if (this.chooseData.length !== 1) {
            this.$message.warning('请选择一个功能菜单后操作')
            return
          }
          this.chooseData[0].sfjy = '1'
          this.api.post(this, 'edit_gn', () => {
            this.$message.success('开启成功')
          }, this.chooseData[0])
        },
        jiny() {
          if (this.chooseData.length !== 1) {
            this.$message.warning('请选择一个功能菜单后操作')
            return
          }
          this.chooseData[0].sfjy = '0'
          this.api.post(this, 'edit_gn', () => {
            this.$message.success('已禁用')
          }, this.chooseData[0])
        },
        deleteFun() {
          this.$emit('deleteFun')
        },
        load(param) {
          this.dxid = param.dxid
          this.$store.state.chooseData = []
          this.api.get(this, 'system_zxt_menu', this.result, param)
        },
        result(data) {
          this.total = data.length
          this.tableData = this.gettree(data)
        },
        gettree(data) {
          var dataList = data
          function fn(data, sjdxid) {
            var result = []
            var temp
            for (var i in data) {
              if (data[i].sjdxid === sjdxid) {
                result.push(data[i])
                temp = fn(data, data[i].dxid)
                if (temp.length > 0) {
                  data[i].children = temp
                }
              }
            }
            return result
          }
          return fn(dataList, this.dxid)
        },
        changeLx(row) {
          switch (row.lx) {
            case '1':
              return '平台'
            case '2':
              return '外链'
            case '3':
              return '弹窗'
            case '4':
              return 'iframe'
            case '5':
              return 'map点位绘制'
            case '6':
              return '服务调用'
            case '7':
              return 'map线、面绘制'
            case '8':
              return 'map面绘制'
            case '9':
              return 'map ICON替换'
          }
        },
        indexMethod(index) {
          return this.pageInfo.limit * (this.pageInfo.start - 1) + 1 + index
        }
      }
    }
    
    

    import组件内容(分了新增和编辑操作,看情况可合并)

    新增操作(两个文件差别在逻辑不同)

    <template>
    
      <el-form :model="dataForm" label-width="110px" ref="dataForm" size="mini" :rules="rules" style="margin-right: 20px" :inline="true" label-position="right">
        <el-form-item label="功能名称" prop="mc">
          <el-input v-model="dataForm.mc" style="200px"></el-input>
        </el-form-item>
        <el-form-item label="访问路径" prop="fwlj">
          <el-input v-model="dataForm.fwlj" style="200px"></el-input>
        </el-form-item>
        <el-form-item label="是否管理" prop="mrxs">
          <el-select filterable v-model="dataForm.mrxs" placeholder="是否管理" style="200px">
            <el-option label="是" value="1"></el-option>
            <el-option label="否" value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="icon" prop="icon">
          <el-input v-model="dataForm.ICON" style="200px"></el-input>
        </el-form-item>
        <el-form-item label="描述" prop="ms">
          <el-input v-model="dataForm.ms" style="200px"></el-input>
        </el-form-item>
        <el-form-item label="显示顺序" prop="xssx">
          <el-input v-model="dataForm.xssx" style="200px"></el-input>
        </el-form-item>
        <el-form-item label="类型" prop="lx">
          <el-select v-model="dataForm.lx" placeholder="选择类型" style="200px">
            <el-option v-for="li in lxlist" :key="li.id" :label="li.label" :value="li.value"></el-option>
          </el-select>
        </el-form-item>
        <!-- <el-form-item label="是否禁用" prop="sfjy">
          <el-select filterable v-model="dataForm.sfjy" placeholder="是否禁用" style="200px">
            <el-option label="是" value="1"></el-option>
            <el-option label="否" value="0"></el-option>
          </el-select>
        </el-form-item> -->
        <el-form-item label="上级对象" prop="sjdxid">
          <el-select v-model="dataForm.sjdxid" filterable placeholder="选择上级对象" style="200px">
            <el-option label="无上级菜单" value="" key=""></el-option>
            <el-option :label="item.mc" :value="item.dxid" v-for="(item,index) in funList" :key="index"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </template>
    <script>
    import { mapState } from 'vuex'
    export default {
      data() {
        return {
          funList: [],
          dataForm: {
            mc: '',
            fwlj: '',
            mrxs: '',
            ICON: '',
            sfjy: '0',
            lx: '',
            xssx: '',
            sjc: '{datetime}',
            cjsj: '{datetime}',
            dxid: '{uuid}',
            sjdxid: ''
          },
          lxlist: [
            { label: '平台', value: '1' },
            { label: '外链', value: '2' },
            { label: '弹窗', value: '3' },
            { label: 'iframe', value: '4' },
            { label: 'map点位绘制', value: '5' },
            { label: 'map服务调用', value: '6' },
            { label: 'map线、面绘制', value: '7' },
            { label: 'map面绘制', value: '8' },
            { label: 'map ICON替换', value: '9' }
          ],
          rules: {
            mrxs: [
              { required: true, message: '请选择是否默认显示', trigger: 'blur' }
            ],
            mc: [
              { required: true, message: '请输入功能名称', trigger: 'blur' }
            ],
            fwlj: [
              { required: true, message: '请输入访问路径', trigger: 'blur' }
            ],
            xssx: [
              { required: true, message: '请输入显示顺序', trigger: 'blur' }
            ],
            lx: [
              { required: true, message: '请输入类型', trigger: 'blur' }
            ],
            sfjy: [
              { required: true, message: '请选择是否禁用', trigger: 'blur' }
            ]
          }
        }
      },
      computed: mapState(['chooseData', 'chooseId']),
      methods: {
        result(data) {
          this.funList = data
        },
        submitForm(that) {
          this.$refs.dataForm.validate(valid => {
            if (!valid) {
              return false
            }
            this.api.post(this, 'add_gn', () => {
              this.$message.success('新增成功')
              that.modalClose() // 关闭弹窗
              that.$parent.reload({ dxid: this.chooseId })
            }, this.dataForm)
          })
        },
        resetForm() {
          this.$refs.dataForm.resetFields()
        }
      },
      created() {
        for (const key in this.data) {
          this.dataForm[key] = this.data[key]
        }
        this.api.get(this, 'gn_list', this.result)
        if (this.chooseData.length) {
          this.dataForm.sjdxid = this.chooseData[0].dxid
        } else {
          this.dataForm.sjdxid = this.chooseId
        }
      }
    
    // ###编辑操作(不同于编辑的地方)
    // methods: {
    
      //   submitForm(that) {
      //     this.$refs.dataForm.validate(valid => {
      //       if (!valid) {
      //         return false
      //       }
      //       this.api.post(this, 'edit_gn', () => {
      //         this.$message.success('更新成功')
      //         that.modalClose() // 关闭弹窗
      //         that.$parent.reload({ dxid: this.chooseId })
      //       }, this.dataForm)
      //     })
      //   }
      // },
      // created() {
      //   this.dataForm = Object.assign({ }, this.chooseData[0])
      //   this.api.get(this, 'gn_list', this.result)
      // 
    
    }
    </script>
    
    

    查询条件

    index.vue

    <template>
    
      <el-form :inline="true" :model="formInline" size="mini" class="gr-form-search" @submit.native.prevent>
        <el-form-item label="用户名">
          <el-input clearable v-model="formInline.userName" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item label="开始时间" prop="startTime">
          <el-date-picker v-model="formInline.startTime" type="datetime" format="yyyy-MM-dd HH:mm" value-format="yyyy-MM-dd HH:mm" style="200px" placeholder="选择日期时间">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="结束时间" prop="endTime">
          <el-date-picker v-model="formInline.endTime" type="datetime" format="yyyy-MM-dd HH:mm" value-format="yyyy-MM-dd HH:mm" style="200px" placeholder="选择日期时间">
          </el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </template>
    <script>
    import index from './index.js'
    export default index
    </script>
    

    index.js

    export default {
      data() {
        return {
          formInline: {
            userName: '',
            startTime: '',
            endTime: ''
    
          }
        }
      },
      mounted() {
        this.onSubmit()
      },
      methods: {
        onSubmit() {
          var data = Object.assign({}, this.formInline)
          this.$emit('searchSubmit', data)
        }
      }
    }
    

    增加查询组件,父页面相对应增加方法

       load(param) {
          this.api.get(this, 'getsslist', this.result, param)
        },
        searchSubmit(data = this.canshu) {
          if (data === undefined) data = {}
          data.pageSize = this.pagePize
          data.pageNum = this.currentPage
          this.canshu = data
          this.loading = true
          this.load(data)
        },
        searchResult(data) {
          this.load(data)
        
    }
    

    弹窗组成文件含index.vue、index.js、directives.js

    index.vue

    
    <template>
    
      <el-dialog :title="dialogOptions.title" :visible.sync="dialogVisible" :width="dialogOptions.width" :before-close="handleClose" v-dialogDrag>
    
        <component ref="childFunx" :is="dialogContentComponent" :data="data" :typeSelectData="typeSelectData" :roomSelectData="roomSelectData" :day="day"></component>
        <span slot="footer" class="dialog-footer" v-if="show">
          <el-button @click="resetForm()">重置</el-button>
          <el-button type="primary" @click="submitForm()">{{dialogOptions.saveBtn}}</el-button>
          <el-button type="danger" v-if="showDel" @click="deleteDate">删除</el-button>
        </span>
      </el-dialog>
    </template>
    <script>
    import grDialog from './index.js'
    export default grDialog
    </script>
    <style  lang="scss">
    .el-dialog {
      border-radius: 8px;
      .el-dialog__header {
        border-radius: 8px 8px 0 0;
        background: #4991f0;
        padding: 8px 15px;
        .el-dialog__headerbtn {
          top: 12px;
        }
        .el-dialog__title {
          font-size: 18px;
          color: #fff;
        }
        .el-icon-close:before {
          color: #fff;
        }
      }
      .el-dialog__body {
        padding: 25px 15px 5px 15px;
      }
      .el-dialog__footer {
        text-align: center;
        padding-top: 0;
      }
      .el-button--primary {
        color: #fff;
        background-color: #409eff;
        border-color: #409eff;
      }
      .el-button:hover {
        background-color: rgb(193, 218, 243);
        border-color: rgb(121, 184, 248);
        color: #000;
      }
    }
    .el-message-box {
      .el-button--primary,
      .el-button--primary:active {
        color: #fff;
        background: #409eff;
        border-color: #409eff;
      }
      .el-button:hover {
        background-color: rgb(193, 218, 243);
        border-color: rgb(121, 184, 248);
        color: #000;
      }
    }
    </style>
    
    

    index.js

    import './directives.js'
    
    export default {
      props: {
        dialogVisible: {
          type: Boolean,
          default: false
        },
        modal: {
          type: Boolean,
          default: true
        },
        dialogOptions: {
          type: Object,
          default: { title: '', saveBtn: '保存',  '30%', isre: false }
        },
        data: { type: [Object, Array], default: () => { } },
        dialogContentComponent: { type: Function },
        show: { type: Boolean, default: true },
        showDel: { type: Boolean, default: false },
        typeSelectData: { type: Array, default: () => [] },
        roomSelectData: { type: Array, default: () => [] },
        day: { type: String, default: '' }
      },
      methods: {
        resetForm() {
          this.$refs.childFunx.resetForm()
        },
        submitForm() {
          this.$refs.childFunx.submitForm(this)
        },
        deleteDate() {
          this.$refs.childFunx.deleteDate(this)
        },
        modalClose() {
          this.$emit('update:dialogVisible', false) // 直接修改父组件的属性
        },
        reLoad() {
          this.$parent.reload()
        },
        handleClose(done) {
          this.$confirm('确认关闭?')
            .then(_ => {
              this.modalClose()
            })
            .catch(_ => { })
        }
      }
    }
    
    

    directives.js(一个拖动功能)

    import Vue from 'vue'
    
    Vue.directive('dialogDrag', {
      bind(el, binding, vnode, oldVnode) {
        const dialogHeaderEl = el.querySelector('.el-dialog__header')
        const dragDom = el.querySelector('.el-dialog')
        dialogHeaderEl.style.cursor = 'move'
    
        // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
        const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
    
        dialogHeaderEl.onmousedown = (e) => {
          // 鼠标按下,计算当前元素距离可视区的距离
          const disX = e.clientX - dialogHeaderEl.offsetLeft
          const disY = e.clientY - dialogHeaderEl.offsetTop
    
          // 获取到的值带px 正则匹配替换
          let styL, styT
    
          // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
          if (sty.left.includes('%')) {
            styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
            styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
          } else {
            styL = +sty.left.replace(/px/g, '')
            styT = +sty.top.replace(/px/g, '')
          }
    
          document.onmousemove = function(e) {
            // 通过事件委托,计算移动的距离
            const l = e.clientX - disX
            const t = e.clientY - disY
    
            // 移动当前元素
            dragDom.style.left = `${l + styL}px`
            dragDom.style.top = `${t + styT}px`
    
            // 将此时的位置传出去
            // binding.value({x:e.pageX,y:e.pageY})
          }
    
          document.onmouseup = function(e) {
            document.onmousemove = null
            document.onmouseup = null
          }
        }
      }
    })
    
    // v-dialogDragWidth: 弹窗宽度拖大 拖小
    Vue.directive('dialogDragWidth', {
      bind(el, binding, vnode, oldVnode) {
        const dragDom = binding.value.$el.querySelector('.el-dialog')
    
        el.onmousedown = (e) => {
          // 鼠标按下,计算当前元素距离可视区的距离
          const disX = e.clientX - el.offsetLeft
    
          document.onmousemove = function(e) {
            e.preventDefault() // 移动时禁用默认事件
    
            // 通过事件委托,计算移动的距离
            const l = e.clientX - disX
            dragDom.style.width = `${l}px`
          }
    
          document.onmouseup = function(e) {
            document.onmousemove = null
            document.onmouseup = null
          }
        }
      }
    }
    )
    
  • 相关阅读:
    mysql日志
    MYSQL-事务中的锁与隔离级别
    MYSQL事务的日志
    Innodb核心特性-事务
    Innodb存储引擎-表空间介绍
    innodb存储引擎简介
    MYSQL之存储引擎
    MYSQL之索引配置方法分类
    MYSQL之索引算法分类
    MYSQL之select的高级用法
  • 原文地址:https://www.cnblogs.com/wwj007/p/14385480.html
Copyright © 2011-2022 走看看