在寫項目時有一個需求是要對表格中的資料根據狀态不同可進行不同的操作,有一種狀态就是需要把該行的資料作為一個總任務,通過點選拆分按鈕打開彈框的形式來進行自定義拆分成若幹個子任務,并且在拆分後可以對每一個子任務進行重新自定義配置設定份數,同僚底部需要顯示任務的總份數,以及配置設定完後還剩餘的份數。大概的效果就是這樣,樣式沒去改,請忽略。。。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmL1gjN4ATN0kDM2ITMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
這裡面遇到了一個問題,就是當子任務設定的份數大于剩餘份數時,子任務還是設定成功了,剩餘份數此時就變成負的了。這顯然不是我想要的效果。我需要當給子任務設定份數的時候,一旦設定份數大于剩餘份數時,就把剩餘的份數全部加給目前設定的子任務,而剩餘份數為0。因為我在watch裡對整個表單的資料進行了監聽,是以就要考慮一個先後的問題,當子任務設定的份數大于剩餘份數時,我需要在剩餘份數變成負數之前,把剩餘份數全部給到目前設定的子任務。想起來Vue中的input事件,測試過input事件會在watch之前觸發。測試結果如下:
于是乎,不妨在input事件中先拿到目前設定的子任務的索引,然後在watch中通過判斷剩餘份數是否小于0,一旦觸發小于0這個條件,便把目前設定的子任務份數強行指派成總分數減去已配置設定的份數,這樣一來,目前設定的子任務份數沒有越界,也拿到了有效最大份數,而剩餘份數剛好為0,同樣沒有越界。ok,說到現在,把代碼大概上一下。
HTML:
<template>
<el-dialog
:visible.sync="showDialog"
title="拆分任務"
class="split"
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="$emit('closeSplit', splitForm)"
>
<el-form :model="splitForm" ref="splitForm">
<el-form-item prop="part" label="将檔案拆分為:">
<el-input v-model="splitForm.part"></el-input>
<el-button type="primary" @click="handleSplit">均分</el-button>
</el-form-item>
<div class="children_task">
<el-form-item
v-for="(item, index) in splitForm.childrenTask"
:label="taskIfo.taskName + '任務' + (index + 1)"
:key="index"
>
設定條數
<el-input v-model="splitForm.childrenTask[index].value" @input="handleInput($event, index)"></el-input>
</el-form-item>
</div>
<el-form-item>
總計{{taskIfo.number}}條,剩餘<span :style="{color:(splitForm.remainNumber !== 0 ? '#ff0000' : '#606266')}">{{splitForm.remainNumber}}條</span>
</el-form-item>
</el-form>
<span slot="footer" class="dialog_footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</span>
</el-dialog>
</template>
JS:
<script>
export default {
data () {
return {
showDialog: this.splitDialog,
splitForm: {
part: '', // 份數
childrenTask: [],
remainNumber: '',
curIndex: 0 // 目前設定條數行索引
},
}
},
props: ['splitDialog', 'taskIfo'],
watch: {
splitDialog (bool) {
this.showDialog = bool
if (bool) {
this.splitForm.remainNumber = this.taskIfo.number
}
},
splitForm: {
handler (val) {
let assignNumber = 0
let remainNumber = 0
if (val.childrenTask.length === 0) {
val.remainNumber = this.taskIfo.number
} else {
val.childrenTask.forEach(item => {
assignNumber += parseInt(item.value)
})
val.remainNumber = (isNaN(this.taskIfo.number - assignNumber)) ? 0 : this.taskIfo.number - assignNumber
}
if (val.remainNumber < 0) {
for (let i = 0; i < this.splitForm.childrenTask.length; i++) {
if (i !== this.curIndex) {
remainNumber += this.splitForm.childrenTask[i].value
}
}
this.splitForm.childrenTask[this.curIndex].value = this.taskIfo.number - remainNumber
}
val.part = val.part.length === 1 ? val.part.replace(/[^1-9]/g, '') : val.part.replace(/\D+/, '')
},
deep: true
}
},
methods: {
handleInput (value, index) {
let val = this.splitForm.childrenTask[index].value
this.splitForm.childrenTask[index].value = Number(val.length === 1 ? val.replace(/[^1-9]/g, '') : val.replace(/\D+/, ''))
this.curIndex = index
},
// 均分
handleSplit () {
this.splitForm.childrenTask = []
let part = this.splitForm.part
let total = this.taskIfo.number
let partNumber = Math.floor(total / part)
for (let i = 0; i < part; i++) {
this.splitForm.childrenTask.splice(0, 0, {value: partNumber})
}
},
handleCancel () {
this.$refs['splitForm'].resetFields()
this.splitForm.childrenTask = []
this.$emit('closeSplit', this.splitForm)
},
handleSubmit () {
this.$refs['splitForm'].validate((valid) => {
if (valid) {
if (this.splitForm.remainNumber === 0) {
this.$emit('confirmSplit', this.splitForm)
} else {
this.showDialog = false
setTimeout(() => {
this.$confirm('任務件數未完全設定,請重新設定件數再拆分。', '拆分', {
showCancelButton: false,
ConfirmButtonText: '知道了'
})
}, 500)
}
this.$refs['splitForm'].resetFields()
this.splitForm.childrenTask = []
}
})
}
}
}
</script>
這裡隻是一個子元件,一些參數要從表格的那個父元件拿過來。這裡需要利用正則做一個限定,輸入第一位時隻能輸入1-9的數字,第一位以後可以輸入0-9的數字,因為用replace時需要字元串的變量,但同時因為後面要進行求和與做差,在限定的外面再強制轉換成number類型的,以防當某一個子任務的份數為0時,剩餘份數顯示NaN。
文筆不是很好,加上上班抽空寫的,有點亂,見諒~
一個正在成長的前端小白~~~