基于vue2 + Ant Design 封装input(输入)下拉Table表格

封装 AInputTable 组件
<!--下拉Table-->
<template><div class="input-select-table" ref="inputTableRef"  v-clickoutside="handleHide"><div class="input-select-table-input" @click="disabled?this:handleShow()"><a-inputv-model="showValue":disabled="disabled"class="select-table-input":placeholder="placeholder"@change="inputValueChange"><a-icon type="bars" style="color: rgba(0,0,0,.45)" slot="suffix" /></a-input></div><div v-bind:class="getTableVisible" :style="tableDivStyle()" ref="tDivTableList"><t-tableref="tTableList":columns="tableColumn":dataSource="dataSource":tableConfig="tableConfig":tableMethods="tableMethods"></t-table></div></div>
</template><script>
import { getAction } from "@/api/manage";
import { deepClone, filterObj } from '@/utils/util';
import debounce from 'lodash/debounce'
import tTable from '@/components/content/defaultTable'const clickoutside = {// 初始化指令bind(el, binding, vnode) {function documentHandler(e) {// 这里判断点击的元素是否是本身,是本身,则返回if (el.contains(e.target)) {return false}// 判断指令中是否绑定了函数if (binding.expression) {// 如果绑定了函数 则调用那个函数,此处binding.value就是handleHide方法binding.value(e)}}// 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听el.__vueClickOutside__ = documentHandler;document.addEventListener('click', documentHandler)},update() {},unbind(el, binding) {// 解除事件监听document.removeEventListener('click', el.__vueClickOutside__);delete el.__vueClickOutside__}
};export default {name: 'AInputTable',props: {placeholder: {type: String,required: false,default: ''},disabled: {type: Boolean,required: false,default: false,},url: {type: String,required: false,default: ''},columns: {type: Array,required: false,default: () => [],},value: {type: String,required: false,default: '',},saveLabel: {type: String,required: false,default: 'id',},showLabel: {type: String,required: false,default: 'name',},sorter: {type: Object,required: false,default: ()=>{},},queryParams: {type: Object,required: false,default: ()=>{},},superQueryParams: {type: String,required: false,default: '',},pageSize: {type: Number,required: false,default: 10,},rowKey: {type: String,required: false,default: "id",},scroll: {type: Object,required: false,default: function () {return { x:true, y: 300 }},},},directives: {clickoutside},components: {tTable},data() {return {tableVisible: false,//----- new -----dataSource: [],/* 分页参数 */ipagination: {current: 1,pageSize: this.pageSize,pageSizeOptions: ['5','10','15','20','30'],showTotal: (total, range) => {return range[0] + "-" + range[1] + " 共" + total + "条"},showSizeChanger: true,total: 0},isorter:  this.sorter,/* 排序参数 */showValue:'',//展示值saveValue:'',//保存值record:{},/* table加载状态 */loading: false,// 存储各个div的stylestyle: {tableDiv:{position: "fixed",// position: "absolute",zIndex: "999",backgroundColor: "#ffffff",border:"#dedede 1px solid",padding: "5"},},tableMethods: {change: this.handleTableChange,},}},created() {},computed: {tableColumn() {let jsonColumns = deepClone(this.columns);return jsonColumns.filter(item => item.dataIndex != 'action')},tableConfig() {return {pagination: this.ipagination,loading: this.loading,rowKey: "id",size:"small",scroll: this.scroll,bordered: true,customRow: this.onCustomRow}},getTableVisible() {if (this.tableVisible) {return 'showTable';} else {return 'hideTable';}},},watch: {value: {immediate: true,handler(val) {if (val) {this.saveValue = val;this.queryShowValueBySaveValue();} else {this.saveValue = '';this.showValue = '';this.record = {};this.$emit('getRecord',{});this.loadData(1);}}},},methods: {loadData(arg) {if(!this.url){this.$message.error("AInputTable组件未指定请求url,请设置url属性!")return}//加载数据 若传入参数1则加载第一页的内容if (arg === 1) {this.ipagination.current = 1;}let params = this.getQueryParams();//查询条件getAction(this.url, params).then((res) => {if (res.success) {this.dataSource = res.result.records;this.ipagination.total = res.result.total;}if(res.code===510){this.$message.warning(res.message)}})},getQueryParams() {let superQueryParamsArr = []if(this.superQueryParams) {superQueryParamsArr = JSON.parse(this.superQueryParams)}if(this.showValue) {//对输入文字进行模糊查询let queryParamsModel = {type: 'string', rule: 'like', field: this.showLabel, val: this.showValue}superQueryParamsArr.push(queryParamsModel)}let sqp = {}if(superQueryParamsArr) {sqp['superQueryParams'] = encodeURI(JSON.stringify(superQueryParamsArr))}let param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);param.field = this.getQueryField();param.pageNo = this.ipagination.current;param.pageSize = this.ipagination.pageSize;return filterObj(param);},getQueryField() {//TODO 字段权限控制let str = "id,";this.tableColumn.forEach(function (value) {str += "," + value.dataIndex;});return str;},handleHide() { // 点击除了页面其他地方关闭车型选择this.tableVisible = false;},handleShow() {this.$emit('click', this.saveValue);this.loadData(1);this.tableVisible = true;},onCustomRow(record) {return {props: {},on: {click: () => {this.record = record;this.saveValue = this.record[this.saveLabel];this.showValue = this.record[this.showLabel];this.$emit('select', this.saveValue);this.$emit('input', this.saveValue);this.$emit('change', this.saveValue);this.$emit('getRecord',this.record);this.handleHide();},},};},inputValueChange(e) {this.showValue = e.target.value;this.$emit('inputChange',e.target.value);if(this.showValue === null || this.showValue === undefined || this.showValue === ''){this.clear();}debounce(()=>{this.loadData(1)}, 1000);},getShowValue(){return this.showValue;},getSaveValue(){return this.saveValue;},clear() {this.saveValue = '';this.showValue = '';this.record = {};this.$emit('select', '');this.$emit('input', '');this.$emit('change', '');this.$emit('getRecord',{});this.handleHide();},handleTableChange(pagination, filters, sorter) {//分页、排序、筛选变化时触发//TODO 筛选if (Object.keys(sorter).length > 0) {this.isorter.column = sorter.field;this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"}this.ipagination = pagination;this.loadData();},queryShowValueBySaveValue(page = 1) {let params = this.getQueryParams(); // 查询条件params.pageNo = page; // 设置当前页码params.pageSize = this.ipagination.pageSize; // 设置每页记录数getAction(this.url, params).then((res) => {if (res.success) {this.dataSource = res.result.records;this.ipagination.total = res.result.total;// 在当前页查找目标值let found = false;for (let i = 0; i < this.dataSource.length; i++) {const item = this.dataSource[i];if (item && item[this.saveLabel] == this.saveValue) {this.showValue = item[this.showLabel];this.record = item;this.ipagination.current = page; // 更新当前页码found = true;break;}}if (!found && page * params.pageSize < res.result.total) {// 如果当前页未找到目标值且还有下一页,继续查找下一页this.queryShowValueBySaveValue(page + 1);}} else {this.$message.warning(res.message);}});},//表格div样式tableDivStyle() {let style = Object.assign({}, this.style.tableDiv)let width1 = this.getDivTopLength();let width2 = this.realTrWidth();if(width1>width2){style['width'] = width2+"px";}else {style['width'] = width1+"px";}this.scroll.x = style.width//设置表格div的位置样式this.setTableDivPosition()return style},//设置表格div的位置样式setTableDivPosition() {this.$nextTick(() => {if (this.$refs.inputTableRef && this.$refs.tDivTableList) {let tDivTableList = this.$refs.tDivTableList// 输入框在页面上的位置const inputBox = this.$refs.inputTableRef.getBoundingClientRect();// 视口高度const viewportHeight =window.innerHeight || document.documentElement.clientHeight;// 视口高度 - 输入框元素底距离视顶的高度 = 输入框距离视口下方的高度let inputBoxBottomDistance = viewportHeight - inputBox.bottom;// 表格的高度let selectTableHeight = tDivTableList.offsetHeight + 8;// 如果下方的距离不够表格展示if (inputBoxBottomDistance < selectTableHeight) {tDivTableList.style.top = inputBox.top - selectTableHeight + "px";} else {tDivTableList.style.top = inputBox.top + inputBox.height + "px";}}})},//table 列总宽度realTrWidth() {let calcWidth = 0this.tableColumn.forEach((column, i) => {let { type, width } = column// 隐藏字段不参与计算if (typeof width === 'number') {calcWidth += width} else if (typeof width === 'string') {width = width.replace("px","");calcWidth += Number(width)} else {calcWidth += Number('120')}})return calcWidth},//获取指定第v据屏幕右侧宽度getDivTopLength() {return 600;},},//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型model: {prop: 'value',event: 'input'}
}
</script>
<style scoped lang="less">
.input-select-table {width: 91%;.showTable {display: block;}.hideTable {display: none;}.select-table-input {margin-right: 20px;}/deep/ .ant-spin-container > .ant-table > .ant-table-content > .ant-table-scroll > .ant-table-header {overflow: hidden !important;overflow-y: scroll !important;margin-bottom: 0 !important;}
}
</style>
参数配置
参数类型必填说明
placeholderString输入框未填值展示提示信息
disabledBooleantrue/false 默认false
valueString绑定v-model或是v-decorator后不需要设置
columnsArray表格列的配置描述
urlStringtable 数据源请求地址 查询需返回带分页的数据
sorterObject排序字段及排序方式 { column: this.sorter, order: ‘desc’ }
saveLabelString选中实际保存字段
showLabelString选中输入框展示字段
queryParamsString查询条件
pageSizeString指定每页显示条数
rowKeyString指定rowKey 默认id 没有id时指定
scrollString设置显示Table高度限制,超出指定高度 滚动展示
superQueryParamsString高级查询条件
使用示例
<template><div style="padding: 0 15px"><j-vxe-tablekeep-sourceref="vTable":loading="loading":columns="columns":dataSource="dataSource":maxHeight="400":disabled="formDisabled":toolbar="true":bordered="true"class="model_table":alwaysEdit="true"@valueChange="handleValueChange"><template v-slot:action="props"><a-popconfirm :title="$t('system.confirmDelete') + '?'" @confirm="handleDelete(props)"><a>{{$t('system.delete')}}</a></a-popconfirm></template><template v-slot:productCode="props"><span v-if="formDisabled" >{{props.value}}</span><a-input-tablev-elsev-model="props.value":columns="partColumns":url="partUrl.list":show-label="'partCode'":save-label="'partCode'":super-query-params="superQueryParams"@getRecord="getProductCodeRecord($event, props)"></a-input-table></template></j-vxe-table></div>
</template><script>
import '@/assets/less/TableExpand.less'
import {deleteAction, getAction, httpAction} from '@/api/manage'
import { columns, url, storageQuantityCol } from './config'
import { deepClone } from '@/utils/util'
import AInputTable from '@/components/common/AInputTable'
import { selectPartColumns as partColumns, url as partUrl } from '@/views/psi/psiBasics/psiPart/config/index'
import {ajaxGetDictItems, getDictItemsFromCache} from "@/api/api";export default {name: 'PsiPurchaseDetailList',props: {//表单禁用disabled: {type: Boolean,default: false,required: false},parentModel: {type: Object,default: () => {},required: false}},components: {AInputTable},data() {return {description: '表体页面',dictOptions: {},superFieldList: [],disableMixinCreated: true,dataSource: [],loading: false,// 表头columns,url,storageQuantityCol,partColumns,partUrl,currentRow: {},superQueryParams: JSON.stringify([{field: 'partStatus', rule: 'in', type: 'string', val: '1'}]),}},watch: {},computed: {formDisabled() {return this.disabled},},methods: {//获取列表getDataList(purchaseId) {if(!purchaseId) {return}this.loading = truegetAction(this.url.list, {purchaseId: purchaseId, pageSize: 50}).then(res => {if (res.success) {this.dataSource = res.result.records || res.result}}).finally(() => {this.loading = false})},//产品编号选择getProductCodeRecord(record, props) {this.currentRow = props;//物料确认选择this.selectConfirmOk(record)},//物料确认选择selectConfirmOk(record) {if(this.currentRow.row) {this.currentRow.row.productCode = record.partCodethis.currentRow.row.productName = record.partNamethis.currentRow.row.productId = record.idthis.currentRow.row.spec = record.partSpecthis.currentRow.row.uom = record.partUnitthis.currentRow.row.proDesc = record.partDescthis.currentRow.target.setValues([this.currentRow.row])}},//子表单提交验证submitValidate() {let _this = thisreturn new Promise(function(resolve, reject){_this.$refs.vTable.validateTable().then(errMap => {if (errMap) {resolve(false)} else {const values = _this.$refs.vTable.getTableData()if(!(values && values.length > 0)) {_this.$message.warning("至少有一条明细!")resolve(false)} else {resolve(true)}}})});},getSubData() {return this.$refs.vTable.getTableData()},//删除方法handleDelete(props) {if (!this.url.delete) {this.$message.error('请设置url.delete属性!')return}props.target.removeRows(props.row)let that = thisdeleteAction(that.url.delete, { id: props.rowId }).then(res => {if (res.success) {//重新计算分页问题that.$message.success(res.message)} else {that.$message.warning(res.message)}})},//监听输入值改变handleValueChange(e) {},}
}
</script>

在这里插入图片描述
在这里插入图片描述

参考博客链接:https://blog.csdn.net/weixin_44912745/article/details/125407433

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/387256.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【信创】samba的命令行使用 _ 统信 _ 麒麟 _ 中科方德

原文链接&#xff1a;【信创】samba的命令行使用 | 统信 | 麒麟 | 中科方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在信创终端操作系统上使用Samba命令操作的文章。Samba是一种用于实现文件和打印共享的免费软件&#xff0c;它允许不同操作系统&#xf…

Android studio IDE 使用日志 2024/7/30

Android studio IDE 使用日志 时间:2024/7/30 11:10 配置 安装中文语言包,汉化操作界面:下载地址 根据版本信息下载 设置中选择安装插件,选择压缩包自动安装 项目的文件夹目录结构 .gradle :包含了Gradle构建系统,自动编译工具产生的文件 .idea :包含IDEA&#xff08;‌A…

UDP程序设计

UDP协议概述 UDP&#xff0c;User Datagram Protocol&#xff0c;用户数据报协议&#xff0c;是一个简单的面向数据报(package-oriented)的传输层协议&#xff0c;规范为&#xff1a;RFC 768。 UDP提供数据的不可靠传递&#xff0c;它一旦把应用程序发给网络层的数据发送出去…

设计模式16-代理模式

设计模式16-代理模式 动机定义与结构模式定义结构 代码推导特点应用总结实例说明1. 远程代理2. 虚拟代理3. 保护代理4. 智能引用代理 动机 在面向对象系统中有一些对象由于某种原因比如对象创建的开销很大或者某些操作需要安全控制&#xff0c;或者需要进程外的访问等情况。直…

Java面试八股之Spring如何解决循环依赖

Spring如何解决循环依赖 在Spring框架中&#xff0c;循环依赖问题通常发生在两个或多个Bean相互依赖的情况下。Spring为了解决循环依赖问题&#xff0c;采用了不同的策略&#xff0c;这些策略主要取决于Bean的作用域以及依赖注入的方式。下面是一些关键点&#xff1a; 单例Be…

centos安装python 3.9

centos安装python 3.9 1. 准备工作 安装必要的构建工具和依赖项&#xff1a; sudo yum groupinstall "Development Tools" sudo yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel …

轻量级服务器资源监控平台Beszel

什么是 Beszel &#xff1f; Beszel 是一个轻量级平台&#xff0c;借助 Beszel&#xff0c;可以访问 CPU 和内存使用情况的历史数据&#xff0c;以及 Docker 容器指标&#xff08;例如特定于容器的 CPU 和内存统计信息&#xff09;。还能收到针对潜在问题的可自定义警报通知&am…

【Golang 面试 - 进阶题】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

基于Django与spark的国漫推荐系统

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 近年来&#xff0c;随着互联网的蓬勃发展&#xff0c;企事业单位对信息的管理提…

C#知识|文件与目录操作:对象的创建、保存、读取

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 面向对象编程的特点就是一切皆对象&#xff0c;操作的也是对象&#xff0c;本节学习文件与目录操作中&#xff0c;对象的保存&#xff1b; 以下为学习笔记。 01 对象的特点 ①&#xff1a;对象运行在内存中&#xff…

二刷代码随想录训练营Day 11| 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素、总结

1.逆波兰表达式 题目链接/文章讲解/视频讲解&#xff1a;代码随想录 代码&#xff1a; class Solution { public:int evalRPN(vector<string>& tokens) {stack<long long> st;for(int i 0; i < tokens.size(); i){if(tokens[i] "" || tokens[i…

vue里给img的src绑定数据失效

起因 在v-for遍历数据时想要通过给img的src单向绑定 图片路径时出现问题 解决过程 上网查说是webpack构建时识别不到&#xff0c;直接不单绑数据&#xff0c;写死试试看 解决方案 直接require导入图像文件模块

热门超声波清洗机有哪些?小型超声波清洗机推荐

在繁忙的工作和生活中&#xff0c;许多人常常会因为种种原因忽略日常的小事&#xff0c;比如忘记清洁手表、眼镜、首饰等常用物品。实际上&#xff0c;这些物品表面不仅积累了灰尘和污垢&#xff0c;特别是跟眼部朝夕相处的眼镜&#xff0c;还可能滋生各种致病细菌&#xff0c;…

【数据分享】《内蒙古省统计年鉴》2000-2023

而今天要限时免费分享的数据就是2000-2023年间出版的《内蒙古省统计年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 位于中国北部的内蒙古自治区&#xff0c;以其独特的地理和文化特性&#xff0c;成为中国经济发展的重要组成部…

京东科技集团将在香港发行与港元1:1挂钩的加密货币稳定币

据京东科技集团旗下公司京东币链科技(香港)官网信息&#xff0c;京东稳定币是一种基于公链并与港元(HKD) 1:1挂钩的稳定币&#xff0c;将在公共区块链上发行&#xff0c;其储备由高度流动且可信的资产组成&#xff0c;这些资产安全存放于持牌金融机构的独立账户中&#xff0c;通…

工具(1)—截屏和贴图工具snipaste

演示和写代码文档的时候&#xff0c;总是需要用到截图。在之前的流程里面&#xff0c;一般是打开WX或者QQ&#xff0c;找到截图工具。但是尴尬的是&#xff0c;有时候&#xff0c;微信没登录&#xff0c;而你这个时候就在写文档。为了截个图&#xff0c;还需要启动微信&#xf…

数据透视表(二)

文章目录 导入外部数据源创建数据透视表Query 工具下的数据透视表创建如何统计业绩成交情况创建组利用函数构建辅助列创建组手动创建多样分组创建组区间统计创建组按年月日统计数据透视表的多种统计方法计算字段 导入外部数据源创建数据透视表 点击数据选项卡下数据-获取外部数…

环境搭建-Windows系统搭建Docker

Windows系统搭建Docker 一、系统虚拟化1.1 启用虚拟化2.2 启用Hyper-v并开启虚拟任务 三、安装WSL3.1 检验安装3.2 安装WSL 四、Docker安装4.1 Docker安装包下载4.2 Docker安装4.3 运行docker Desktop 五、Docker配置5.1 打开Docker配置中心5.2 配置Docker国内镜像 六、使用 一…

马斯克的Memphis AI超级计算中心:全球最强AI训练集群的诞生

引言 近期&#xff0c;马斯克宣布其最新的Memphis AI超级计算中心正式启动&#xff0c;这一新闻引发了科技界的广泛关注。该中心配备了10万块液冷H100 GPU&#xff0c;成为全球最强大的AI训练集群。本文将深入探讨Memphis AI超级计算中心的建设过程、技术细节、以及其对未来人…

昇思25天学习打卡营第24天|基于MobileNetv2的垃圾分类案例:从数据准备到导出模型文件

目录 MindSpore 版本配置及相关数据集与预训练权重文件下载 基于 MindSpore 的垃圾分类数据集创建与配置 MobileNetV2 模型的构建与相关类定义 基于 MindSpore 的 MobileNetV2 模型训练与测试代码分析 基于 MobileNetV2 模型的图像推理代码分析 MobileNetV2 模型的构建、加…