2019年5月24日 星期五

[Vue.js] 如何在component自訂v-model


v-model 通常用在HTML的 input,根據輸入的內容會跟著改變這個參數的內容,建立專案時會將一些基礎元件(如:input)定義成一個component,方便在各個頁面引入使用。

其實 v-model 是結合了 propsemit ,可以先參考『[Vue.js] 父子元件的雙向溝通,簡單的props和emit使用範例』,比較能理解下面的內容。

舉例常見的用法來看:
<input v-model="username" />
v-model其實綁定了名為 valuepropsinputemit事件,因此所謂的 v-model 就是一個父子元件的雙向溝通,可以拆寫成:
<input :value="username"
       @input="(value)=>(username=value)" />
跟使用 v-model 達到的效果相同。


定義元件的v-model和使用

1. 定義子元件
input.vue
<template>
    <input ref="input"
        class="my-input"
        type="text"
        :placeholder="placeholder"
        :value="value"
        @input="updateValue" />
</template>

<script>
export default {
  props: {
    value: String,
    placeholder: {
      type: String
     }
  },
  methods: {
    updateValue: function() {
      this.$emit('input', this.$refs.input.value);
    }
  }
}
</script>

<style scoped>
.my-input {
    color: #3b3b3b;
    font-size: 1rem;
    line-height: 1.5;
    border: 1px solid #003377;
    padding: 4px;
}
</style>

2. 在父元件使用
<template>
  <div style="text-align: center">
    <h1>coustom v-model</h1>
    <my-input v-model="username" />
    <p>My name is {{ username }}</p>

    <h1>coustom v-model with placeholder</h1>
    <my-input v-model="email" placeholder="input your email" />
    <p>My email is {{ email }}</p>
  </div>
</template>

<script>
import MyInput from './input.vue'
export default {
  data: function() {
    return {
      username: "",
      eamil: ""
    }
  },
  components: {
    MyInput
  }
}
</script>

頁面預覽:


上述只有把 placehodler 加到 props 裡,其他像是typedisabledreadonly等等常用的attr可以依照這個方式加進你的元件裡。另外除了 inputcheckboxradio這些表格常用的也可以一一寫成元件來使用。


自訂props的預設值和監聽事件

預設情況下,v-model 是綁定的 propsvalueinputemit事件,若要自訂名稱請參考:
export default {
  prop: ['keyword'],
  model: {
    prop: 'keyword',
    event: 'transfer'
  }
  methods: {
    updateValue: function() {
      this.$emit('transfer', this.$refs.input.value)
    }
  }
}
在上面的例子裡,propskeyword,綁定的事件則是trasfer,也就是說這邊的 v-model 應該理解成:
<input :keyword="username"
       @transfer="(value)=>(username=value)" />


參考資料:
https://scotch.io/tutorials/add-v-model-support-to-custom-vuejs-component


沒有留言:

張貼留言