# [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
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.