Skip to content

اتصال کلاس و استایل - Class and Style Bindings

یک نیاز رایج برای اتصال داده‌‌، دستکاری لیستِ کلاس‌ها و استایل‌های درون خطی (inline styles) یک عنصر است. از آنجا که class و style هر دو اتریبیوت تگ html هستند، می‌توانیم از v-bind برای اختصاص یک مقدار رشته‌ای به آن‌ها به صورت پویا، درست مانند سایر اتریبیوت‌ها استفاده کنیم. با این حال، تلاش برای تولید این مقادیر با استفاده از اتصال رشته‌ها می‌تواند خسته‌کننده و مستعد خطا باشد. به همین دلیل، Vue هنگامی که v-bind با class و style استفاده شود، قابلیت‌های ویژه‌ای را فراهم می‌کند. اضافه بر رشته‌ها، همچنین می‌توانند به آبجکت‌ها یا آرایه‌ها نیز متصل شوند.

اتصال کلاس‌های HTML

اتصال به آبجکت‌ها (Binding to Objects)

می‌توانیم یک آبجکت را به ‎:class (کوتاه‌شده عبارت v-bind:class) برای تعویض کلاس‌های المان به صورت پویا، ارسال کنیم:

template
<div :class="{ active: isActive }"></div>

سینتکس بالا بدین معناست که وجود کلاس active توسط درستی (Truthy) داده isActive تعیین خواهد شد.

شما می‌توانید چندین کلاس را با داشتن فیلدهای بیشتر در آبجکت تغییر دهید. علاوه بر این، دایرکتیو ‎:class همچنین می‌تواند با خاصیت ساده class هم‌زیستی داشته باشد. بنابراین با در نظر گرفتن وضعیت زیر:

js
const isActive = ref(true)
const hasError = ref(false)
js
data() {
  return {
    isActive: true,
    hasError: false
  }
}

و تمپلیت زیر:

template
<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>

به این صورت رندر خواهد شد:

template
<div class="static active"></div>

وقتی isActive یا hasError تغییر کند، لیست کلاس‌ها به ترتیب به‌روزرسانی خواهد شد. به عنوان مثال، اگر hasError به true تبدیل شود، لیست کلاس‌ها به "static active text-danger" تبدیل خواهد شد.

آبجکت متصل‌شده نیازی نیست درون‌خطی (inline) باشد:

js
const classObject = reactive({
  active: true,
  'text-danger': false
})
js
data() {
  return {
    classObject: {
      active: true,
      'text-danger': false
    }
  }
}
template
<div :class="classObject"></div>

به این صورت رندر خواهد شد:

template
<div class="active"></div>

ما همچنین می‌توانیم به یک پراپرتی computed که یک آبجکت برمی‌گرداند متصل شویم. این الگویی متداول و قدرتمند است:

js
const isActive = ref(true)
const error = ref(null)

const classObject = computed(() => ({
  active: isActive.value && !error.value,
  'text-danger': error.value && error.value.type === 'fatal'
}))
js
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
template
<div :class="classObject"></div>

اتصال به آرایه‌ها

می‌توانیم ‎:class را به یک آرایه متصل کنیم تا یک لیست از کلاس‌ها را اعمال کنیم:

js
const activeClass = ref('active')
const errorClass = ref('text-danger')
js
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}
template
<div :class="[activeClass, errorClass]"></div>

که به این صورت رندر خواهد شد:

template
<div class="active text-danger"></div>

اگر می‌خواهید یک کلاس را در لیست به صورت شرطی تغییر دهید، می‌توانید از عبارت شرطی تک خطی (ternary expression) استفاده کنید:

template
<div :class="[isActive ? activeClass : '', errorClass]"></div>

مثال بالا همیشه errorClass را اعمال خواهد کرد، اما activeClass فقط زمانی اعمال خواهد شد که isActive درست باشد.

البته، ممکن است کمی طولانی شود اگر چندین کلاس شرطی داشته باشید. به همین دلیل امکان استفاده از سینتکس آبجکت درون سینتکس آرایه وجود دارد:

template
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>

با کامپوننت‌ها

این بخش به پیش‌نیاز کامپوننت‌ها نیاز دارد. اگر می‌خواهید می‌توانید آن را رد کنید و بعدا برگردید.

وقتی شما از خاصیت class در یک کامپوننت با یک المان ریشه‌ای استفاده می‌کنید، آن کلاس‌ها به المان ریشه‌ای کامپوننت اضافه شده و با هر کلاس موجود در آن ادغام می‌شوند.

به عنوان مثال، اگر کامپوننتی به نام MyComponent با تمپلیت زیر داشته باشیم:

template
<!-- تمپلیت کامپوننت فرزند -->
<p class="foo bar">Hi!</p>

سپس برخی کلاس‌ها را هنگام استفاده از آن اضافه کنیم:

template
<!-- هنگام استفاده از کامپوننت -->
<MyComponent class="baz boo" />

HTML رندر شده به این صورت خواهد بود:

template
<p class="foo bar baz boo">Hi!</p>

همین موضوع در مورد اتصال شرطی کلاس‌ها نیز صادق است:

template
<MyComponent :class="{ active: isActive }" />

وقتی isActive درست باشد، HTML رندر شده به این صورت خواهد بود:

template
<p class="foo bar active">Hi!</p>

اگر کامپوننت شما چندین المان ریشه‌ای داشته باشد، باید مشخص کنید کدام المان این کلاس را دریافت خواهد کرد. می‌توانید این کار را با استفاده از خاصیت ‎$attrs کامپوننت انجام دهید:

template
<!-- $attrs با استفاده از MyComponent تمپلیت -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
template
<MyComponent class="baz" />

به این صورت رندر خواهد شد:

html
<p class="baz">Hi!</p>
<span>This is a child component</span>

می‌توانید در بخش خاصیت‌های Fallthrough بیشتر در مورد انتقال خاصیت‌های کامپوننت بخوانید.

اتصال استایل‌های درون‌خطی (Binding Inline Styles)

اتصال به آبجکت‌ها

‎:style از اتصال به آبجکت جاوااسکریپت پشتیبانی می‌کند - متناظر با خاصیت style عناصر HTML است:

js
const activeColor = ref('red')
const fontSize = ref(30)
js
data() {
  return {
    activeColor: 'red',
    fontSize: 30
  }
}
template
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

اگرچه کلیدهای camelCase توصیه می‌شوند، ‎:style همچنین از کلیدهای پراپرتی CSS با خط‌تیره نیز پشتیبانی می‌کند (مربوط به نحوه استفاده از آنها در CSS واقعی است) - به عنوان مثال:

template
<div :style="{ 'font-size': fontSize + 'px' }"></div>

اتصال مستقیم به یک آبجکت استایل ایده‌ی خوبی است تا تِمپلیت تمیزتر باشد:

js
const styleObject = reactive({
  color: 'red',
  fontSize: '30px'
})
js
data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}
template
<div :style="styleObject"></div>

اتصال آبجکت استایل اغلب با پراپرتی‌های computed که آبجکت برمی‌گردانند، استفاده می‌شود.

اتصال به آرایه‌ها

می‌توانیم ‎:style را به یک آرایه از چندین آبجکت استایل متصل کنیم. این آبجکت‌ها ادغام شده و به همان عنصر اعمال خواهند شد:

template
<div :style="[baseStyles, overridingStyles]"></div>

پیشوند خودکار (Auto-prefixing)

وقتی از یک خاصیت CSS که نیاز به یک vendor prefix در ‎:style دارد، استفاده می‌کنید، Vue به طور خودکار prefix مناسب را اضافه خواهد کرد. Vue این کار را با بررسی در زمان اجرا برای دیدن اینکه چه خاصیت‌های استایلی در مرورگر فعلی پشتیبانی می‌شوند، انجام می‌دهد. اگر مرورگر از یک خاصیت خاص پشتیبانی نکند، prefix های مختلف پیاده خواهند شد تا یکی پیدا شود که پشتیبانی می‌شود.

مقادیر چندگانه (Multiple Values)

می‌توانید یک آرایه از چندین مقدارِ پیشونددار را به یک پراپرتی استایل ارائه دهید، به عنوان مثال:

template
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

فقط آخرین مقدار در آرایه که مرورگر آن را پشتیبانی می‌کند، رندر خواهد شد. در این مثال، display: flex را برای مرورگرهایی که از نسخه بدون پیشوند flexbox پشتیبانی می‌کنند، رندر خواهد کرد.

اتصال کلاس و استایل - Class and Style Bindings has loaded