کار با منوهای آبشاری و جزئیات v-model

Working with Cascading Menus and V-Model Details

Vue.JS 2: کار با منوهای آبشاری و جزئیات v-model - قسمت 49

در قسمت قبل با کار با radiobutton ها و همچنین checkbox ها آشنا شدیم و در این قسمت به سراغ منوهای آبشاری خواهیم رفت. این منوها به کاربر اجازه می دهند از بین چندین گزینه، یک گزینه خاص را انتخاب کند. تفاوت منوهای آبشاری و radiobutton در این است که radiobutton ها معمولا گزینه های محدودی دارند (در اکثر اوقات کمتر از سه گزینه) اما منوهای آبشاری گزینه های بسیار بیشتری دارند (به طور مثال انتخاب یک شهر از بین شهرهای کشور). اگر به فایل app.vue نگاه کنید متوجه می شوید که من قالب خالی منوی آبشاری را برایتان قرار داده ام اما هیچ گزینه ای درون آن ننوشته ام. ما می خواهیم در این جلسه ابتدا منوی آبشاری را با استفاده از Vue تکمیل کنیم و سپس مقدار انتخاب شده توسط کاربر را در خصوصیت خاص خودش در data ذخیره نماییم.

در ابتدا به data رفته و گزینه های منوی آبشاری خود را تعریف می کنیم:

<script>
export default {
  data() {
    return {
      userData: {
        email: "",
        password: "",
        age: 27
      },
      message: "A new text",
      sendMail: [],
      gender: "male",
      priorities: ["High", "Medium", "Low"]
    };
  }
};
</script>

Priorities به معنی «اولویت» است که من سه گزینه high (بالا) و Medium (متوسط) و Low (پایین) را برای آن انتخاب کرده ام. در مرحله بعد با استفاده از دستور v-for درون این آرایه گردش کرده و گزینه ها را به کاربر نمایش می دهیم سپس کاربر می تواند از بین این گزینه ها، گزینه مورد نظر خودش را انتخاب کند. توجه داشته باشید که کل این فرم و همچنین گزینه های آن فرضی هستند و شما برای برنامه های واقعی باید گزینه های واقعی خودتان را پیاده سازی کنید.

حالا می توانیم با حلقه v-for بگوییم:

<div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 from-group">
  <label for="priority">Priority</label>
  <select id="priority" class="form-control">
    <option v-for="priority in priorities">{{ priority }}</option>
  </select>
</div>

نکته: اگر بخواهیم یکی از مقادیر به صورت پیش فرض انتخاب شده باشد باید به شکل زیر عمل کنیم:

<option v-for="priority in priorities" :selected="priority == 'Medium'">{{ priority }}</option>

همانطور که می دانید قابلیت selected از قابلیت های پیش فرض HTML است بنابراین با bind کردن آن به options و ذکر شرط بالا، می توانیم گزینه خودمان را انتخاب کنیم. شرط بالا می گوید اگر priority (هر کدام از آیتم های آرایه priorities در هر گردش) برابر medium بود مقدار selected را برای آن تعیین کن.

البته راه دیگری نیز برای ثبت حالت پیش فرض وجود دارد. برای انجام این کار باید خصوصیتی را که با استفاده از v-model به منوی خود متصل کرده‌ ایم برابر با مقدار پیش فرضی قرار بدهیم. با انجام این کار روش قبلی override شده و یا به زبان ساده تر باطل می شود. بنابراین من روش قبلی را حذف کرده و از روش جدید برای تعیین مقدار پیش فرض استفاده می کنم. به کد زیر توجه کنید:

<script>
export default {
  data() {
    return {
      userData: {
        email: "",
        password: "",
        age: 27
      },
      message: "A new text",
      sendMail: [],
      gender: "male",
      selectedPriority: "High",
      priorities: ["High", "Medium", "Low"]
    };
  }
};
</script>

خصوصیت selectedPriority باعث می شود دستور قبلی ما باطل شده و از این به بعد مقدار پیش فرض منوی آبشاری روی High تنظیم شود. حالا تنها کاری که باقی مانده است استفاده از دستور v-model برای متصل کردن این خصوصیت به منوی آبشاری خودمان است. نکته قابل توجه اینجاست که دستور v-model روی <option> قرار نمی گیرد بلکه روی خود تگ <select> قرار خواهد گرفت. شما می توانید این موضوع را در کد زیر مشاهده کنید:

<div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 from-group">
  <label for="priority">Priority</label>
  <select id="priority" class="form-control" v-model="selectedPriority">
    <option v-for="priority in priorities">{{ priority }}</option>
  </select>
</div>

در نهایت برای نمایش آن در panel-body مثل همیشه عمل می کنیم:

<div class="panel-body">
  <p>Mail: {{ userData.email }}</p>
  <p>Password: {{ userData.password }}</p>
  <p>Age: {{ userData.age }}</p>
  <p style="white-space: pre">Message: {{ message }}</p>
  <p>
    <strong>Send Mail?</strong>
  </p>
  <ul>
    <li v-for="item in sendMail">{{ item }}</li>
  </ul>
  <p>Gender: {{ gender }}</p>
  <p>Priority: {{ selectedPriority }}</p>
  <p>Switched:</p>
</div>

حالا اگر به مرورگر مراجعه کنید (npm run dev در حال اجرا باشد) نتیجه را به خوبی مشاهده می کنید.

تا این قسمت از کار فقط از فیلدهای پیش فرض زبان HTML استفاده کرده ایم. استفاده از این روش هیچ اشکالی ندارد و در اکثر مواقع از همین روش استفاده خواهیم کرد اما در برخی از اوقات نیاز داریم از کامپوننت های خودمان استفاده کنیم. به طور مثال من می خواهم گزینه ای را ایجاد کنم که به صورت یک سوئیچ عمل می کند، یعنی مقدار خاصی را خاموش یا روشن می کند. برای تعریف کردن این عنصر باید از ویو استفاده کنیم چرا که هیچ معادلی در زبان HTML ندارد. البته قبل از کد نویسی باید درک کنیم که دستور v-model در پشت صحنه چطور عمل می کند.

به کد زیر توجه کنید:

<div class="form-group">
  <label for="email">Mail</label>
  <input type="text" id="email" class="form-control" v-model="userData.email" />
</div>

دستور v-model کار خاصی نمی کند بلکه کار آن دقیقا معادل کد زیر است:

<div class="form-group">
  <label for="email">Mail</label>
  <input
    type="text"
    id="email"
    class="form-control"
    :value="userData.email"
    @input="userData.email = $event.target.value"
  />
</div>

این کد دقیقا همان کار قبلی را انجام می دهد. یعنی v-model ابتدا value را تنظیم می کند (مقدار پیش فرض درون input) و سپس با یک listener به نام input@ (در هنگام وارد شدن مقدار در فیلد) مقدار userData.email را روی مقدار جدید تایپ شده تنظیم می کند. توجه کنید که مقدار event$ همان رویداد عادی جاوا اسکریپیت است که به صورت خودکار ارسال می شود.

بنابراین اگر بخواهیم عنصر خاص خودمان را در HTML بسازیم، این عنصر باید:

  • دارای خصوصیت Value باشد.
  • دارای رویدادی به نام input باشد تا v-model بتواند به آن واکنش نشان دهد.

در قسمت بعد عنصر فرم خودمان را طراحی خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.