Skip to content

اتصال 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) جاوااسکریپت فعلی را به عنوان منبع حقیقی در نظر می گیرد. شما باید مقدار اولیه را در سمت جاوا اسکریپت با استفاده از آپشن datareactivity 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([])
js
export default {
  data() {
    return {
      checkedNames: []
    }
  }
}
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' }
])
js
export default {
  data() {
    return {
      selected: 'A',
      options: [
        { 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 مطالعه کنید.

اتصال input در فرم has loaded