કસ્ટમ ડાયરેક્ટિવ્સ (Custom Directives)
પ્રસ્તાવના (Introduction)
કોર (core) માં ઉપલબ્ધ ડિફોલ્ટ ડાયરેક્ટિવ્સ (જેમ કે v-model અથવા v-show) ઉપરાંત, Vue તમને તમારા પોતાના કસ્ટમ ડાયરેક્ટિવ્સ રજીસ્ટર કરવાની પણ મંજૂરી આપે છે.
અમે Vue માં કોડ પુનઃઉપયોગના બે સ્વરૂપો રજૂ કર્યા છે: કમ્પોનન્ટ્સ અને કમ્પોઝેબલ્સ. કમ્પોનન્ટ્સ મુખ્ય બિલ્ડિંગ બ્લોક્સ છે, જ્યારે કમ્પોઝેબલ્સ સ્ટેટફુલ લોજિકના પુનઃઉપયોગ પર ધ્યાન કેન્દ્રિત કરે છે. બીજી બાજુ, કસ્ટમ ડાયરેક્ટિવ્સ મુખ્યત્વે સાદા એલિમેન્ટ્સ પર લો-લેવલ DOM એક્સેસ સાથે સંકળાયેલા લોજિકના પુનઃઉપયોગ માટે છે.
કસ્ટમ ડાયરેક્ટિવને કમ્પોનન્ટ જેવી જ લાઇફસાયકલ હૂક્સ ધરાવતી ઓબ્જેક્ટ તરીકે વ્યાખ્યાયિત કરવામાં આવે છે. હૂક્સ તે એલિમેન્ટ મેળવે છે જેની સાથે ડાયરેક્ટિવ જોડાયેલ હોય છે. અહીં ડાયરેક્ટિવનું ઉદાહરણ છે જે જ્યારે એલિમેન્ટને Vue દ્વારા DOM માં દાખલ કરવામાં આવે ત્યારે તેમાં ક્લાસ ઉમેરે છે:
vue
<script setup>
// ટેમ્પલેટ્સમાં v-highlight સક્ષમ કરે છે
const vHighlight = {
mounted: (el) => {
el.classList.add('is-highlight')
}
}
</script>
<template>
<p v-highlight>આ વાક્ય મહત્વનું છે!</p>
</template>આ વાક્ય મહત્વનું છે!
<script setup> માં, કોઈપણ camelCase વેરીએબલ કે જે v ઉપસર્ગ (prefix) થી શરૂ થાય છે તેનો ઉપયોગ કસ્ટમ ડાયરેક્ટિવ તરીકે થઈ શકે છે. ઉપરના ઉદાહરણમાં, vHighlight નો ટેમ્પલેટમાં v-highlight તરીકે ઉપયોગ કરી શકાય છે.
જો તમે <script setup> નો ઉપયોગ કરી રહ્યાં નથી, તો directives ઓપ્શન નો ઉપયોગ કરીને કસ્ટમ ડાયરેક્ટિવ્સ રજીસ્ટર કરી શકાય છે:
js
export default {
setup() {
/*...*/
},
directives: {
// ટેમ્પલેટમાં v-highlight સક્ષમ કરે છે
highlight: {
/* ... */
}
}
}એપ લેવલ પર ગ્લોબલ રીતે કસ્ટમ ડાયરેક્ટિવ્સ રજીસ્ટર કરવા પણ સામાન્ય છે:
js
const app = createApp({})
// v-highlight ને તમામ ઘટકોમાં વાપરી શકાય તેવું બનાવો
app.directive('highlight', {
/* ... */
})vue માંથી GlobalDirectives ઇન્ટરફેસને વિસ્તૃત કરીને ગ્લોબલ કસ્ટમ ડાયરેક્ટિવને ટાઈપ (type) કરવી શક્ય છે.
વધુ વિગતો: Typing Custom Global Directives
કસ્ટમ ડાયરેક્ટિવ્સનો ઉપયોગ ક્યારે કરવો
કસ્ટમ ડાયરેક્ટિવ્સનો ઉપયોગ ફક્ત ત્યારે જ થવો જોઈએ જ્યારે ઇચ્છિત કાર્યક્ષમતા ફક્ત સીધા DOM મેનીપ્યુલેશન દ્વારા જ પ્રાપ્ત કરી શકાય.
આનું સામાન્ય ઉદાહરણ v-focus કસ્ટમ ડાયરેક્ટિવ છે જે એલિમેન્ટને ફોકસમાં લાવે છે.
vue
<script setup>
// ટેમ્પલેટ્સમાં v-focus સક્ષમ કરે છે
const vFocus = {
mounted: (el) => el.focus()
}
</script>
<template>
<input v-focus />
</template>આ ડાયરેક્ટિવ autofocus એટ્રિબ્યુટ કરતાં વધુ ઉપયોગી છે કારણ કે તે માત્ર પેજ લોડ પર જ કામ કરતું નથી - તે ત્યારે પણ કામ કરે છે જ્યારે એલિમેન્ટ ગતિશીલ રીતે Vue દ્વારા દાખલ કરવામાં આવે!
જ્યારે શક્ય હોય ત્યારે v-bind જેવી બિલ્ટ-ઇન ડાયરેક્ટિવ્સ સાથે ડેક્લેરેટિવ ટેમ્પલેટિંગ (Declarative templating) કરવાની ભલામણ કરવામાં આવે છે કારણ કે તે વધુ કાર્યક્ષમ છે અને સર્વર-રેન્ડરિંગ હિતેચ્છુ છે.
ડાયરેક્ટિવ હૂક્સ (Directive Hooks)
ડાયરેક્ટિવ ડેફીનેશન ઓબ્જેક્ટ ઘણા હૂક ફંક્શન્સ (બધા વૈકલ્પિક) પ્રદાન કરી શકે છે:
js
const myDirective = {
// બાઉન્ડ એલિમેન્ટના એટ્રિબ્યુટ્સ અથવા
// ઇવેન્ટ લિસનર્સ લાગુ થાય તે પહેલાં કૉલ કરવામાં આવે છે
created(el, binding, vnode) {
// આર્ગ્યુમેન્ટ્સ પર વિગતો માટે નીચે જુઓ
},
// એલિમેન્ટને DOM માં દાખલ કરવામાં આવે તે પહેલાં જ કૉલ કરવામાં આવે છે.
beforeMount(el, binding, vnode) {},
// જ્યારે બાઉન્ડ એલિમેન્ટનું પેરેન્ટ કમ્પોનન્ટ
// અને તેના તમામ બાળકો માઉન્ટ થાય ત્યારે કૉલ કરવામાં આવે છે.
mounted(el, binding, vnode) {},
// પેરેન્ટ કમ્પોનન્ટ અપડેટ થાય તે પહેલાં કૉલ કરવામાં આવે છે
beforeUpdate(el, binding, vnode, prevVnode) {},
// પેરેન્ટ કમ્પોનન્ટ અને તેના તમામ બાળકો
// અપડેટ થયા પછી કૉલ કરવામાં આવે છે
updated(el, binding, vnode, prevVnode) {},
// પેરેન્ટ કમ્પોનન્ટ અનમાઉન્ટ થાય તે પહેલાં કૉલ કરવામાં આવે છે
beforeUnmount(el, binding, vnode) {},
// જ્યારે પેરેન્ટ કમ્પોનન્ટ અનમાઉન્ટ થાય ત્યારે કૉલ કરવામાં આવે છે
unmounted(el, binding, vnode) {}
}હૂક આર્ગ્યુમેન્ટ્સ (Hook Arguments)
ડાયરેક્ટિવ હૂક્સમાં આ આર્ગ્યુમેન્ટ્સ પાસ કરવામાં આવે છે:
el: તે એલિમેન્ટ કે જેની સાથે ડાયરેક્ટિવ જોડાયેલ છે. આનો ઉપયોગ સીધા DOM ને મેનીપ્યુલેટ કરવા માટે થઈ શકે છે.binding: નીચેની પ્રોપર્ટીઝ ધરાવતી ઓબ્જેક્ટ.value: ડાયરેક્ટિવને પાસ કરેલી વેલ્યુ. ઉદાહરણ તરીકેv-my-directive="1 + 1"માં, વેલ્યુ2હશે.oldValue: અગાઉની વેલ્યુ, ફક્તbeforeUpdateઅનેupdatedમાં ઉપલબ્ધ છે. તે વેલ્યુ બદલાઈ હોય કે ન હોય તે છતાં ઉપલબ્ધ છે.arg: ડાયરેક્ટિવને પાસ કરેલી આર્ગ્યુમેન્ટ, જો કોઈ હોય તો. ઉદાહરણ તરીકેv-my-directive:fooમાં, arg"foo"હશે.modifiers: મોડિફાયર્સ ધરાવતી ઓબ્જેક્ટ, જો કોઈ હોય તો. ઉદાહરણ તરીકેv-my-directive.foo.barમાં, મોડિફાયર ઓબ્જેક્ટ{ foo: true, bar: true }હશે.instance: કમ્પોનન્ટનો ઇન્સ્ટન્સ જ્યાં ડાયરેક્ટિવનો ઉપયોગ થાય છે.dir: ડાયરેક્ટિવ ડેફીનેશન ઓબ્જેક્ટ.
vnode: બાઉન્ડ એલિમેન્ટનું પ્રતિનિધિત્વ કરતું અન્ડરલાઇંગ VNode.prevVnode: પાછલા રેન્ડરમાંથી બાઉન્ડ એલિમેન્ટનું પ્રતિનિધિત્વ કરતું VNode. ફક્તbeforeUpdateઅનેupdatedહૂક્સમાં જ ઉપલબ્ધ છે.
ઉદાહરણ તરીકે, નીચેના ડાયરેક્ટિવ વપરાશને ધ્યાનમાં લો:
template
<div v-example:foo.bar="baz">binding આર્ગ્યુમેન્ટ આ આકારની ઓબ્જેક્ટ હશે:
js
{
arg: 'foo',
modifiers: { bar: true },
value: /* `baz` ની વેલ્યુ */,
oldValue: /* અગાઉના અપડેટમાંથી `baz` ની વેલ્યુ */
}બિલ્ટ-ઇન ડાયરેક્ટિવ્સની જેમ જ, કસ્ટમ ડાયરેક્ટિવ આર્ગ્યુમેન્ટ્સ પણ ડાયનેમિક હોઈ શકે છે. ઉદાહરણ તરીકે:
template
<div v-example:[arg]="value"></div>અહીં ડાયરેક્ટિવ આર્ગ્યુમેન્ટ આપણા કમ્પોનન્ટ સ્ટેટમાંની arg પ્રોપર્ટીના આધારે રિએક્ટિવ રીતે અપડેટ થશે.
નોંધ
el સિવાય, તમારે આ આર્ગ્યુમેન્ટ્સને ફક્ત-વાંચવા (read-only) માટે જ ગણવા જોઈએ અને તેમાં ક્યારેય ફેરફાર કરવો જોઈએ નહીં. જો તમારે હૂક્સમાં માહિતી શેર કરવાની જરૂર હોય, તો એલિમેન્ટના dataset દ્વારા તેમ કરવાની ભલામણ કરવામાં આવે છે.
ફંક્શન શોર્ટહેન્ડ (Function Shorthand)
કસ્ટમ ડાયરેક્ટિવ માટે mounted અને updated માટે સમાન વર્તન હોવું સામાન્ય છે, જેમાં અન્ય હૂક્સની જરૂર નથી. આવા કિસ્સાઓમાં આપણે ડાયરેક્ટિવને ફંક્શન તરીકે વ્યાખ્યાયિત કરી શકીએ છીએ:
template
<div v-color="color"></div>js
app.directive('color', (el, binding) => {
// આ `mounted` અને `updated` બંને માટે કૉલ કરવામાં આવશે
el.style.color = binding.value
})ઓબ્જેક્ટ લિટરલ્સ (Object Literals)
જો તમારા ડાયરેક્ટિવને બહુવિધ મૂલ્યોની જરૂર હોય, તો તમે JavaScript ઓબ્જેક્ટ લિટરલ પણ પાસ કરી શકો છો. યાદ રાખો, ડાયરેક્ટિવ્સ કોઈપણ માન્ય JavaScript એક્સપ્રેશન લઈ શકે છે.
template
<div v-demo="{ color: 'white', text: 'હેલો!' }"></div>js
app.directive('demo', (el, binding) => {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "હેલો!"
})કમ્પોનન્ટ્સ પર વપરાશ
ભલામણ કરેલ નથી
કમ્પોનન્ટ્સ પર કસ્ટમ ડાયરેક્ટિવ્સનો ઉપયોગ કરવાની ભલામણ કરવામાં આવતી નથી. જ્યારે ઘટકમાં બહુવિધ રૂટ નોડ્સ હોય ત્યારે અણધાર્યું વર્તન આવી શકે છે.
જ્યારે કમ્પોનન્ટ્સ પર ઉપયોગ કરવામાં આવે છે, ત્યારે ફોલથ્રુ એટ્રિબ્યુટ્સ ની જેમ જ કસ્ટમ ડાયરેક્ટિવ્સ હંમેશા ઘટકના રૂટ નોડ પર લાગુ થશે.
template
<MyComponent v-demo="test" />template
<!-- MyComponent નું ટેમ્પલેટ -->
<div> <!-- v-demo ડાયરેક્ટિવ અહીં લાગુ કરવામાં આવશે -->
<span>મારું કમ્પોનન્ટ કન્ટેન્ટ</span>
</div>નોંધ કરો કે ઘટકો સંભવિતપણે એક કરતા વધુ રૂટ નોડ ધરાવી શકે છે. જ્યારે મલ્ટી-રૂટ કમ્પોનન્ટ પર લાગુ કરવામાં આવે છે, ત્યારે ડાયરેક્ટિવને અવગણવામાં આવશે અને ચેતવણી આપવામાં આવશે. એટ્રિબ્યુટ્સથી વિપરીત, ડાયરેક્ટિવ્સને v-bind="$attrs" સાથે અલગ એલિમેન્ટ પર પાસ કરી શકાતા નથી.