آموزش اضافه کردن پشتیبانی v-model به کامپوننت های سفارشی سازی شده Vue.js

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 06 خرداد 1397
دسته بندی ها : جاوا اسکریپت

v-model یکی از دستور العمل هایی است که همراه با Vue.js می آید. کاربردی بودن آن به خاطر این است که با آن می توان اتصال دو طرفه میان داده ها و view ها ایجاد کرد.

با اتصال دو طرفه داده ها، وقتی که داده هایمان را به وسیله کادر های وارد کردن اطلاعات یا هر چیز دیگری به روز رسانی می کنیم، می توانیم DOM را دستکاری کنیم.

در پایان این مقاله، پی می برید که دستور العمل v-model به ما کمک می کند داده ها را در Vue.js مدیریت کنیم. همچنین نحوه استفاده از آن برای کامپوننت های خود را نیز یاد می گیرید.

جدول محتویات:

  1. نحوه کار v-model به صورت داخلی
  2. نحوه اضافه کردن v-model به کامپوننت های سفارشی سازی شده
  3. سفارشی سازی prop ها (صفات) و event های (رویداد ها) v-model
  4. استفاده از v-model ب روی ContentEditable
  5. نتیجه گیری

نحوه کار v-model به صورت داخلی

بر اساس دانش ما در زمینه HTML، می دانیم که input، select و textarea روش های اصلی فرستادن داده ها به برنامه است.

پس فرض کنید این کد را داریم:

<input v-model="email" />

v-model آن را به این صورت بیان می کند:

<input :value="email" @input="e => email = e.target.value" />

معنای این بخش این است که v-model برای کار کردن، از عناصر و کامپوننت ها انتظار دادن که یک prop را دریافت کرده و یک event را خارج کنند.

برای عناصری مانند تگ های select و checkbox ها که چندین مقدار را قبول می کنند، Vue به طور خودکار آرایه ای از مقادیر انتخاب شده را بر می گرداند.

نحوه اضافه کردن v-model به کامپوننت های سفارشی سازی شده

برای این که به کامپوننت های خود اجازه دهیم اتصال دو طرفه v-model را پشتیبانی کنند، همانطور که پیش تر گفتم کامپوننت ها باید مقدار یک prop را دریافت کرده، و ورودی یک input را خروجی بگیرند.

بیایید کامپوننت ساده ای به نام basic-input بسازیم.

<template>
  <input @input="handleInput" />
</template>

<script>
export default {
  prop: ['value'],
  data () {
    return {
      content: this.value
    }
  },
  methods: {
    handleInput (e) {
      this.$emit('input', this.content)
    }
  }
}
</script>

همانطور که در مثال بالا مشاهده می کنید، تنها کاری که کامپوننت برای پشتیبانی v-model می کند، دریافت مقدار یک prop و خروج یک رویداد input است.

همانند همیشه از کامپوننت بالا استفاده می کنیم، و فقط دستور العمل v-model را اضافه می کنیم. به این صورت:

<basic-input v-model="email" />

پس همانطور که می بینید، اضافه کردن اتصال دو طرفه به کامپوونت های Vue ساده است. درست همانند باقی کار ها با Vue، بسیار ساده.

سفارشی سازی prop ها (صفات) و event های (رویداد ها) v-model

بیایید یک قدم جلوتر برویم. شاید نخواهیم از رویداد و صفت پیشفرض برای پشتیبانی v-model در کامپوننتمان استفاده کنیم. خوشبختانه، Vue به شما اجازه سفارشی سازی آن را می دهد.

برای سفارشی سازی رویداد و صفت، فقط صفت model را اینگونه به کامپوننتمان اضافه می کنیم و مقدار را تعریف می کنیم:

export default {
  prop: ['hidden'],
  model: {
      prop: 'hidden',
      event: 'blur'
  }
  methods: {
      handleInput (value) {
          this.$emit('blur', value)
      }
  }
}

پس از تعریف کامپوننت بالا، وقتی Vue به این بخش می رسد:

<basic-input v-model="email" />

به طور خودکار آنرا به این صورت تغییر می دهد:

<basic-input :hidden="email" @blur="e => email = e.target.value" />

با داشتن این کد در جای خودش، می تواند از بروز اختلال در هنگام تعریف رویداد ها و صفات کامپوننت خود جلوگیری کنیم.

استفاده از v-model بر روی ContentEditable ها

عناصر Content Editable (محتوای قابل ویرایش) عناصر HTML ای هستند که نمی توانند ورودی ها را دریافت کنند، اما برای انجام این کار تعریف شده اند.

اساسا، یک Content Editable یک div یا یک عنصر مشابه است، که می تواند در جهت کار مانند یک ورودی پیکربندی شود.

ما عناصر Content Editable را با اضافه کردن صفت contecteditable به عنصر، که در این مورد یک div است تعریف می کنیم.

<div class="editor" contenteditable="contenteditable"></div>

v-model بر روی عناصر Content Editable کار می کند، اما باید به صراحت از محتویات عنصر استفاده کنیم، وگرنه آن محتویات خارج نمی شوند.

منظورم این است که تعریف کامپوننت هایمان به این شکل کفایت نمی کند:

<template>
  <div contenteditable="contenteditable" @input="updateInput">
      {{ content }}
  </div>
</template>

<script>
  export default {
      prop: ['value'],
      data () {
          return { content: '' }
      },
      methods: {
          updateInput () {
              this.$emit('input', this.content)
          }
      }
  }
</script>

اگر سعی کنید از کامپوننت بالا استفاده کنید، با وجو این که ما تمام موارد مورد نیاز را سر جای خود داریم، v-model به روز رسانی نمی شود. دقیقا نمی دانم که این چرا کار نمی کند، اما فکر می کنم به خاطر این است که template (الگو) ها بازنویسی شده اند. به هر حال، راه حل ساده است، باید در عوض محتویات div را خروجی بگیریم.

برای خروجی گرفتن، باید innerText یا innerHTML را از div بگیریم. پس متود updateInput ما باید به این شکل باشد:

updateInput () {
  this.$emit('input', this.$el.innerText)
}

همچنین می توانیم از محتویات ref به جای محتویات عنصر اصلی استفاده کنیم.

با انجام این کار، v-model برای عناصر Content Editable کار خواهر کرد. همچنین می توانیم this.content را در متود updateInput به روز رسانی کنیم.

نتیجه گیری

خوش حالم که توانستید تا اینجای کار را به پایان برسانید. حال که نحوه استفاده از v-model برای کامپوننت های سفارشی سازی شده Vue را دیدید، بروید و آن دسته از کامپوننت هایتان که به v-model احتیاج دارند را ویرایش کنید.

منبع

مقالات پیشنهادی

بهترین ابزارهای نمونه‌سازی و مزایای استفاده از آنها

وقتی به یک طراح با تجربه تبدیل شوید، درست می‌دانید می‌خواهید چه کاری انجام دهید. اما تا زمانی که شما آن را در عمل مشاهده نکنید، هیچوقت نمی‌دانید که طر...

افسانه های UX - گرافیک می تواند به دیداری کردن قسمتی از وب کمک کند

یکی از حقه های اکثر طراحان وب برای نمایش بهتر و جلب توجه کاربران نسبت به یک قسمت از وبسایت استفاده از گرافیک سنگین و جلوه های نمایشی فلش می باشد. شاید...

دلایل بهینه‌سازی وبسایت

زمانی که شرکت‌ها شروع به ساخت یک وبسایت می‌کنند مطمئنا از انجام این‌ کار هدفی دارند. ممکن است آن‌ها قصد داشته باشند تا نام یک برند را معروف کنند و یا...

بهترین ابزارهای فشرده‌سازی تصاویر برای محیط وب

در این موضوع که حجم صفحات وب هر روز در حال افزایش است هیچ شکی نیست. ما هر روز موارد جانبی بیشتری به وبسایت اضافه می‌کنیم که در نتیجه باعث می‌شود تا سر...