استایل‌دهی لینک فعال

Active Link Styling

25 آبان 1399
Vue.JS 2: استایل دهی لینک فعال - قسمت 78

در قسمت قبل لینک هایی را ایجاد کردیم که با کلیک روی آن ها بتوانیم بین کامپوننت های مختلف جابجا شویم. همچنین در مورد حالت های history و hash صحبت کردیم و تفاوت های آن ها را بررسی نمودیم اما مشکلی که وجود داشت، مشخص نبودن کامپوننت نمایش داده شده از طریق لینک ها بود. یعنی اگر تگ های h1 را نداشتیم که بالای صفحه نام کامپوننت را بنویسند، قابلیت تشخیص کامپوننت ها را نداشتیم. برای حل این مسئله بهتر است که لینک ها را به صورتی استایل دهی کنیم که لینک فعال شده مشخص باشد. خوشبختانه بوت استرپ یک کلاس active دارد که به عنصر پدر (<li>)متصل شده و می تواند این استایل دهی را برای ما انجام دهد اما مشکلی وجود دارد.

قبل از توضیح مشکل باید مفهومی را مرور کنیم تا دقیقا متوجه صحبت من بشوید. وقتی از فعال بودن یک لینک صحبت می کنیم منظورمان چیست؟ در زبان CSS وضعیت active در یک لینک همان فعال بودن لینک است. به طور مثال:

a:active { color:green;}

یعنی زمانی که لینک فعال شد آن را به رنگ سبز تغییر بده. این وضعیت زمانی رخ می دهد که روی لینک کلیک کنیم (همان چند صدم ثانیه ای که دستمان را روی کلیک چپ نگه داشته ایم). مثلا می توانید روی لینکی بروید و کلیک چپ را نگه دارید اما رها نکنید. در این حالت لینک Active یا فعال است؛ آن را با حالت های hover (رفتن موس روی لینک بدون کلیک) یا  visited (لینک قبلا باز شده باشد) اشتباه نگیرید.

اما زمانی که در این قسمت از دوره Vue راجع به فعال بودن یک لینک صحبت می کنیم منظورمان چیز دیگری است (از جنبه دیگری آن را بررسی می کنیم). زمانی که از فعال بودن یک لینک در برنامه SPA خود در Vue صحبت می کنیم، یعنی در صفحه ای باشیم که آن لینک به آدرس آن اشاره دارد. مثلا اگر لینک ما به کامپوننت user اشاره می کند و URL فعلی مرورگر نیز به صورت localhost:8080/user باشد، یعنی لینک ما باید در وضعیت فعال قرار بگیرد و استایل های CSS ای بگیرد که نشان دهد در آن صفحه هستیم.

کامپوننت router-link که از آن برای لینک های خودمان استفاده کرده ایم، به صورت خودکار کلاس router-link-active را به تگ های <a> می چسباند بنابراین در دو مشکل داریم:

  • نام اشتباه کلاس: کلاس به جای router-link-active باید active باشد چرا که بوت استرپ کلاس router-link-active را نمی شناسد.
  • اضافه شدن کلاس به عنصر اشتباه: کلاس اضافه شده به عنصر <a> اضافه می شود در صورتی که باید به <li> اضافه شود.

ساختار کد در جلسه قبل (فایل Header.vue):

<template>
  <ul class="nav nav-pills">
    <li role="presentation">
      <router-link to="/">Home</router-link>
    </li>
    <li role="presentation">
      <router-link to="/user">User</router-link>
    </li>
  </ul>
</template>

برای حل این مشکل باید <li> ها را حذف کرده و فقط از کامپوننت router-link استفاده کنیم. سپس خصوصیتی به نام tag را با مقدار li به router-link می دهیم تا خودش یک <li> را برای ما بسازد. در حالت پیش فرض router-link به تگ <a> تبدیل می شود اما با مشخص کردن مقدار برای tag به آن می گوییم که به <li> تبدیل شود. در مرحله بعد تگ های <a> را درون router-link می گذاریم. با این کار، مشکل اضافه شدن کلاس به تگ اشتباه را حل کرده ایم. از طرف دیگر برای تغییر کلاس می توانیم از خصوصیت active-class روی router-link استفاده کنیم. هر مقداری را که به این خصوصیت بدهید، در زمان فعال شدن لینک، به عنوان کلاس به لینک داده می شود. با این حساب می توان گفت:

<template>
  <ul class="nav nav-pills">
    <router-link to="/" tag="li" active-class="active">
      <a>Home</a>
    </router-link>
    <router-link to="/user" tag="li" active-class="active">
      <a>User</a>
    </router-link>
  </ul>
</template>

یعنی هر زمان که این لینک ها فعال شوند (روی آن ها کلیک شود) کلاس Active به آن ها داده می شود. از طرفی این کلاس در بوت استرپ شناخته شده و استایل های مورد نظر ما به آن اضافه خواهد شد. اگر کد ها را ذخیره کرده و به مرورگر بروید متوجه اشکالی در برنامه می شوید. فارغ از اینکه روی لینک Home یا User کلیک کنیم، Home همیشه فعال می ماند. به نظر شما مشکل کجاست؟

نحوه اعمال کلاس active در Vue بدین شکل است:

  • کامپوننت router-link به مقدار خصوصیت to نگاه می کند.
  • اگر URL مرورگرِ کاربر با مقدار پاس داده شده به to شروع شود، یعنی لینک فعال شده است.

آیا متوجه مشکل می شوید؟ ما مقدار to در اولین لینک را / گذاشته ایم (یعنی صفحه اصلی):

localhost:8080/

از طرفی تمام صفحات ما با همین / شروع می شود چرا که دیگر صفحات جزئی از صفحه اصلی هستند. مثلا برای صفحه user چنین آدرسی را داریم:

localhost:8080/user

همانطور که می بینید در user نیز پس از 8080 علامت / را داریم. در وب سایت های واقعی با سرور های واقعی نیز همینطور است. مثلا اگر آدرس سایت ما roxo.ir باشد، صفحات مختلف ما بدین شکل خواهد بود:

roxo.ir/plus

roxo.ir/authors

roxo.ir/category/%d8%b3%d8%a6%d9%88

به همین دلیل است که Home همیشه فعال باقی می ماند. این رفتار برای لینک هایی خوب است که پس از مقدار to اطلاعاتی اضافه دارند (مثل #). مثلا اگر به To مقدار user/ را بدهیم، صفحه زیر باید همچنان فعال باشد:

localhost:8080/user#Amir

این رفتار برای چنین URL ای بسیار خوب است اما اینجا که بحث از صفحه اصلی می باشد باید رفتار پیش فرض را تغییر بدهیم. برای این کار به لینک / عبارت exact (به معنی «دقیق» یا «عینی») را اضافه می کنیم:

<template>
  <ul class="nav nav-pills">
    <router-link to="/" tag="li" active-class="active" exact>
      <a>Home</a>
    </router-link>
    <router-link to="/user" tag="li" active-class="active">
      <a>User</a>
    </router-link>
  </ul>
</template>

با اضافه کردن exact به Vue می گوییم که صفحاتی را به عنوان فعال در نظر بگیر که «دقیقا» برابر با / باشند نه اینکه با / شروع شوند. حالا اگر مرورگر را باز کنید و کد ها را تست نمایید همه چیز بدون مشکل اجرا می شود و لینک ها فقط زمانی فعال هستند که در کامپوننت مورد نظر باشیم.

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

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