日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

發布時間:2023/11/27 生活经验 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 开发的一些坑(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。