કમ્પોનન્ટ v-model (Component v-model)
મૂળભૂત વપરાશ (Basic Usage)
v-model નો ઉપયોગ કમ્પોનન્ટ પર ટુ-વે બાઈન્ડિંગ (two-way binding) કરવા માટે થઈ શકે છે.
Vue 3.4 થી શરૂ કરીને, આ હાંસલ કરવા માટેનો ભલામણ કરેલ અભિગમ defineModel() મેક્રોનો ઉપયોગ કરવાનો છે:
vue
<script setup>
const model = defineModel()
function update() {
model.value++
}
</script>
<template>
<div>પેરેન્ટ બાઉન્ડ v-model છે: {{ model }}</div>
<button @click="update">વધારો</button>
</template>પેરેન્ટ પછી v-model સાથે વેલ્યુ બાંધી શકે છે:
template
<Child v-model="countModel" />defineModel() દ્વારા પરત કરવામાં આવેલી વેલ્યુ એક રિફ (ref) છે. તે અન્ય કોઈપણ રિફની જેમ એક્સેસ અને મ્યુટેટ કરી શકાય છે, સિવાય કે તે પેરેન્ટ વેલ્યુ અને લોકલ વેલ્યુ વચ્ચેના ટુ-વે બાઈન્ડિંગ તરીકે કાર્ય કરે છે:
- તેની
.valueપેરેન્ટv-modelદ્વારા બાઉન્ડ વેલ્યુ સાથે સિંક (synced) થયેલ છે; - જ્યારે તે ચાઇલ્ડ દ્વારા મ્યુટેટ કરવામાં આવે છે, ત્યારે તે પેરેન્ટ બાઉન્ડ વેલ્યુને પણ અપડેટ કરવાનું કારણ બને છે.
આનો અર્થ એ છે કે તમે આ રિફને v-model સાથે નેટિવ ઇનપુટ એલિમેન્ટ સાથે પણ બાંધી શકો છો, જે સમાન v-model વપરાશ પ્રદાન કરતી વખતે નેટિવ ઇનપુટ એલિમેન્ટ્સને લપેટવાનું (wrap) સરળ બનાવે છે:
vue
<script setup>
const model = defineModel()
</script>
<template>
<input v-model="model" />
</template>પડદા પાછળની પ્રક્રિયા
defineModel એક સગવડતા મેક્રો (convenience macro) છે. કમ્પાઇલર તેને નીચે પ્રમાણે વિસ્તાર કરે છે:
modelValueનામનો પ્રોપ, જેની સાથે લોકલ રિફની વેલ્યુ સિંક થયેલ છે;update:modelValueનામની ઇવેન્ટ, જે લોકલ રિફની વેલ્યુ મ્યુટેટ થાય ત્યારે એમિટ થાય છે.
આ રીતે તમે 3.4 પહેલા ઉપર બતાવેલ તે જ ચાઇલ્ડ કમ્પોનન્ટ લાગુ કરશો:
vue
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="props.modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</template>પછી, પેરેન્ટ કમ્પોનન્ટમાં v-model="foo" આ રીતે કમ્પાઇલ કરવામાં આવશે:
template
<Child
:modelValue="foo"
@update:modelValue="$event => (foo = $event)"
/>જેમ તમે જોઈ શકો છો, તે ઘણું વધારે લખાણ છે. જો કે, પડદા પાછળ શું થઈ રહ્યું છે તે સમજવું મદદરૂપ છે.
કારણ કે defineModel પ્રોપ જાહેર કરે છે, તમે તેને defineModel માં પાસ કરીને અન્ડરલાઇંગ પ્રોપના ઓપ્શન્સ જાહેર કરી શકો છો:
js
// v-model ને જરૂરી (required) બનાવવું
const model = defineModel({ required: true })
// ડિફોલ્ટ વેલ્યુ પૂરી પાડવી
const model = defineModel({ default: 0 })WARNING
જો તમારી પાસે defineModel પ્રોપ માટે default વેલ્યુ છે અને તમે પેરેન્ટ કમ્પોનન્ટમાંથી આ પ્રોપ માટે કોઈ વેલ્યુ પ્રદાન કરતા નથી, તો તે પેરેન્ટ અને ચાઇલ્ડ કમ્પોનન્ટ્સ વચ્ચે ડિ-સિંક્રોનાઇઝેશન (de-synchronization) નું કારણ બની શકે છે. નીચેના ઉદાહરણમાં, પેરેન્ટનો myRef અનડિફાઇન્ડ (undefined) છે, પરંતુ ચાઇલ્ડનો model ૧ છે:
vue
<script setup>
const model = defineModel({ default: 1 })
</script>vue
<script setup>
const myRef = ref()
</script>
<template>
<Child v-model="myRef"></Child>
</template>v-model આર્ગ્યુમેન્ટ્સ (v-model Arguments)
કમ્પોનન્ટ પરનું v-model આર્ગ્યુમેન્ટ પણ સ્વીકારી શકે છે:
template
<MyComponent v-model:title="bookTitle" />ચાઇલ્ડ કમ્પોનન્ટમાં, આપણે તેની પ્રથમ આર્ગ્યુમેન્ટ તરીકે defineModel() માં સ્ટ્રિંગ પાસ કરીને સંબંધિત આર્ગ્યુમેન્ટને સપોર્ટ કરી શકીએ છીએ:
vue
<script setup>
const title = defineModel('title')
</script>
<template>
<input type="text" v-model="title" />
</template>જો પ્રોપ ઓપ્શન્સની પણ જરૂર હોય, તો તે મોડેલ નામ પછી પાસ કરવા જોઈએ:
js
const title = defineModel('title', { required: true })3.4 પહેલાનો વપરાશ
vue
<script setup>
defineProps({
title: {
required: true
}
})
defineEmits(['update:title'])
</script>
<template>
<input
type="text"
:value="title"
@input="$emit('update:title', $event.target.value)"
/>
</template>બહુવિધ v-model બાઈન્ડિંગ્સ (Multiple v-model Bindings)
ચોક્કસ પ્રોપ અને ઇવેન્ટને લક્ષ્ય બનાવવાની ક્ષમતાનો લાભ લઈને આપણે અગાઉ v-model આર્ગ્યુમેન્ટ્સ સાથે શીખ્યા હતા, હવે આપણે સિંગલ કમ્પોનન્ટ ઇન્સ્ટન્સ પર બહુવિધ v-model બાઈન્ડિંગ્સ બનાવી શકીએ છીએ.
દરેક v-model કમ્પોનન્ટમાં વધારાના ઓપ્શન્સની જરૂરિયાત વિના, અલગ પ્રોપ સાથે સિંક થશે:
template
<UserName
v-model:first-name="first"
v-model:last-name="last"
/>vue
<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
</template>3.4 પહેલાનો વપરાશ
vue
<script setup>
defineProps({
firstName: String,
lastName: String
})
defineEmits(['update:firstName', 'update:lastName'])
</script>
<template>
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
</template>v-model મોડિફાયર્સ ને હેન્ડલ કરવા (Handling v-model Modifiers)
જ્યારે આપણે ઇનપુટ બાઇન્ડિંગ્સ ફોર્મ (form input bindings) શીખી રહ્યા હતા, ત્યારે આપણે જોયું કે v-model માં બિલ્ટ-ઇન મોડિફાયર્સ છે - .trim, .number અને .lazy. કેટલાક કિસ્સાઓમાં, તમે કસ્ટમ મોડિફાયર્સને સપોર્ટ કરવા માટે તમારા કસ્ટમ ઇનપુટ કમ્પોનન્ટ પર v-model પણ ઈચ્છી શકો છો.
ચાલો એક ઉદાહરણ કસ્ટમ મોડિફાયર, capitalize બનાવીએ, જે v-model બાઇન્ડિંગ દ્વારા પૂરી પાડવામાં આવેલ સ્ટ્રિંગના પ્રથમ અક્ષરને કેપિટલાઇઝ (મોટો) કરે છે:
template
<MyComponent v-model.capitalize="myText" />કમ્પોનન્ટ v-model માં ઉમેરવામાં આવેલા મોડિફાયર્સને આ રીતે defineModel() રિટર્ન વેલ્યુને ડિસ્ટ્રક્ચર કરીને ચાઇલ્ડ કમ્પોનન્ટમાં એક્સેસ કરી શકાય છે:
vue
<script setup>
const [model, modifiers] = defineModel()
console.log(modifiers) // { capitalize: true }
</script>
<template>
<input type="text" v-model="model" />
</template>મોડિફાયર્સના આધારે વેલ્યુ કેવી રીતે વાંચવી/લખવી જોઈએ તે શરતી રીતે ગોઠવવા માટે, અમે defineModel() માં get અને set ઓપ્શન્સ પાસ કરી શકીએ છીએ. આ બે ઓપ્શન્સ મોડલ રિફ ના ગેટ/સેટ (get / set) પર વેલ્યુ મેળવે છે અને ટ્રાન્સફોર્મ કરેલી વેલ્યુ પરત કરવી જોઈએ. આ રીતે આપણે capitalize મોડિફાયરને લાગુ કરવા માટે set ઓપ્શનનો ઉપયોગ કરી શકીએ છીએ:
vue
<script setup>
const [model, modifiers] = defineModel({
set(value) {
if (modifiers.capitalize) {
return value.charAt(0).toUpperCase() + value.slice(1)
}
return value
}
})
</script>
<template>
<input type="text" v-model="model" />
</template>3.4 પહેલાનો વપરાશ
vue
<script setup>
const props = defineProps({
modelValue: String,
modelModifiers: { default: () => ({}) }
})
const emit = defineEmits(['update:modelValue'])
function emitValue(e) {
let value = e.target.value
if (props.modelModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
emit('update:modelValue', value)
}
</script>
<template>
<input type="text" :value="props.modelValue" @input="emitValue" />
</template>આર્ગ્યુમેન્ટ્સ સાથે v-model માટે મોડિફાયર્સ
અહીં વિવિધ આર્ગ્યુમેન્ટ્સ સાથે બહુવિધ (multiple) v-model સાથે મોડિફાયર્સ વાપરવાનું બીજું ઉદાહરણ છે:
template
<UserName
v-model:first-name.capitalize="first"
v-model:last-name.uppercase="last"
/>vue
<script setup>
const [firstName, firstNameModifiers] = defineModel('firstName')
const [lastName, lastNameModifiers] = defineModel('lastName')
console.log(firstNameModifiers) // { capitalize: true }
console.log(lastNameModifiers) // { uppercase: true }
</script>3.4 પહેલાનો વપરાશ
vue
<script setup>
const props = defineProps({
firstName: String,
lastName: String,
firstNameModifiers: { default: () => ({}) },
lastNameModifiers: { default: () => ({}) }
})
defineEmits(['update:firstName', 'update:lastName'])
console.log(props.firstNameModifiers) // { capitalize: true }
console.log(props.lastNameModifiers) // { uppercase: true }
</script>