|
|
3 settimane fa | |
|---|---|---|
| .. | ||
| AppLink | 3 settimane fa | |
| README.md | 3 settimane fa | |
| index.coffee | 3 settimane fa | |
| index.pug | 3 settimane fa | |
| index.styl | 3 settimane fa | |
AppLink - универсальный компонент для работы со ссылками в приложении. Автоматически определяет тип ссылки (внутренняя/внешняя) и использует соответствующий компонент (router-link для внутренних маршрутов, a для внешних URL). Обеспечивает единообразие поведения, безопасности и стилизации всех ссылок в приложении.
https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/src/master/vue/app/shared/AppLink/
# В основном файле приложения (app/temp.coffee)
components:
'app-link': require 'app/shared/AppLink'
app-link(to="/about") О нас
app-link(to="https://example.com") Внешний сайт
to (обязательный)String | ObjectПримеры:
//- Строковый путь
app-link(to="/events")
//- Объект маршрута Vue Router
app-link(:to="{ name: 'EventDetail', params: { id: event._id } }")
//- Внешний URL
app-link(to="https://facebook.com/borbad")
//- Email ссылка
app-link(to="mailto:info@borbad.s5l.ru")
//- Телефонная ссылка
app-link(to="tel:+992371234567")
href (опциональный)String''Пример:
app-link(href="https://example.com" to="/fallback") Ссылка
target (опциональный)String'_self''_self', '_blank', '_parent', '_top'Пример:
app-link(to="https://example.com" target="_blank") Открыть в новом окне
rel (опциональный)String''target="_blank" автоматически добавляется noopener noreferrerПример:
app-link(to="https://example.com" rel="nofollow") Ссылка nofollow
class (опциональный)String | Object | Array''Примеры:
//- Строка
app-link(to="/" class="text-blue-600 hover:text-blue-800")
//- Объект
app-link(to="/" :class="{ 'font-bold': isActive }")
//- Массив
app-link(to="/" :class="['text-blue-600', 'hover:text-blue-800']")
activeClass (опциональный)String'app-link--active'Пример:
app-link(to="/events" active-class="bg-blue-100 text-blue-800")
exact (опциональный)BooleanfalseПример:
app-link(to="/" exact) Главная
@clickEvent объектПример:
app-link(to="/events" @click="handleEventClick")
[body] (основной слот)Примеры:
//- Текстовое содержимое
app-link(to="/events") Все мероприятия
//- HTML содержимое
app-link(to="/events")
div(class="flex items-center")
span Мероприятия
icon(name="arrow-right")
//- Компоненты внутри
app-link(to="/cart")
cart-icon
span Корзина
badge(:count="cartCount")
.app-link - основной класс компонента.app-link--active - класс активного состояния (по умолчанию)app-link(to="/" class="app-link--sm") Маленькая
app-link(to="/" class="app-link--md") Средняя
app-link(to="/" class="app-link--lg") Большая
//- Основной стиль
app-link(to="/" class="app-link--primary") Основная
//- Вторичный стиль
app-link(to="/" class="app-link--secondary") Вторичная
//- Текстовый стиль
app-link(to="/" class="app-link--text") Текстовая
//- С иконкой внешней ссылки
app-link(to="https://example.com" class="app-link--external") Внешняя
//- Без подчеркивания
app-link(to="/" class="no-underline") Без подчеркивания
//- Подчеркивание при hover
app-link(to="/" class="underline-on-hover") Подчеркивание при наведении
nav(class="flex space-x-6")
app-link(
to="/"
exact
active-class="text-blue-600 border-blue-600"
class="pb-2 border-b-2 border-transparent transition-colors"
) Главная
app-link(
to="/events"
active-class="text-blue-600 border-blue-600"
class="pb-2 border-b-2 border-transparent transition-colors"
) Мероприятия
app-link(
to="/blog"
active-class="text-blue-600 border-blue-600"
class="pb-2 border-b-2 border-transparent transition-colors"
) Блог
div(
v-for="event in events"
:key="event._id"
class="bg-white rounded-lg shadow-md overflow-hidden"
)
app-link(:to="'/events/' + event._id")
img(:src="event.image" :alt="event.title" class="w-full h-48 object-cover")
div(class="p-4")
h3(class="text-lg font-semibold mb-2") {{ event.title }}
p(class="text-gray-600 mb-2") {{ event.event_data.location }}
p(class="text-gray-500 text-sm") {{ formatDate(event.event_data.event_date) }}
div(class="flex space-x-4")
app-link(
to="https://facebook.com/borbad"
target="_blank"
rel="noopener noreferrer"
class="app-link--external text-gray-600 hover:text-blue-600"
)
icon(name="facebook" class="w-6 h-6")
app-link(
to="https://instagram.com/borbad"
target="_blank"
rel="noopener noreferrer"
class="app-link--external text-gray-600 hover:text-pink-600"
)
icon(name="instagram" class="w-6 h-6")
div(class="flex space-x-4")
app-link(
to="/events"
class="app-link--primary app-link--lg"
) Смотреть мероприятия
app-link(
to="/contacts"
class="app-link--secondary app-link--lg"
) Связаться с нами
app-link(
:to="{
path: '/events',
query: {
category: 'music',
date: '2024-03'
}
}"
class="text-blue-600 hover:text-blue-800"
) Музыкальные мероприятия марта
app-link(
:to="{
name: 'BlogPost',
params: {
id: post._id,
slug: post.slug
}
}"
class="block p-6 bg-white rounded-lg shadow hover:shadow-md transition-shadow"
)
h3(class="text-xl font-semibold mb-2") {{ post.title }}
p(class="text-gray-600") {{ post.excerpt }}
div(class="space-y-2")
app-link(
to="mailto:info@borbad.s5l.ru"
class="text-blue-600 hover:text-blue-800"
) info@borbad.s5l.ru
app-link(
to="tel:+992371234567"
class="text-blue-600 hover:text-blue-800"
) +992 37 123-45-67
# Внутренние ссылки
'/about'
'/events/123'
{ name: 'Home' }
{ path: '/blog', query: { category: 'news' } }
# Внешние ссылки
'https://example.com'
'//cdn.example.com/image.jpg'
'mailto:test@example.com'
'tel:+1234567890'
'ftp://example.com'
'#section'
rel="noopener noreferrer" для target="_blank"# В обработчиках событий
handleExternalClick: (event) ->
EventBus.emit('external_link_clicked', {
url: @normalizedHref
target: @target
})
handleInternalClick: (event) ->
EventBus.emit('internal_link_clicked', {
to: @normalizedTo
route: @$route
})
// В глобальных стилях
.app-link--custom
@apply bg-gradient-to-r from-purple-500 to-pink-500 text-white
&:hover
@apply from-purple-600 to-pink-600
&.app-link--active
@apply from-purple-700 to-pink-700
# Создание производного компонента
CustomAppLink =
name: 'CustomAppLink'
extends: require 'app/shared/AppLink'
methods:
handleExternalClick: (event) ->
# Дополнительная логика
analytics.track('external_link_click', { url: @normalizedHref })
# Вызов родительского метода
@$super.handleExternalClick(event)
app-link(
:to="linkUrl"
:class="{ 'border-green-500': $el.isRouterLink, 'border-red-500': $el.isExternalLink }"
) Ссылка
# В основном приложении
EventBus.on 'external_link_clicked', (data) ->
debug.log "Внешняя ссылка: "+data.url
EventBus.on 'internal_link_clicked', (data) ->
debug.log "Внутренняя ссылка: "+JSON.stringify(data.to)
//- Правильно
app-link(to="/about") О нас
//- Неправильно
a(href="/about") О нас
router-link(to="/about") О нас
//- Правильно
app-link(to="https://example.com" target="_blank") Ссылка
//- Опасно (без rel)
app-link(to="https://example.com" target="_blank" rel="") Ссылка
//- Правильно
app-link(:to="{ name: 'EventDetail', params: { id: event._id } }") {{ event.title }}
//- Менее предпочтительно
app-link(:to="'/events/' + event._id") {{ event.title }}
//- Правильно
app-link(to="/events")
span Мероприятия
icon(name="arrow-right")
//- Неправильно (не семантично)
app-link(to="/events") > Мероприятия >
Компонент AppLink обеспечивает единообразное, безопасное и удобное использование ссылок во всем приложении, автоматически обрабатывая различные сценарии и предоставляя богатые возможности для кастомизации.