我希望创建一个时间表网格。基本上,一个网格可以显示当前星期和您正在从事的项目,例如:https://jsfiddle.net/ho9a8neq/ 如何设置v模型,以便可以将具有相应日期的值正确发送到数据库? 像
[
{date: "jan-1": 8, project: 1},
{date: "jan-2": 10, project: 1},
{date: "jan-3": 10, project: 2}
]
答案 0 :(得分:3)
为了能够在时间轴上收集不同项目的数据并跟踪每个项目的日期,我提出的解决方案包括以下数据结构:
day = ''
week = [day, day, day]
project = [week, week, ...]
为简单起见,它限制了以后增加几周的时间。可以对此进行更改,但是它将需要更多的模型复杂性,而且我认为这不会有助于理解如何将数据绑定到模型。
对于每周,必须有一个保留每天数据的模型,这是通过创建一个空字符串数组来完成的:
week: ['','','','','','','']
每个项目可以包含几个星期:
data: [week, week, week]
用户创建新项目时,必须考虑当前星期复制项目模型:
_.cloneDeep(project(this.weekNum, this.rows.length))
现在,有了数据结构,将视图绑定到它:
<input type="text" style="width: 35px;" v-model="row.data[weekNum][i]">
请参阅摘要以了解所有内容如何联系在一起:
const weekData = () => new Array(7).fill('');
const project = (weekNum, id) => ({
project: "first",
id,
data: Array(weekNum + 1).fill([]).map(weekData)
});
new Vue({
el: "#app",
data: {
weekNum: 0,
rows: [_.cloneDeep(project(0, 0))]
},
methods: {
addProject() {
window.pp = _.cloneDeep(
project(this.weekNum, this.rows.length)
)
this.rows.push(
window.pp
);
},
deleteRow(key) {
this.rows.splice(key, 1);
},
nextWeek() {
this.weekNum++;
this.rows.forEach(_project => {
if (!_project.data[this.weekNum]) {
_project.data.push(weekData());
}
});
},
prevWeek() {
this.weekNum--;
this.rows.forEach(row => {
if (!row.data[this.weekNum]) {
row.data.unshift(weekData());
}
});
},
dates(dateFormat, weekNumber) {
let startOfWeek = moment().startOf('week').add(weekNumber, "week");
const endOfWeek = moment().endOf('week').add(weekNumber, "week");
const days = [];
while (startOfWeek <= endOfWeek) {
days.push(startOfWeek.format(dateFormat))
startOfWeek = startOfWeek.clone().add(1, 'd');
}
return days
},
log() {
const output = _.reduce(this.rows, (result, row) => {
const project = {
project: row.id
};
const startWeek = moment().startOf('week');
const weekDays = [];
row.data.forEach((week, weekIdx) => {
week.forEach((data, dataIdx) => {
if (data === '') return;
weekDays.push({
data,
project: row.id,
day: startWeek.clone().add(weekIdx, 'week').add(dataIdx, 'd').format('MMM D')
});
});
});
return [...result, ...weekDays];
}, []);
console.log(output)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/moment@2.24.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.min.js"></script>
<div id="app">
<!-- for the sake of simplicity limit the date to future weeks -->
<button @click="prevWeek" :disabled="weekNum < 1">Previous week</button>
<button @click="nextWeek">Next week</button>
<button @click="addProject">Add project</button>
<table>
<tr>
<th>Project</th>
<th v-for="(day, i) in dates('MMM D', weekNum)" :key="i">{{day}}</th>
</tr>
<tbody>
<tr v-for="(row, key) in rows" :key="key">
<td>Project {{key}}</td>
<td v-for="(n,i) in dates('YYYY-MM-DD', weekNum)" :key="`${row.id}-${i}`">
<input type="text" style="width: 35px;" v-model="row.data[weekNum][i]">
</td>
<td><button @click="deleteRow(key)">x</button></td>
</tr>
</tbody>
</table>
<button @click="log()">log</button>
</div>