vue與element ui的el-checkbox的坑

一,場景javascript

      經過使用checkbox,實現如圖的場景, 點擊某個tag,實現選中和非選中狀態。前端

      

 

二, 官網的例子vue

         經過切換checked值爲true或者false來實現,一個checkbox的狀態切換java

<template>
  <!-- `checked` 爲 true 或 false -->
  <el-checkbox v-model="checked">備選項</el-checkbox>
</template>
<script>
  export default {
    data() {
      return {
        checked: true
      };
    }
  };
</script>

  效果以下:瀏覽器

     

 

 

 三, 思考。測試

     經過循環li, 給數據添加checked屬性,並綁定到v-model上,來實現 一的場景。模板代碼以下:ui

<template>
  <div class="demo">
    <ul>
      <li v-for="(item, index) in list" :key="index">  //循環li
        <el-checkbox v-model="item.checked">  //v-model綁定到每一個item的checked屬性
          {{ item.name }}
        </el-checkbox>
      </li>
    </ul>
  </div>
</template>

     後臺返回數據格式(已精簡),以下(沒有checked屬性)this

         [
            { id: 1, pid: 1, name: '地區' },
            { id: 2, pid: 2, name: '遊戲類型' },
            { id: 3, pid: 4, name: '性別' },
            { id: 4, pid: 5, name: '設備類型' },
            { id: 5, pid: 6, name: '休閒時間' },
            { id: 6, pid: 7, name: '王者榮耀' },
            { id: 7, pid: 8, name: '音樂' },
            { id: 8, pid: 9, name: '品牌手錶' },
            { id: 9, pid: 10, name: '相機' },
            { id: 10, pid: 12, name: '遊戲人羣' },
          ]

  我要作的, mounted方法獲取後臺數據,再給每條數據循環添加checked屬性,初始值爲false。調試

<script>
  export default {
    name: 'demo',
    data() {
      return {
        list: [],
        allTags: [],
      }
    },
    methods: {
      getList() {
//獲取數據用settimeout模擬 setTimeout(() => { this.allTags = [ { id: 1, pid: 1, name: '地區' }, { id: 2, pid: 2, name: '遊戲類型' }, { id: 3, pid: 4, name: '性別' }, { id: 4, pid: 5, name: '設備類型' }, { id: 5, pid: 6, name: '休閒時間' }, { id: 6, pid: 7, name: '王者榮耀' }, { id: 7, pid: 8, name: '音樂' }, { id: 8, pid: 9, name: '品牌手錶' }, { id: 9, pid: 10, name: '相機' }, { id: 10, pid: 12, name: '遊戲人羣' }, ] this.allTags.map(item => { item.checked = false return item }) this.list = this.allTags }, 1500) }, }, mounted() { this.getList() }, } </script>  

     到這覺得實現了功能,看效果發現問題: 點擊時候,沒有勾上,只有框變了顏色。對象

 

            

 

 

      排查問題.....

     (腦補痛苦過程......)

      猜想:

        1,element不支持這種方法綁定,只能按官網例子中,循環el-checkbox來實現。

        2,vue綁定問題

      針對問題1:  換成了循環el-checkbox,發現結果是同樣的不行。 否認!

      剩下的就是猜想二:

            人爲把返回數據默認加上checked屬性, 即data格式爲:

       [
            { id: 1, pid: 1, name: '地區', checked: false},
            { id: 2, pid: 2, name: '遊戲類型' , checked: false},
            { id: 3, pid: 4, name: '性別' , checked: false},
            { id: 4, pid: 5, name: '設備類型' , checked: false},
            { id: 5, pid: 6, name: '休閒時間' , checked: false},
            { id: 6, pid: 7, name: '王者榮耀', checked: false },
            { id: 7, pid: 8, name: '音樂', checked: false },
            { id: 8, pid: 9, name: '品牌手錶' , checked: false},
            { id: 9, pid: 10, name: '相機' , checked: false},
            { id: 10, pid: 12, name: '遊戲人羣' , checked: false},
          ]

     測試發現,這樣能夠。

         迷茫。。。

         而後在控制檯打印數據,對比了一下結果。

         前端添加checked屬性的狀況  和        後臺返回數據原本就有checked屬性狀況 打印出來分別如 1 和 圖2

                           

 

 

                                                                      圖1                                                                                                                             圖2

           對比一下發現,前端添加checked屬性, vue並無添加get set方法,所以,監聽不到checked值變化,進而不能更新view。這點,能夠在瀏覽器vue調試中看到,點擊時候 數據的checked屬性 true和false是在交替變化,可是view上沒同步更新。截了個圖        

            

 

四,解決方法

 

        兩種方法,

        1, 拿到值不賦值給data屬性的allTags,而是定義臨時變量let, 操做完以後,賦值給list,即:

<script>
  export default {
    name: 'demo',
    data() {
      return {
        list: [],
      }
    },
    methods: {
      getList() {
        //獲取數據用settimeout模擬
        setTimeout(() => {
         let allTags = [  //這裏let定義allTags
            { id: 1, pid: 1, name: '地區' },
            { id: 2, pid: 2, name: '遊戲類型' },
            { id: 3, pid: 4, name: '性別' },
            { id: 4, pid: 5, name: '設備類型' },
            { id: 5, pid: 6, name: '休閒時間' },
            { id: 6, pid: 7, name: '王者榮耀' },
            { id: 7, pid: 8, name: '音樂' },
            { id: 8, pid: 9, name: '品牌手錶' },
            { id: 9, pid: 10, name: '相機' },
            { id: 10, pid: 12, name: '遊戲人羣' },
          ]
          allTags.map(item => {
            item.checked = false
            return item
          })
          this.list = allTags
        }, 1500)
      },
    },
    mounted() {
      this.getList()
    },
  }
</script>  

      2(推薦),用vue.$set方法,強制vue監聽checked屬性

<script>
  export default {
    name: 'demo',
    data() {
      return {
        list: [],
      }
    },
    methods: {
      getList() {
        //獲取數據用settimeout模擬
        setTimeout(() => {
         this.allTags = [  //這裏let定義allTags
            { id: 1, pid: 1, name: '地區' },
            { id: 2, pid: 2, name: '遊戲類型' },
            { id: 3, pid: 4, name: '性別' },
            { id: 4, pid: 5, name: '設備類型' },
            { id: 5, pid: 6, name: '休閒時間' },
            { id: 6, pid: 7, name: '王者榮耀' },
            { id: 7, pid: 8, name: '音樂' },
            { id: 8, pid: 9, name: '品牌手錶' },
            { id: 9, pid: 10, name: '相機' },
            { id: 10, pid: 12, name: '遊戲人羣' },
          ]
          this.allTags.map(item => {
            //item.checked = false
            this.$set(item, 'checked', false) // 這裏,給對象添加屬性,用$set方法。
            return item
          })
          this.list = this.allTags
        }, 1500)
      },
    },
    mounted() {
      this.getList()
    },
  }
</script>  

 done!!

五,總結。

       這個問題是我在項目中遇到的問題,經過一步一步鎖定問題以後,抽出來作了最精簡版本,故作此總結,也給其餘遇到坑的童鞋一點點幫助。 

      ps,每次用element ui 都會有一些感觸,苦笑。

相關文章
相關標籤/搜索