# [Vue] Custom Component 使用 v-model ###### tags: `Vue` `前端筆記` ## `v-model` 的基本介紹 在一般的表單 component 中,常用 `v-model` 語法糖綁定同 scope input 及 state 的值,讓開發者省略自行動態綁定 value 及傳接更動 state 的事件。 ```javascript= <template> <input v-model="searchText"> </template> <script> export default { data () { return { searchText: 'Lun' } } } </script> ``` 等價於: ```javascript= <template> <input v-bind:value="searchText" v-on:input="searchText = $event.target.value" > </template> <script> export default { data () { return { searchText: 'Lun' } }, } </script> ``` ==所以可以得知 `v-model` 是 `:value` + `event` 縮寫的語法糖。== ## `v-model` 也可以下在 component 上,透過 `v-model` 的語法糖幫忙簡化更動 parent component state 的方法 ==切記心法:`v-model` 是 `:value` + `event` 的縮寫語法糖。== ```javascript= // App.vue <template> <input-component v-model="name"></input-component> </template> <script> import InputComponent from "./InputComponent.vue"; export default { name: 'APP', components: { InputComponent, }, data () { return { name: 'Lun' } } } </script> ``` ```javascript= // InputComponent.vue <template> <input type="text" :value="name" @input="$emit('input', $event.target.value)"> </template> <script> export default { name: 'InputComponent', // props 告訴 Vue 要往外找接來的資料,此例子是 v-model props: ['name'] } </script> ``` 因為 `v-model` 是 `:value` + `event` 的縮寫語法糖,所以在 child component 透過 `props` 讓 Vue 得知有外部資料,再手動綁定 `:value` 及 `event`。`evnet` 則因為 child component 要改 parent component 的 state 要透過發射事件(`$evnet`)。 > 手動綁定事件 + `$emit` = 還是「合法地」透過事件改變 parent component 的 state。 (初始化,`App.vue` 及 `TestInput.vue` state 相同)  (`TestInput.vue` 輸入新值了,好險有 `v-model` 同步更新 parent 及 child 的 state)   ## Parent 還需要透過自己的事件接 child component 射來的 `$emit` 嗎? 不用,只要在 child component 寫入手動綁定(`props`, `:value` 及 `$emit`),在 parent component 中叫用 child component 寫入 `v-model="keyName"` 即可。 **`v-model="keyName"` -> child component props 要接的 keyName。** ## Vue 3 的大躍進 在 Vue 3 中使用 v-model to custom component 有新的 defaul keyName,讓程式碼的閱讀性更上一層樓。 ```javascript= // App.vue <template> <input-component v-model="testValue"></input-component> </template> <script> export default { data () { return { testValue: 'Lun' } } } </script> ``` ```javascript= // InputComponent.vue <template> <input :value="modelValue" @input="$emit('updata:modelValue', $event.target.value)" /> </template> <script> export default { // props 告訴 Vue 有外部的資料,Vue 會自己找來源 // modelValue -> 預設的 v-model keyName props: { modelValue: { type: String } } } </script> ``` 在 Vue 3 提供了預設的 `modelValue` 供開發者使用預設的 keyName 取得 parent 傳的 v-model 資料。 而更新資料的 `emit`,Vue 3 也有語意更明確的 `update:modelValue` 的方法,讓開發者更明白這個是更新 parent state。 (parent 透過 v-model 與 child 雙向綁定)  (Vue 3 預設的 `modelValue` 以及 `update:modelValue`)  (多虧 v-model 雙向綁定,parent 跟 child 的 state 都有同步更新)   ### 除了預設 `modelValue` 及 `update:modelValue` 外,開發者可以自行命名 從上部分可以得知,child 中是透過 props 預設的 `modelValue` 接 parent 的 v-model 綁定資料。 但是開發者也可以自行命名,做法很簡單,就把 parent 給 child 的 `v-model="valueKey"`,改寫成 `v-model:customName="valueKey"` 就好了。(連更新的 `emit` 也要使用 v-model 的名字) ```javascript= // App.vue <template> <input-component v-model:myName="testValue"></input-component> </template> <script> export default { data () { return { testValue: 'Lun' } } } </script> ``` ```javascript= // InputComponent.vue <template> <input :value="myName" @input="$emit('updata:myName', $event.target.value)" /> </template> <script> export default { // props 告訴 Vue 有外部的資料,Vue 會自己找來源 // 因為 parent 有給名字,所以就要使用名字 props: { myName : { type: String } } } </script> ``` (parent 中的 state)  (因為 v-model 有給名字,所以 child 也需要使用名字)-> 在開發者工具也可以看到有名字的 `props` 及 `updata:customName`  (child 跟 parent 都有綁在一起)   ## 參考資料 1. [Using v-model on Components](https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components) 2. [How To Add v-model Support to Custom Vue.js Components](https://www.digitalocean.com/community/tutorials/how-to-add-v-model-support-to-custom-vue-js-components) 3. [Vue.js Tip #1: Use V-Model on Custom Components](https://javascript.plainenglish.io/vue-js-tip-1-use-v-model-on-custom-components-be56401727e0) 4. [Vue JS 3 Tutorial - 36 - Components and v-model](https://www.youtube.com/watch?v=CALrQCw41dI) 5. [VueJS. v-model in custom component](https://stackoverflow.com/questions/46258763/vuejs-v-model-in-custom-component) 6. [008 天絕對看不完的 Vue.js 3 指南 - 2.2.7 v-model 與元件的雙向綁定](P.121 - P.122) 7. [Vue - The Complete Guide (incl. Router & Composition API) - lecture: 147](https://www.udemy.com/course/vuejs-2-the-complete-guide/learn/lecture/21526418#questions)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up