我有一个使用Vuejs动态生成的表。它在呈现为readOnly的单元格中具有输入元素。每个元素都有一个“编辑”按钮,单击后将变为“保存”,并启用该行的输入元素进行编辑。单击保存时,我想捕获输入的新值和先前的值。我将日期字段从原始格式设置为mm/dd/yy
,其格式为2019-10-10T07:00:00Z
,我可以使用momentjs成功格式化日期,但它似乎并不粘滞。输入的值与提醒时的值不同。关于我在做什么错的任何想法?我是否需要重构我的代码以允许我执行此操作,因为必须对每个字段都进行此操作,以便可以访问新值和以前的值。
<div id="app">
<table border=1 width=100%>
<tr>
<td>EDIT</td>
<td v-for="editableKey in editableKeys" :key="editableKey" class="label">{{ editableKey }}</td>
</tr>
<tr v-for="(program, index) in programs">
<td><button v-if="program.isReadOnly" v-on:click="editItem(program)">edit</button> <button @click="saveItem(program)" v-else>save</button></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="program.isReadOnly" v-model="formatDate(program)"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="program.isReadOnly" v-model="program.company"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="program.isReadOnly" v-model="program.funding"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="program.isReadOnly" v-model="program.funded"></td>
<td><select :class="bgColor(program)" type="text" v-bind:data-id="program.id" :disabled="program.isReadOnly" v-model="program.Recruit">
<option>Internal</option>
<option>Recruiting</option>
</select>
<!--<input :class="bgColor(program)" type="text" v-bind:data-id="program.id" :readonly="program.isReadOnly" v-model="program.Recruit">--></td>
<td><input type="text" v-on:change="" v-bind:data-id="program.id" :readonly="program.isReadOnly" v-model="program.program"></td>
</tr>
</table>
</div>
new Vue({
el:"#app",
data: () => ({
programs: [],
editableKeys: ['date', 'company', 'funding', 'funded', 'recruit', 'program'],
}),
created () {
this.getPrograms();
},
methods: {
getPrograms() {
axios.get("https://my-json-server.typicode.com/isogunro/jsondb/Programs").then(response => {
this.programs = response.data.map(program => ({
...program,
isReadOnly: true
}));
}).catch(error => {
console.log(error);
});
},
editItem (program) {
program.isReadOnly = false
},
saveItem (program) {
program.isReadOnly = true
console.log(program)
alert("New Value: "+program.Date)
alert("Previous Value: "+program.Date)
},
bgColor (program) {
return program.funded === program.funding ? 'yellow' : 'white'
},
formatDate(program){
var formatL = moment.localeData().longDateFormat('L');
var format2digitYear = formatL.replace(/YYYY/g,'YY');
return moment(program.Date).format(format2digitYear);
},
updateField(program){
console.log(program)
alert(program)
}
}
})
为清楚起见,这里是pen。感谢您可以提供的任何帮助。
如果您希望它的行为使输入的数据不同于所显示的数据,则必须将输入与数据解耦。
只是完成它v-model
需要分配一个变量,以便输入可以更新其值。现在,您正在使用[[0]无法工作的v-model="formatDate(program)"
,因为传递函数的静态结果无法进行反应。有几种方法可以完成此操作。这是v-model
和事件监听器替换value
请注意,在模板中使用函数进行渲染不是一种好习惯。最好一次执行一次并使用缓存的值,这样就不必重新计算该值]]<input
type="text"
v-bind:data-id="program.id"
:readonly="program.isReadOnly"
:value="formatDate(program)"
@input="updateDate($event, program)"
>
更新方法
editItem (program) {
program.isReadOnly = false
program.tempDate = null; // added tempDate to be set to null initially
},
saveItem (program) {
program.isReadOnly = true
if(program.tempDate !== null) {
// if tempDate is set, update Date
program.Date = program.tempDate;
// and clear tempDate
program.tempDate = null;
}
console.log({...program})
},
// new method to convert value of the input from string to Date (if date passed is valid)
updateDate(e, program ) {
if(new Date(e.target.value).toString() !== 'Invalid Date'){
program.tempDate = new Date(e.target.value)
} else {
program.tempDate = null
}
},
更新
v-model
,只是请注意,此示例不检查日期格式的正确性。function toDDMMYY(date) {
const [y, m, d] = (new Date(date)).toISOString().slice(0, 10).split('-')
return `${d}/${m}/${y%100}`
}
new Vue({
el: "#app",
data() {
return {
test: "hello",
programs: "",
hide: true,
editable: [],
}
},
created: function() {
this.getPrograms();
},
methods: {
getPrograms: function() {
axios.get("https://my-json-server.typicode.com/isogunro/jsondb/Programs").then((response) => {
this.programs = response.data.map(row => ({
...row,
dateFormatted: toDDMMYY(row.Date),
editable: false
}));
})
.catch(function(error) {
console.log(error);
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<div id="app">
<table border=1 width=100%>
<tr>
<td width=10px>EDIT</td>
<td>Date</td>
<td>Program</td>
<td>Company</td>
<td>Funding</td>
<td>Funded</td>
<td>Recruit</td>
</tr>
<tr v-for="program in programs">
<td>
<button v-if="program.editable == false" @click="program.editable = true">edit</button>
<button v-else @click="program.editable = false">save</button>
</td>
<td><input type="text" v-bind:data-id="program.id" :readonly="!program.editable" v-model="program.dateFormatted"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="!program.editable" v-model="program.program"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="!program.editable" v-model="program.company"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="!program.editable" v-model="program.funding"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="!program.editable" v-model="program.funded"></td>
<td><input type="text" v-bind:data-id="program.id" :readonly="!program.editable" v-model="program.Recruit"></td>
</tr>
</table>
</div>