vue.js - 使用列表渲染时,改变表单v-model绑定的data异常,成功改变后表单的值也不作相应更新

查看:93
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆