草庐IT

基于element-ui封装下拉表格组件

正一品程序员 2023-11-05 原文

当下拉数据很多时,我们需要封装成一个下拉表格的组件,可以分页,模糊搜索
searchCostItem.vue

<template>
  <div>
    <el-popover v-model="popVisible" width="700" trigger="click" placement="bottom">
      <div>
        <FBATable
          ref="countryTableRef"
          :data="tableData"
          height="300"
          :rowHeader="countryColumns"
          @rowClick="handleRowClick"
        ></FBATable>
        <div class="demo-footer">
          <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="pagination.PageIndex"
            :page-sizes="[5, 10, 20, 50, 100]"
            :page-size="pagination.PageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="pagination.TotalCount"
          >
          </el-pagination>
        </div>
      </div>
      <el-input v-model="keyWords" @input="changeKey" :placeholder="placeholder" slot="reference" :CatId="CatId"> </el-input>
    </el-popover>
  </div>
</template>
<script>
import { delay } from '@/utils/index'
import { wfinFeeItemGetPageList } from '@/api/OverseasWarehouse/Cost'
import FBATable from '@/components/FBATable'
export default {
  props: {
    name: {
      type: String,
      default: ''
    },
    index: {
      type: Number,
      default: () => 0
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    CatId: {
      type: Number
    }
  },
  components: {
    FBATable
  },
  data() {
      return {
      pagination: {
        TotalCount: 0,
        PageIndex: 1,
        PageSize: 10
      },
      tableData: [],
      countryColumns: [
        {
          prop: 'NameCn',
          label: '中文名',
          align: 'center'
        },
        {
          prop: 'NameEn',
          label: '英文名',
          align: 'center'
        },
        {
          prop: 'FeeItemCode',
          label: '费用项编码',
          align: 'center'
        },
        {
          prop: 'FeeItemTypeStr',
          label: '费用类型',
          align: 'center'
        }
      ],
      popVisible: false,
      selected: [],
      timer: null
    }
  },
  created() {},
  computed: {
    keyWords: {
      get() {
        return this.name
      },
      set(val) {
        this.$emit('update:name', val)
      }
    }
  },
  watch: {
    CatId: {
      handler(newVal, oldVal) {
        this.getList(newVal)
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    getList(CatId) {
      const { PageSize, PageIndex } = this.pagination
      wfinFeeItemGetPageList({
        PageSize,
        PageIndex,
        NameCn: this.keyWords,
        CatId: CatId ? CatId : 0
      })
        .then(res => {
          if (res.ErrorCode === 0) {
            this.tableData = res.Body.Items
            this.pagination.TotalCount = res.Body.TotalCount
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
        handleSelectionChange(val) {
      if (val.length >= 2) {
        let arrays = val.splice(0, val.length - 1)
        arrays.forEach(row => {
          this.$refs.countryTableRef.$refs.FBATable.toggleRowSelection(row) //除了当前点击的,其他的全部取消选中
        })
      }
      this.$emit('selectedData', { list: val, index: this.index })
      this.timer = setTimeout(() => {
        this.popVisible = false
      }, 500)
    },
    handleRowClick(val) {
      this.$emit('selectedData', { list: val, index: this.index })
      this.timer = setTimeout(() => {
        this.popVisible = false
      }, 200)
    },
    // 搜索
    changeKey() {
      delay(() => {
        this.pagination.PageIndex = 1
        this.getList()
      }, 200)
    },
    handleSizeChange(val) {
      this.pagination.PageSize = val
      this.getList()
    },
    handleCurrentChange(val) {
      this.pagination.PageIndex = val
      this.getList()
    }
  },
  destroyed() {
    clearTimeout(this.timer)
  }
}
</script>
<style lang="scss" scoped>
.demo-form-inline {
  position: relative;
  margin: 15px 10px;
}
.demo-footer {
  display: flex;
  justify-content: flex-end;
}
.country-footer {
  text-align: center;
  position: relative;
  margin: 10px auto;
}
</style>

delay.js

export const delay = (function() {
  let timer = 0
  return function(callback, ms) {
    clearTimeout(timer)
    timer = setTimeout(callback, ms)
  }
})()

FBATable.vue

<template>
  <div>
    <el-table
      ref="FBATable"
      border
      :data="data"
      :span-method="spanMethod"
      :max-height="height"
      :header-cell-style="
        showHeaderStyle
          ? { background: '#f1f2f7', color: '#333' }
          : { background: 'none' }
      "
      @selection-change="handleSelectionChange"
      @row-click="handleRowClick"
    >
      <el-table-column
        type="selection"
        v-if="showCheckBox"
        width="55"
      ></el-table-column>
      <el-table-column type="index" v-if="showIndex" width="55" label="序号">
      </el-table-column>
      <el-table-column
        v-for="(col, index) in rowHeader"
        :key="index"
        :prop="col.prop"
        :label="col.label"
        :width="col.width"
        :fixed="col.fixed"
        :align="col.align"
      >
        <template slot-scope="scope">
          <ex-slot
            v-if="col.render"
            :render="col.render"
            :row="scope.row"
            :index="scope.$index"
            :column="col"
          >
          </ex-slot>
          <span v-else>
            {{ scope.row[col.prop] }}
          </span>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination-end" v-if="isPagination">
      <el-pagination
        :hide-on-single-page="false"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="PaginationData.currentPage"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="PaginationData.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="PaginationData.total"
      >
      </el-pagination>
    </div>
  </div>
</template>
<script>
// 自定义内容的组件
var exSlot = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null
    }
  },

  render: (h, data) => {
    const params = {
      row: data.props.row,
      index: data.props.index
    }

    if (data.props.column) params.column = data.props.column
    return data.props.render(h, params)
  }
}
export default {
  name: 'FBATable',
  components: {
    'ex-slot': exSlot
  },
  props: {
    // 表格数据
    data: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 表头数据
    rowHeader: {
      type: Array,
      default: () => {
        return []
      }
    },
    showCheckBox: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    showIndex: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    height: {
      type: String,
      default: () => {
        return 'auto'
      }
    },
     spanMethod: {
      type: Function,
      default: () => {
        return ''
      }
    },
    PaginationData: {
      type: Object,
      default: () => ({
        currentPage: 1,
        pageSize: 10,
        total: 0
      })
    },
    isPagination: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    showHeaderStyle: {
      type: Boolean,
      default: () => {
        return true
      }
    }
  },
 methods: {
    handleSelectionChange(val) {
      this.$emit('getSelection', val)
    },
    handleRowClick(row) {
      this.$emit('rowClick', row)
    },
    // 	pageSize 改变时会触发
    handleSizeChange(val) {
      this.$emit('pageSizeChange', val)
    },
    // currentPage 改变时会触发
    handleCurrentChange(val) {
      this.$emit('pageCurrentChange', val)
    }
  }
}
</script>
<style lang="scss" scoped>
	.tableHeader {
	  background: #1890ff;
	}
	.pagination-end {
	  width: 100%;
	  margin-top: 20px;
	  display: flex;
	  justify-content: flex-end;
	}
</style>

在页面中引用

            <SearchCostItem
              v-model="form.FeeItemName"
              :name.sync="form.FeeItemName"
              @selectedData="selectedFeeItem"
              :CatId="form.CatId"
              placeholder="选择费用项"
            />

展示效果

有关基于element-ui封装下拉表格组件的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  3. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  4. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  5. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  6. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  7. ruby - 如何使用 Ruby 将 CSV 文件读入 HTML 表格? - 2

    我正在尝试将一个简单的CSV文件读入HTML表格以在浏览器中显示,但我遇到了麻烦。这就是我正在尝试的:Controller:defshow@csv=CSV.open("file.csv",:headers=>true)end查看:输出:NameStartDateEndDateQuantityPostalCode基本上我只获取标题,而不会读取和呈现CSV正文。 最佳答案 这最终成为最终解决方案:Controller:defshow#OpenaCSVfile,andthenreaditintoaCSV::Tableobjectforda

  8. ruby - 如何使用 Nokogiri 解析纯 HTML 表格? - 2

    我想用Nokogiri解析HTML页面。页面的一部分有一个表,它没有使用任何特定的ID。是否可以提取如下内容:Today,3,455,34Today,1,1300,3664Today,10,100000,3444,Yesterday,3454,5656,3Yesterday,3545,1000,10Yesterday,3411,36223,15来自这个HTML:TodayYesterdayQntySizeLengthLengthSizeQnty345534345456563113003664354510001010100000344434113622315

  9. ruby-on-rails - ActiveAdmin 自定义选择过滤器下拉名称 - 2

    对于用户模型,我有一个过滤器来检查用户的预订状态,该状态由整数值(0、1或2)表示。UserActiveAdmin索引页上的过滤器是通过以下代码实现的:filter:booking_status,as::select然而,这会导致下拉选项为0、1或2。当管理员用户从下拉列表中选择它们时,我更愿意自己将它们命名为“未完成”、“待定”和“已确认”之类的名称。有没有办法在不改变booking_status在模型中的表示方式的情况下做到这一点? 最佳答案 假设booking_status是模型中的枚举字段,您可以使用:过滤器:booking

  10. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

随机推荐