اتصال input در فرم
هنگامی که با فرمها در فرانتاند سروکار داریم، اغلب نیاز داریم که دادههای المنتهای input فرم را با متغیر مربوطه در جاوااسکریپت همگام سازی کنیم. اتصال دستی داده و رویدادهای تغییر داده به یکدیگر میتواند دشوار باشد:
template
<input
:value="text"
@input="event => text = event.target.value">
دایرکتیو v-model
به ما کمک می کند تا کد بالا را به صورت زیر خلاصه کنیم:
template
<input v-model="text">
علاوه بر این، v-model
را میتوان در انواع مختلف المنتهای ورودی مانند <textarea>
و <select>
استفاده کرد. بر اساس المنتی که روی آن استفاده می شود، به طور خودکار به پراپرتی مخصوص و رویداد ویژه DOM وصل میشود:
- المنتهای
<textarea>
و<input>
با تایپهای نوشتاری (text types) ، از پراپرتیvalue
و رویدادinput
استفاده میکنند. <input type="checkbox">
و<input type="radio">
از پراپرتیchecked
و رویدادchange
استفاده می کنند.- المنت
<select>
ازvalue
بعنوان پراپ و ازchange
بعنوان رویداد استفاده میکند.
نکته
v-model
مقدار دهیهای اولیه value
، checked
یا selected
موجود در المنتهای فرم را نادیده میگیرد. همیشه اِستیت (state) جاوااسکریپت فعلی را به عنوان منبع حقیقی در نظر می گیرد. شما باید مقدار اولیه را در سمت جاوا اسکریپت با استفاده از reactivity APIs اعلام کنید.
استفاده پایه
Text
template
<p>پیام برابر است با: {{ message }}</p>
<input v-model="message" placeholder="متن را وارد کنید" />
پیام برابر است با:
نکته
برای زبان هایی که به IME نیاز دارند (چینی، ژاپنی، کره ای و غیره)، متوجه خواهید شد که v-model
در طول ترکیب IME به روز نمی شود. اگر میخواهید به این بهروزرسانیها نیز پاسخ دهید، بهجای استفاده از v-model
از شنونده رویداد input
و پیوند value
خود استفاده کنید.
Multiline text
template
<span>پیام چند خطی برابر است با:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="چند خط متن وارد کنید"></textarea>
پیام چند خطی برابر است با:
توجه کنید که گذاشتن متن درون <textarea>
کار نخواهد کرد. به جای آن از v-model
استفاده کنید.
template
<!-- بد -->
<textarea>{{ text }}</textarea>
<!-- خوب -->
<textarea v-model="text"></textarea>
Checkbox
checkbox منفرد، مقدار boolean:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
همچنین میتوانیم چندین چک باکس را به یک آرایه یا مقدار Set متصل کنیم
js
const checkedNames = ref([])
template
<div>Checked names: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
Checked names: []
در این حالت، آرایه checkedNames
همیشه حاوی مقادیر چک باکسهای فعال خواهد بود.
Radio
template
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
Picked:
Select
select منفرد:
template
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected:
توصیه
اگر مقدار اولیه عبارت v-model
شما با هیچ یک از گزینهها (options) مطابقت نداشته باشد، المنت <select>
در حالت «انتخاب نشده» نمایش داده می شود. در iOS این باعث میشود که کاربر نتواند اولین مورد را انتخاب کند زیرا iOS رویداد change را در این مورد اجرا نمیکند. بنابراین توصیه میشود همانطور که در مثال بالا نشان داده شده است، یک option غیرفعال با مقدار خالی ارائه کنید.
Multiple select (متصل به آرایه):
template
<div>Selected: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected: []
optionهای select را می توان به صورت پویا با v-for
رندر کرد:
js
const selected = ref('A')
const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
template
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
پیوندهای مقدار (Value Bindings)
برای رادیو، چک باکس و optionهای Select، مقادیر اتصال v-model
معمولاً رشتههای ثابت (یا بولین برای چک باکس) هستند:
template
<!-- میشود "a" هنگام انتخاب شدن برابر با مقدار رشته `picked` متغیر -->
<input type="radio" v-model="picked" value="a" />
<!-- false میشود یا true یا `toggle` متغیر -->
<input type="checkbox" v-model="toggle" />
<!-- میشود "abc" هنگامی که اولین آپشن انتخاب شود برابر با مقدار رشته `selected` متغیر -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
اما گاهی اوقات ممکن است بخواهیم مقدار آن را به یک پراپرتی پویا در نمونه فعال فعلی متصل کنیم. برای رسیدن به این هدف میتوانیم از v-bind
استفاده کنیم. علاوه بر این، استفاده از v-bind
به ما این امکان را می دهد که مقدار ورودی (input) را به مقادیر غیر رشتهای متصل کنیم.
Checkbox
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
true-value
و false-value
ویژگیهای مخصوص Vue هستند که فقط با v-model
کار میکنند. با علامت زدن کادر روی 'yes'
و وقتی علامت آن را بردارید روی 'no'
تنظیم می شود. همچنین میتوانید با استفاده از v-bind
آنها را به مقادیر پویا متصل کنید:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
توصیه
ویژگیهای true-value
و false-value
بر ویژگی value
اینپوت تأثیر نمیگذارند، زیرا مرورگرها چکباکسهای علامتنخورده را در فرم ارسالی درج نمیکنند. برای تضمین اینکه یکی از دو مقدار در یک فرم ارسال میشود (به عنوان مثال "بله" یا "خیر")، به جای آن از اینپوتهای رادیویی استفاده کنید.
Radio
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
وقتی اولین ورودی رادیویی علامت زده میشود، متغیر pick
روی مقدار first
تنظیم میشود و وقتی ورودی دوم انتخاب میشود روی مقدار second
تنظیم میشود.
Select Options
template
<select v-model="selected">
<!-- inline object literal -->
<option :value="{ number: 123 }">123</option>
</select>
v-model
از اتصال داده مقادیر غیر رشتهای نیز پشتیبانی میکند! در مثال بالا هنگامی که option انتخاب شده است، selected
به آبجکت { number: 123 }
تنظیم میشود.
تغییردهندهها (Modifiers)
.lazy
بهطور پیشفرض، v-model
اینپوت را با دادهها پس از هر رویداد input
همگامسازی میکند (به استثنای ترکیب IME همانطور که در بالا بیان شد). میتوانید پس از رویدادهای change
به جای همگامسازی، تغییردهنده lazy
را اضافه کنید:
template
<!-- "input" به جای "change" همگام سازی بعد از -->
<input v-model.lazy="msg" />
.number
اگر میخواهید ورودی کاربر بهطور خودکار به صورت عددی تایپ شود، میتوانید تغییردهنده number
را به اینپوتهای v-model
خود اضافه کنید:
template
<input v-model.number="age" />
اگر ورودی را نتوان با parseFloat()
تجزیه کرد، به جای آن از مقدار اصلی (رشتهای) استفاده میشود. به طور خاص، اگر ورودی خالی باشد (مثلاً پس از اینکه کاربر فیلد ورودی را پاک کرد)، یک رشته خالی برگردانده میشود. این رفتار با خاصیت DOM به نام valueAsNumber
متفاوت است.
اگر اینپوت دارای type="number"
باشد، تغییردهنده number
بهطور خودکار اعمال میشود.
.trim
اگر میخواهید فضای خالی اینپوت کاربر بهطور خودکار بریده شود، میتوانید تغییردهنده trim
را به ورودیهای مدیریتشده v-model
خود اضافه کنید:
template
<input v-model.trim="msg" />
v-model
در کامپوننتها
اگر هنوز با کامپوننت های Vue آشنا نیستید، می توانید از خواندن این قسمت صرف نظر کنید.
انواع اینپوتهای نهادینه شده HTML همیشه نیازهای شما را برآورده نمیکند. خوشبختانه، کامپوننتهای Vue به شما این امکان را میدهد که اینپوتهای قابل استفاده مجدد را با رفتار کاملاً سفارشی سازی شده بسازید. این اینپوتها حتی با v-model
کار میکنند! برای کسب اطلاعات بیشتر، در راهنمای کامپوننتها درباره کاربرد v-model
مطالعه کنید.