vue自定義組件使用v-model

組件系統(tǒng)作為Vue最重要的部分之一,多人協(xié)作開發(fā)的時候,寫好一個可復用的組件灰常重要,別的同事用到你寫的組件的時候會覺得:“誒,這個小伙汁有點東西!”

  • 如果不用v-model,在原生input標簽上怎么實現(xiàn)雙向綁定呢?
<template>
  <input :value="text" @input="handler" />
</template>
<script>
  export default {
    name: 'customInput',
    data () {
      return {
        text: 'message'
      }
    },
    methods: {
      handler (event) {
        // 這里有個點要注意一下,v-model不會處理輸入法組合文字過程中得到更新
        if (event.target.composing) return
        this.text = event.target.value
      }
    }
  }
</script>

這里有個點要注意一下,對于input標簽,v-model不會處理輸入法組合文字過程中得到更新
文檔地址,如果對源碼感興趣可以參考這里

v-model就是上面操作的語法糖

  • 下面我們來實現(xiàn)一個簡單的星級組件并兼容v-model
<template>
  <div class="component-star" @click.stop="">
    <ul class="star-list">
      <li v-for="(item, index) in list" :key="index" @click="change(index)">{{item}}</li>
    </ul>
    <span class="label">{{label}}</span>
  </div>
</template>

<script>
  export default {
    name: 'myStar',
    props: {
      value: { // 必須是value屬性,名字不能變
        type: [Number, String],
        required: true
      }
    },
    data () {
      return {
      }
    },
    computed: {
      list () {
        return '★★★★★☆☆☆☆☆'.slice(5 - this.value, 10 - this.value).split('')
      },
      label () {
        const arr = ['1星', '2星', '3星', '4星', '5星']
        return arr[this.value - 1]
      }
    },
    watch: {
    },
    methods: {
      // 當星級變化
      change (val) {
        let num = val + 1
        this.$emit('input', num) // 必須是input事件
      }
    }
  }
</script>

<style lang="less">
  .component-star {
    .star-list {
      display: inline-flex;
      font-size: 20px;
      li {
        cursor: pointer;
        margin-right: 5px;
        color: #f7ba2a;
        transform: scale(1);
        transition: transform .1s linear;
        &:hover {
          transform: scale(1.3);
        }
      }
    }
  }
</style>

有兩個關(guān)鍵的地方:
1、組件的props中必須要定義value屬性
2、當值變化后,一定要用input事件回傳修改后的值

寫好注冊就可以在任意組件中使用了

<template>
  <div class="parent">
    <my-star v-model="star"></my-star>
  </div>
</template>
<script>
  export default {
    name: 'parent',
    data () {
      return {
        star: 3
      }
    },
    watch: {
      star (val) {
        console.log(val)
      }
    }
  }
</script>

那么問題來了:如果我編寫的組件內(nèi)部還有一個使用v-model的組件怎么辦呢?

比如剛才的組件我想在element提供的el-rate組件基礎(chǔ)上做一層封裝,只需要把"v-model"替換為":value",這樣功能即可正常使用。(當然,如果你是按需加載element組件的話,不要忘了先注冊組件)

<template>
  <div class="component-star" @click.stop="">
    <!--只需要把v-model替換為:value-->
    <el-rate :value="value" @change="change" ref="rate"></el-rate>
  </div>
</template>

如果報了這個錯:[Vue warn]: Invalid prop: type check failed for prop "value". Expected Number, got String.說明你傳進來的value是個String類型的值,el-rate的value參數(shù)只接受Number類型的值,把組件v-model綁定的變量改成數(shù)字類型就好了。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • VUE Vue :數(shù)據(jù)驅(qū)動的M V Vm框架 m :model(后臺提供數(shù)據(jù)),v :view(頁面),vM(模板...
    wudongyu閱讀 5,538評論 0 11
  • 主要還是自己看的,所有內(nèi)容來自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,556評論 0 25
  • 一日時間, 忙里偷閑。 望窗外、陰雨連連。 吉他彈奏, 勿忘心安。 樂書中屋,詩中韻,畫中顏。 科院桃園, 已是晴...
    拾憶絮語閱讀 368評論 1 6
  • 人臉識別(http://ai.baidu.com/tech/face) 選擇立即使用(登錄百度賬號)人臉識別2.p...
    敏姐姐_e9d0閱讀 298評論 0 1
  • 2018年3月春天到了,適合戀愛的季節(jié),90后姑娘小白在經(jīng)歷了一年的感情冬眠,經(jīng)過春節(jié)家庭的輪番詢問,在這新的一年...
    嫣然小沫閱讀 438評論 0 0

友情鏈接更多精彩內(nèi)容