{%hackmd BJrTq20hE %} ###### tags: `Vue` `composition API` # 從composition API 開始VUE的生活- v-model 資料的雙向綁定、自訂義組件的資料綁定、One-Way Data Flow 單向資料流 ## v-model v-model指令使用來雙向綁定資料與畫面渲染的資料。 v-model使用的標籤為 input、textarea、select 以下為基本的範例 ### input type="text" ```javascript= <script setup> const num = ref(0) ``` ```htmlembedded= <input type="text" v-model="num"> <h2>{{num}}</h2> </script> ``` 畫面與資料綁定  當input的內容改變,const num = ref(0),同時也被改變並呈現在畫面上。  這個時候的const num = ref("0123")資料型態變成字串了 [v-model修飾符](https://hackmd.io/HQqcF68vRi-MPYEM8-jIiQ?view#52-v-model%E4%BF%AE%E9%A3%BE%E7%AC%A6) ### input type="checkbox" ```javascript= <script setup> const data = ref(true) ``` ```htmlembedded= <input type="checkbox" v-model="data"> <label for="check" >checkbox</label> <h2>{{data}}</h2> </script> ```   ### input type="checkbox" 與顯示所選內容 ```javascript= <script setup> const checkList = ref([]) </script> ``` 注意這邊的input內要有value這個屬性才會把透過v-model把值寫到checkList這個空陣列。 ```htmlembedded= <template> <input type="checkbox" id="Black Tea" value="Black Tea" v-model="checkList"> <label for="Black Tea">Black Tea</label> <input type="checkbox" id="Milk Tea" value="Milk Tea" v-model="checkList"> <label for="Milk Tea">Milk Tea</label> <input type="checkbox" id="Green tea" value="Green tea" v-model="checkList"> <label for="Green tea">Green tea</label> <h2>checkList:{{checkList}}</h2> </template> ```   ### input type="radio" 與顯示所選內容 ```javascript= <script setup> const picked = ref('') </script> ``` 注意這邊的input內要有value這個屬性才會把透過v-model把值寫到picked這個空字串。 ```htmlembedded= <template> <input type="radio" id="male" value="male" v-model="picked"> <label for="male">Male</label> <input type="radio" id="female" value="female" v-model="picked"> <label for="female">Female</label> <h2>Gender:{{picked}}</h2> </template> ```   ### select 與顯示所選內容 ```javascript= <script setup> const menu = ref('') const menuComputed = computed(()=> menu.value === ''? '還沒點餐' : menu ) </script> ``` ```htmlembedded= <template> <select name="menu" id="orderList" v-model="menu"> <option value="" disabled selected>請選擇一樣你想吃的東西</option> <option>牛排</option> <option>炒飯</option> <option>文字燒</option> <option>火鍋</option> </select> <h2>你的點餐:{{menuComputed}}</h2> </template> ```   ### select 多選 與顯示所選內容 多選的話menus要為空陣列 ```javascript= <script setup> const menus = ref([]) const menuComputed = computed(()=> menu.value === ''? '還沒點餐' : menu ) </script> ``` ```htmlembedded= <template> <select name="menu" id="orderList" v-model="menus" multiple> <option value="" disabled selected>請選擇一樣你想吃的東西</option> <option>牛排</option> <option>炒飯</option> <option>文字燒</option> <option>火鍋</option> </select> <h2>你的點餐:{{menuComputed}}</h2> </template> ```   補充select內的option也可以使用v-for指令 ```javascript= <script setup> const menus = ref([]) const options = ref(['牛排','炒飯','文字燒','火鍋']) const menuComputed = computed(()=> menu.value === ''? '還沒點餐' : menu ) </script> ``` ```htmlembedded= <template> <h2>option使用v-for</h2> <select name="menu" id="orderList" v-model="menus" multiple> <option value="" disabled selected>請選擇你想吃的東西</option> <option v-for="option in options" :key="option" :value="option">{{option}}</option> </select> <h2>你的點餐:{{menusComputed}}</h2> </template> ``` ### v-model與子元件的使用 父元件 :::success props內的modelValue與emits內的update:modelValue這兩個當子元件使用v-model綁定父元件的資料時是固定的不能改變。 ::: ```javascript= <script setup> const componentString = ref('APP') // 可以知道componentString有沒有被改變 watch(componentString,(newValue, oldValue)=>{ console.log('new', newValue); console.log('old', oldValue); }) ``` ```htmlembedded= <TestComponent v-model="componentString" /> <h3>{{componentString}}</h3> </script> ``` 子元件 :::success 1.元件內的input就不是使用v-model綁props.value了 而是使用v-bind綁定rops.value。 2.emit的部分所綁定的動作是input,其中update:modelValue這個"方法"當子元件有input且綁定父元件的資料時update:modelValue不能改變寫法。 3.所傳的資料是$event.target.value,就等於addEventListener('input',(e)=>{e.target.value})裡面的e.target.value ::: ```javascript= <script setup> const props = defineProps(['modelValue']) const emits = defineProps(['update:modelValue']) </script> ``` ```htmlembedded= <template> <h2>TestComponent</h2> <input :value="props.modelValue" @input="emits('update:modelValue', $event.target.value)"> </template> ``` ### 元件v-model是由props與emit這兩個組成 父元件 :::success 1.與上述的範例不同因為不是使用v-model綁定所以傳入資料的時候可以自訂。 2.因為沒有使用v-model所以要處理資料接收,固定使用@updata:model-value或是@updata:modelValue來接收資料 ::: ```javascript= <script setup> const componentString = ref('APP') const getData = (res)=>{ componentString.value = res } // 可以知道componentString有沒有被改變 watch(componentString,(newValue, oldValue)=>{ console.log('new', newValue); console.log('old', oldValue); }) </script> ``` ```htmlembedded= <template> <h2>元件v-model是由props與emit這兩個組成</h2> <TestComponentA :send-string="componentString" @update:model-Value="getData"/> <h3>{{componentString}}</h3> </template> ``` 子元件 :::success 1.元件內的input就不是使用v-model綁props.value了 而是使用v-bind綁定rops.value。 2.emit的部分所綁定的動作是input,其中update:modelValue這個"方法"當子元件有input且綁定父元件的資料時update:modelValue不能改變寫法。 3.所傳的資料是$event.target.value,就等於addEventListener('input',(e)=>{e.target.value})裡面的e.target.value ::: ```javascript= <script setup> const props = defineProps(['sendString']) const emits = defineProps(['update:modelValue']) </script> ``` ```htmlembedded= <template> <h2>componentA</h2> <input type="text" :value="props.sendString" @input="emits('update:modelValue', $event.target.value)"> </template> ``` 結果如下圖 原本  在子元件輸入123後  watch也監測到了資料改變  延伸閱讀 --- [vue官方文件 v-model](https://vuejs.org/guide/components/events.html#usage-with-v-model) 內有子元件可以透過computed的get與set使用v-model,與v-model自訂修飾符。 ## One-Way Data Flow 透過把方法傳送到子元件執行,讓資料只留在父元件 父元件 ```javascript= <script setup> const write = ref('') function writeJack(){ write.value = 'Jack' </script> } ``` ```htmlembedded= <TestComponentB :ComponentWriteJackFn="writeJack"/> <input type="text" v-model="write"> ``` 子元件 ```javascript= <script setup> const props = defineProps(['ComponentWriteJackFn']) </script> ``` ```htmlembedded= <template> <h2>componentB</h2> <button type="button" @click="props.ComponentWriteJackFn" >writeJack</button> </template> ``` 參考資料 --- [Vue3 + Vite 快速上手 Get Startrd EP4 - v-model 資料的雙向綁定 / 自訂義組件的資料綁定 / One-Way Data Flow 單向資料流](https://www.youtube.com/watch?v=firPRbhoX7o)
×
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
.