vue.js - 使用列表渲染时,改变表单v-model绑定的data异常,成功改变后表单的值也不作相应更新
本文介绍了vue.js - 使用列表渲染时,改变表单v-model绑定的data异常,成功改变后表单的值也不作相应更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
第一次点击保存的时候在vue Devtool里查看赋值是正常的,第二次的时候就要点击了其他input的时候才会赋值成功。取消按钮也是类似的情况,而且就算赋值成功input里的值也不会发生改变,这是为什么啊?
<template>
<layout>
<div slot='header'>
<h2 class="uk-display-inline">标题</h2>
<a v-link="" class="uk-float-right">返回</a>
</div>
<div slot='content'>
<ul class="uk-tab" data-uk-switcher="{connect:'#phTabs'}">
<li class="uk-active"><a href="">输入参数</a></li>
<li><a href="">输出类型</a></li>
<li><a href="">输入文件</a></li>
</ul>
<div class="uk-block">
<ul id="phTabs" class="uk-switcher">
<li class="uk-active">
<validator name="inputParaVali">
<div class="uk-clearfix">
<span>共{{inputParams.length}}条数据</span>
<button class="uk-button uk-button-success uk-float-right uk-margin-small-left">生成配置文件</button>
<button class="uk-button uk-button-success uk-float-right" :disabled='!allowAddParam' @click='addParam'>新增参数</button>
</div>
<form action="" class="uk-form uk-margin-top">
<table class="uk-table">
<thead>
<tr>
<th>参数key</th>
<th>参数中文描述</th>
<th>参数类型</th>
<th>value</th>
<th>value边界</th>
<th>默认值</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<template v-for="param in inputParams">
<tr>
<td><input type="text" v-model='param.key[0]' placeholder="" :class="($inputParaVali.key && $inputParaVali.key.valid) ? '':'uk-form-danger'" v-validate:key="{required:true}" initial="off"></td>
<td><input type="text" v-model='param.desc[0]' :class="($inputParaVali.desc && $inputParaVali.desc.valid) ? '':'uk-form-danger'" v-validate:desc="{required:true}" initial="off"></td>
<td><v-select :options="paramTypeOptions" :selected="param.type[0]" :multiple="false" :searchable="false" :show-labels="false" @update="updateParamType" key="id" label="name"></v-select></td>
<td><input type="text" v-model='param.value[0]' :class="($inputParaVali.value && $inputParaVali.value.valid) ? '':'uk-form-danger'" v-validate:value="{required:true}" initial="off"></td>
<td><input type="text" v-model='param.valueBoundary[0]' :class="($inputParaVali.valueboundary && $inputParaVali.valueboundary.valid) ? '':'uk-form-danger'" v-validate:valueBoundary="{required:true}" initial="off"></td>
<td><input type="text" v-model='param.defaultValue[0]' :class="($inputParaVali.defaultvalue && $inputParaVali.defaultvalue.valid) ? '':'uk-form-danger'" v-validate:defaultValue="{required:true}" initial="off"></td>
<td>
<button type="button" class="uk-button uk-button-success" :data-index='$index' :disabled='!$inputParaVali.modified||$inputParaVali.untouched||$inputParaVali.invalid' @click.prevent='saveParam'>保存</button>
<button type="button" v-show='$inputParaVali.modified' :data-index='$index' class="uk-button uk-button-success uk-margin-small-left" @click.prevent='cancelEdit'>取消</button>
<button type="button" v-show='!$inputParaVali.modified' :data-index='$index' class="uk-button uk-button-success uk-margin-small-left" @click.prevent='deleteParam'>删除</button>
</td>
</tr>
</template>
</tbody>
</table>
</form>
</validator>
</li>
<li>
</li>
<li>
</li>
</ul>
</div>
</div>
</layout>
</template>
<script>
import 'VALIDATOR'
import layout from './../Layout'
import vSelect from 'COMPONENT/MultiSelect'
export default {
components: {
layout,
vSelect
},
data() {
return {
allowAddParam:true,
paramTypeOptions:[],
inputParams:[],
outputType:{
},
inputFile:{
supportVideo:true,
supportImg:true,
file:{
id:'',
value:'',
name:'',
failed:false
}
}
}
},
methods: {
addParam(){
this.allowAddParam=false
this.inputParams.push({
key:['',''],
desc:['',''],
type:['',''],
value:['""','""'],
valueBoundary:['/','/'],
defaultValue:['/','/']
})
},
updateParamType(){
},
saveParam(e){
this.allowAddParam=true
let index = parseInt(e.target.dataset.index)
let params = this.inputParams[index]
console.log(params)
params.key[1]=params.key[0]
params.desc[1]=params.desc[0]
params.type[1]=params.type[0]
params.value[1]=params.value[0]
params.valueBoundary[1]=params.valueBoundary[0]
params.defaultValue[1]=params.defaultValue[0]
},
cancelEdit(e){
console.log(e)
this.allowAddParam=true
let index = parseInt(e.target.dataset.index)
let params = this.inputParams[index]
params.key[0]=params.key[1]
params.desc[0]=params.desc[1]
params.type[0]=params.type[1]
params.value[0]=params.value[1]
params.valueBoundary[0]=params.valueBoundary[1]
params.defaultValue[0]=params.defaultValue[1]
},
deleteParam(e){
this.allowAddParam=true
let index = parseInt(e.target.dataset.index)
this.inputParams.splice(index,1)
},
uploadFiles(){
}
}
}
</script>
<style lang="less" scoped>
table{
table-layout: fixed;
}
</style>
开始时是这样的界面:
点击增加参数后添加了一行tr
输入参数key 和 参数中文描述的值看到data也作相应改变了
点击保存按钮,赋值成功了
继续改变参数key的值,点击保存按钮,这次没有赋值成功,但我console.log打印出来是赋值成功的。好奇怪啊
但当我点击了其他input后,vue Devtllo里面又显示赋值成功了,这是什么原因啊?
接下来我改变参数中文描述的值,并点击取消,发现desc[0]的值并没有被改变为desc[1]的值
可是还是一样的,当我点击了其他input后desc[0]的值成功改为了desc[1]的值,然并卵啊,参数中文描述的那个input的值不是和desc[0]绑定了吗?为什么desc[0]改变了input里的值还是没变啊
以上就是我遇到的两个问题,求大神解答
听取了Tomoe的建议后修改的代码:
<template>
<layout>
<div slot='header'>
<h2 class="uk-display-inline">标题</h2>
<a v-link="" class="uk-float-right">返回</a>
</div>
<div slot='content'>
<ul class="uk-tab" data-uk-switcher="{connect:'#phTabs'}">
<li class="uk-active"><a href="">输入参数</a></li>
<li><a href="">输出类型</a></li>
<li><a href="">输入文件</a></li>
</ul>
<div class="uk-block">
<ul id="phTabs" class="uk-switcher">
<li class="uk-active">
<validator name="inputParaVali">
<div class="uk-clearfix">
<span>共{{inputParams.length}}条数据</span>
<button class="uk-button uk-button-success uk-float-right uk-margin-small-left">生成配置文件</button>
<button class="uk-button uk-button-success uk-float-right" :disabled='!allowAddParam' @click='addParam'>新增参数</button>
</div>
<form action="" class="uk-form uk-margin-top">
<table class="uk-table">
<thead>
<tr>
<th>参数key</th>
<th>参数中文描述</th>
<th>参数类型</th>
<th>value</th>
<th>value边界</th>
<th>默认值</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<template v-for="param in inputParams">
<tr>
<td><input type="text" v-model='param.key.temValue' placeholder="" :class="($inputParaVali.key && $inputParaVali.key.valid) ? '':'uk-form-danger'" v-validate:key="{required:true}" initial="off"></td>
<td><input type="text" v-model='param.desc.temValue' :class="($inputParaVali.desc && $inputParaVali.desc.valid) ? '':'uk-form-danger'" v-validate:desc="{required:true}" initial="off"></td>
<td><v-select :options="paramTypeOptions" :selected="param.type.temValue" :multiple="false" :searchable="false" :show-labels="false" @update="updateParamType" key="id" label="name"></v-select></td>
<td><input type="text" v-model='param.value.temValue' :class="($inputParaVali.value && $inputParaVali.value.valid) ? '':'uk-form-danger'" v-validate:value="{required:true}" initial="off"></td>
<td><input type="text" v-model='param.valueBoundary.temValue' :class="($inputParaVali.valueboundary && $inputParaVali.valueboundary.valid) ? '':'uk-form-danger'" v-validate:valueBoundary="{required:true}" initial="off"></td>
<td><input type="text" v-model='param.defaultValue.temValue' :class="($inputParaVali.defaultvalue && $inputParaVali.defaultvalue.valid) ? '':'uk-form-danger'" v-validate:defaultValue="{required:true}" initial="off"></td>
<td>
<button type="button" class="uk-button uk-button-success" :data-index='$index' :disabled='!$inputParaVali.modified||$inputParaVali.untouched||$inputParaVali.invalid' @click.prevent='saveParam'>保存</button>
<button type="button" v-show='$inputParaVali.modified' :data-index='$index' class="uk-button uk-button-success uk-margin-small-left" @click.prevent='cancelEdit'>取消</button>
<button type="button" v-show='!$inputParaVali.modified' :data-index='$index' class="uk-button uk-button-success uk-margin-small-left" @click.prevent='deleteParam'>删除</button>
</td>
</tr>
</template>
</tbody>
</table>
</form>
</validator>
</li>
<li>
</li>
<li>
</li>
</ul>
</div>
</div>
</layout>
</template>
<script>
import 'VALIDATOR'
import layout from './../Layout'
import vSelect from 'COMPONENT/MultiSelect'
export default {
components: {
layout,
vSelect
},
data() {
return {
allowAddParam:true,
paramTypeOptions:[],
inputParams:[],
outputType:{
},
inputFile:{
supportVideo:true,
supportImg:true,
file:{
id:'',
value:'',
name:'',
failed:false
}
}
}
},
methods: {
addParam(){
this.allowAddParam=false
this.inputParams.push({
key:{
temValue:'',
value:''
},
desc:{
temValue:'',
value:''
},
type:{
temValue:'',
value:''
},
value:{
temValue:'""',
value:'""'
},
valueBoundary:{
temValue:'/',
value:'/'
},
defaultValue:{
temValue:'/',
value:'/'
}
})
},
updateParamType(){
},
saveParam(e){
this.allowAddParam=true
let index = parseInt(e.target.dataset.index)
let params = this.inputParams[index]
params.key.value=params.key.temValue
params.desc.value=params.desc.temValue
params.type.value=params.type.temValue
params.value.value=params.value.temValue
params.valueBoundary.value=params.valueBoundary.temValue
params.defaultValue.value=params.defaultValue.temValue
},
cancelEdit(e){
this.allowAddParam=true
let index = parseInt(e.target.dataset.index)
let params = this.inputParams[index]
params.key.temValue=params.key.value
params.desc.temValue=params.desc.value
params.type.temValue=params.type.value
params.value.temValue=params.value.value
params.valueBoundary.temValue=params.valueBoundary.value
params.defaultValue.temValue=params.defaultValue.value
},
deleteParam(e){
this.allowAddParam=true
let index = parseInt(e.target.dataset.index)
this.inputParams.splice(index,1)
},
uploadFiles(){
}
}
}
</script>
<style lang="less" scoped>
table{
table-layout: fixed;
}
</style>
解决方案
一言敝之,vue 沒辦法追蹤「透過索引給數組賦值」這個行為 (受限於 Javascript 語言特性)
所以你這邊的代碼才會沒反應。
params.key[1]=params.key[0]
params.desc[1]=params.desc[0]
params.type[1]=params.type[0]
params.value[1]=params.value[0]
params.valueBoundary[1]=params.valueBoundary[0]
params.defaultValue[1]=params.defaultValue[0]
其實還是有方法可以透過索引賦值並且能響應,例如利用 $set
,不過我認為把其改成對象會更好,例如:
key:{
tempValue: '',
value: '',
}
saveParams() {
params.key.value = params.key.tempValue
}
這樣處理比較直觀些,至於數組跟對象的差別,我寫了小例子可以看下:jsFiddle
这篇关于vue.js - 使用列表渲染时,改变表单v-model绑定的data异常,成功改变后表单的值也不作相应更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文