vue與element ui的el-checkbox的坑


一,場景

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

      

 

二, 官網的例子

         通過切換checked值為true或者false來實現,一個checkbox的狀態切換

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

  效果如下:

     

 

 

 三, 思考。

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

<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屬性)

         [
            { 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 都會有一些感觸,苦笑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM