vue綁定key的案例(輸入框失焦問題)

之前做過這樣的一個需求,就是輸入框可動態增加或者減少的場景。通過v-for來遍歷所有輸入框,那麼分析下面key幾種情況:

爲了演示,這裏假設輸入框的校驗規則是允許字符數爲1-5。

1.沒有綁定key 或者 key綁定index的情況
如圖所示,第二個輸入框輸入了6個字符,校驗不通過,但是第三個輸入框校驗是通過的,但是當我們刪除第二個輸入框的時候,第三個輸入框變爲第二個輸入框,本來校驗通過的,現在反而不通過了。
在這裏插入圖片描述
分析:當dom發生變化的時候,vue進行dom進行的增刪,藉助vnode的key比較,第二個輸入框綁定的key爲2,第三個輸入綁定的輸入框爲3,那麼將第二個輸入框刪除後,第三個輸入框變爲第二個輸入框,這時候vue刪除key爲3的節點,key爲2的節點依舊存在,替換的僅僅是輸入框的值,那麼就會出現上面這種情況。

2.key綁定唯一值的情況
通過下面這個函數生成唯一值:

  uuid (index) {
     	 return `uuid-${index}-${Date.now()}-${Math.random().toFixed(2)}`;
  }

爲了解決第一種情況出現,我們嘗試將key綁定唯一值,但是出現另外一個bug。

如圖所示,第一種情況的問題在這裏確實能得到解決,但是每當我在輸入框輸入的時候,一輸入一個字符就會出現失去焦點。
在這裏插入圖片描述分析:每當值發生變化,vue就會重新渲染。因爲我的key值是通過時間戳和隨機數來生成,所以重新渲染的時候,節點的key肯定和上一次不一樣,那麼vue會將所有節點全部替換,所以出現失焦的情況。

3.key仍舊綁定唯一值的情況
將綁定的唯一key存起來,當輸入後,重新渲染的時候,用上次的key,而不是重新新的key,這樣就能解決第2種情況出現的問題
在這裏插入圖片描述
分析:如下面代碼展示,將唯一key存進keyList裏面,然後下次渲染仍舊用上次的key

    <el-form :model="form">
        <el-form-item class="main-container" v-for="(item, index) in form.list" :key="keyList[index]"
                      :prop="'list.' + index + '.value'"
                      :rules="{
                        validator: validateName, trigger: 'blur'
                       }">
            <el-input class="main-input" v-model="item.value"></el-input>
            <el-button v-if="index === form.list.length -1" @click="add(index)">+</el-button>
            <el-button v-if="form.list.length > 1" @click="sub(index)">-</el-button>
      </el-form-item>
    </el-form>

addsub函數在增刪輸入框的同時,也對keyList進行增刪

data () {
    var validateName = (rule, value, callback) => {
        if (value === '') {
            callback(new Error('輸入不能爲空'));
        } else {
            if (value.length > 5) {
                callback(new Error('輸入項不能超過5個字符'));
            }
        }
      };
      return {
          form: {
            list: [
                {
                    value: ''
                }
            ]
          },
          keyList: [this.uuid(0)],
          validateName
      }
  },
  methods: {
      add (index) {
          this.keyList.push(this.uuid(index));
          this.form.list.push({value: ''})
      },
      sub (index) {
          this.keyList.splice(index, 1);
          this.form.list.splice(index, 1);
      },
      uuid (index) {
          return `uuid-${index}-${Date.now()}-${Math.random().toFixed(2)}`;
      }
  }

完整代碼地址:https://github.com/suhuashan/vue-blog
如果對您有幫助,請star下~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章