欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

antd checkbox 默认选中_antd 开发的一些坑(一)

发布时间:2023/11/27 39 豆豆
生活随笔 收集整理的这篇文章主要介绍了 antd checkbox 默认选中_antd 开发的一些坑(一) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

使用antd以来,有些东西总是现用现查,现总结一波,以提升开发效率

一:表格下钻及默认展开一级

{treeData && treeData.length > 0 ? (<TablerowKey={record => `${record.deptCode}`}loading={tableLoading}defaultExpandedRowKeys={treeData.map(item => item.deptCode)} columns={this.state.columns}dataSource={treeData}pagination={false}onExpand={this.handldOnExpand}scroll={{ y: 450 }}/>) : (<div style={{ minHeight: 450, textAlign: 'center', boxSizing: 'border-box', paddingTop: '200px' }}><Spin /></div>)}解释一: modal里面的table,为什么要判断 treeData.length>0? 再展示table? 因为这个treedata的值是在state: treeData:[],上定义的,接口返回再赋值,如果不判断的话,组件初次render之后,
就会执行defaultExpandedRowKeys={treeData.map(item => item.deptCode)} ,等数据回来,第一级数据就不会展开了,因为初次识别的是一个空数组,所以,这里判断
length>0才展示就会默认展示返回的一级数据了。解释二:根据部门的deptCodePaths值判断的onExpand={this.handldOnExpand}是按照部门数下钻的,所以,这里有三个函数比较重要,注意理解:// 展开加号handldOnExpand = async (expanded, record) => {if (!expanded || record.children.length) returnlet {treeData,} = this.statelet res = await this.getTableChildrenData({ deptIsUserChoose: false, deptCodePaths: [record.deptCodePath] })let node = this.findTreeNode(record.deptCode, treeData)node.children = resthis.setState({ tableLoading: false })}//根据传入的nodeId查找到节点findTreeNode = (nodeId, treeList) => {let node = nullif (!treeList || treeList === []) {return []}for (const value of treeList) {if (+value.deptCode === +nodeId) {node = valuereturn node} else if (Array.isArray(value.children)) {node = this.findTreeNode(nodeId, value.children)if (node) return node}}}// 得到子节点getTableChildrenData({ deptIsUserChoose = false, deptCodePaths = [] }) {let {tableLoading,} = this.stateif (tableLoading) returnthis.setState({ tableLoading: true })return  // this.props.enpsStore.getEnpsSituationDetail({ 掉接口// ...this.props.searchParams,// deptIsUserChoose,//  deptCodePaths// }).then(res => res)}

二: select多选一行显示可滑动:

注意:如果只是这一个需要这样的话,那么就需要在外面套一个盒子,进行局部更改,否则,更改的就是全局的了

// treeSelect 
.ant-select-selection--multiple{.ant-select-selection__rendered {display: flex;overflow: auto;>li {flex-shrink: 0;}&::-webkit-scrollbar {display: none;}}
}// 多选select.ant-select-selection--multiple {width: 100%;.ant-select-selection__rendered {height: 30px;ul {display: flex;width: 100%;overflow: auto;&::-webkit-scrollbar {display: none;}>li {flex-shrink: 0;}}}}如果遇到选中抖动的情况,有可能是line-height影响的,可以加上:(外层封一个盒子)
.chart_statement { // 外层盒子,免得干扰了全局.ant-form-item-label {line-height: 31px !important;}.ant-form-item-control {line-height: 25px !important}
}

三:upload手动上传

即:不是及时上传,是先保存文件,然后,点击提交按钮之后再上传,注意文件的类型和写法:

需要转化成formdata格式上传:

this.state = {buttonLoading: false,fileList: [],disableBtn: false,};handleSubmit = (e) => {e.preventDefault();this.props.form.validateFields((err, values) => {if (!err) {const { fileList } = this.state;// console.log('filelist----', fileList[0]);const formData = new FormData();fileList.forEach((file) => {formData.append('file', file);});// console.log('file----', formData.get('file'))this.props.appContext.adminActions.uploadBillFile({file: formData,periodId: values.name,templateId: values.belong,}).then((res) => {if (res.msg === '成功') {message.success('上传成功');} else {message.error(`${res.msg}`);}})this.setState({fileList: [],disableBtn: false,})this.onCancel('reload')}});}render: (){const props = {onRemove: (file) => {this.setState((state) => {const index = state.fileList.indexOf(file);const newFileList = state.fileList.slice();newFileList.splice(index, 1);return {fileList: newFileList,};}, () => {if (this.state.fileList < 1) {this.setState({disableBtn: false,})}});},beforeUpload: (file) => {this.setState(state => ({fileList: [...state.fileList, file],}), () => {if (this.state.fileList.length >= 1) {this.setState({disableBtn: true, // 如果上传的有一个文件了,就不让上传,用户删除当前文件之后放可上传})}});return false;},fileList,};}// 组件显示
<Upload{...props}accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"><Button style={{ width: '400px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '14px' }} disabled={this.state.disableBtn}><Icon type="cloud-upload" style={{ fontSize: '16px' }} />请上传文件</Button>
</Upload>// upload上没有action,是先转化成流文件,再传给后端的// 这里有一个坑,就是我封装的request自定义了请求头,导致文件上传不对,所以,修改之后的request是:
async function uploadRequest(url, options = {}) {const response = await fetch(url, Object.assign({headers: {'x-kylin-proxy-with': 'apirequest', // 用于麒麟 未登录接口不会302而是返回接口真实数据},credentials: 'include',responseType: 'arraybuffer',}, options));const data = await response.json();if (data) {return data;}
}export default uploadRequest;headers看下是否需要带,不要自定义'Content-Type': 'application/json;charset=UTF-8',注意了

四:对于顶部搜索的栅格布局,常用的是这种类型

 const formItemLayout = {labelCol: {xs: { span: 4 },md: { span: 6 },},wrapperCol: {xs: { span: 20 },md: { span: 18 },},};<Row type="flex" justify="start" align="top"><Col span={8}><FormItem {...formItemLayout} label="费用类型">{getFieldDecorator('expenseId')(<Select allowClear style={{ width: '100%' }} placeholder="请选择费用类型" onChange={this.selectChange}>{this.state.selectList.length > 0 ? this.state.selectList.map(item => (<Option value={item.id} key={item.id} style={{ fontSize: '14px' }}>{item.expenseName}</Option>)) : ''}</Select>)}</FormItem></Col><Col span={8} push={2}><FormItem {...formItemLayout} label="模板名称">{getFieldDecorator('templateName')(<Input allowClear onChange={this.inputChange} placeholder="请输入模板名称" />)}</FormItem></Col><Col span={4} push={4}><div style={{ marginTop: 5 }}><Button onClick={this.handleReset} shape="round" style={{ fontSize: '14px' }}>重置</Button></div></Col></Row>

五: table定栏滑动,scrollX算法

有时候,表格比较宽的时候,可能需要定最左栏,或者几栏,其余可以滑动的效果,坑就是这个scrollX的值是动态算出来的,不是直接写死的值,如果直接写死的,那么,到了其他屏幕上就会有空隙的情况;

render: (){const columns = [{title: '费用类型',dataIndex: 'expenseName',width: '500px',}, {title: '模板名称',dataIndex: 'name',width: '240px',}, {title: '更新人',dataIndex: 'updater',width: '240px',}, {title: '更新时间',width: '300px',render: record => (<span>{this.time(record.updateAt)}</span>),}]let scrollX = columns.reduce((sum, item, idx) => {// console.log('sum, item, idx--->',sum, item, idx)if (idx !== 0) {item.width = item.title.split('').length * 15 < 240? 240: item.title.split('').length * 15}return sum + item.width
}, 0)// 如果有某一列小于240,也按照240展示了,这样算出来的scrollX就是动态的了,<TablerowKey={record => `${record.deptCode}`}loading={tableLoading}defaultExpandedRowKeys={treeData.map(item => item.deptCode)}columns={columns}dataSource={treeData}pagination={false}onExpand={this.handldOnExpand}scroll={{ y: 450, x: scrollX}}/>
}

六:下载流文件的坑:

后端返回的excal前端下载一般有两种方式,一种是返回路径:window.open打开下载,另一种是后端直接返回一种流文件,坑是本来我用的是fetch请求的,但是,headers里面不仅需要用get()

方法取出来,请求头也做了拦截转化,所以,这种情况下,还是用axios比较好,省去了一堆bug,在这点上,axios优于fetch

server里面:import axios from 'axios';
export const downloadSummaryData = data => axios('/sst/downloadSummaryData', { // 下载method: 'POST', // 注意这里是post还是get,如果是get,就要在路径上拼接参数了data,responseType: 'blob', // 转化成流文件
});页面上:// 下载明细downLoadDetail = (record) => {this.props.appContext.adminActions.downloadDetail({ // 参数expenseId: record.expenseId}).then((res) => {const contentType = res.headers['content-type'];const disposition = res.headers['content-disposition'];const fileName = decodeURI(disposition.substring(disposition.indexOf('filename=') + 9, disposition.length));// console.log('fileName---', fileName, res);const blob = new Blob([res.data], { type: contentType });const link = document.createElement('a');link.href = window.URL.createObjectURL(blob);link.download = fileName;link.click();link.remove();});}

axios拿到的流文件信息

总结

以上是生活随笔为你收集整理的antd checkbox 默认选中_antd 开发的一些坑(一)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。