# ZeenSpeakerSection
ZeenSpeakerSection секция включающая в себя слайдер и набор карточек с данными спикера
# Примеры:
Все значения по умолчанию
:speakers="speakers"
Спикеры
Смена позиции стрелок слайдера
:speakers="speakers"
:arrow-position="'bottom'"Спикеры
Активация пагинации
:speakers="speakers"
:arrow-position="'bottom'"
is-paginationСпикеры
Передача данных в карточку спикера
:speakers="speakers"
:arrow-position="'bottom'"
:attrsSpeaker="{
theme: 'main', }"
is-paginationСпикеры
# Slots
Название | Описание |
---|---|
top-icon-next | Топ иконка next |
top-icon-prev | Топ иконка prev |
icon-next | Нижняя иконка next |
icon-prev | Нижняя иконка prev |
# props
Название | Тип | Обязательный | По умолчанию | Описание |
---|---|---|---|---|
speakers | Object | + | - | Принимает в себя объект с данными спикера совпадает с данными которые приходят с сервера подробнее см. ниже |
mainHeadlineAttrs | Object | - | - | Принимает в себя объект с props для компонента ZeenHeadline, где ключом будет является props который ожидает получить компонент ZeenHeadline, а значением будет являтся присваемовое значение |
breakpoints | Object | - | - | Объект с брейкпоинтами |
title | String | - | Спикеры | Заголовок блока спикеров |
arrowPosition | String | - | top | Принимает два значения top и bottom. Перемещает вверх или вниз стрелки слайдера |
isPagination | Boolean | - | false | Наличие пагинации |
isClickableBullets | Boolean | - | true | Будут ли кликабельными буллиты в слайдере |
# Speakers - код объекта
Код объекта
export default [
{
id: '3bb4a22f-d533-404a-8d2f-7ad4e1d89f5214',
login: 'spe4',
phone: '555-35-35',
picture: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
gender: '',
birthdate: null,
country: '',
city: '',
company_name: 'Компания',
facebook_link: '1',
vk_link: '2',
twitter_link: '3',
instagram_link: '4',
company_field_list: [],
interest_list: [],
name: 'Константин Константинопольский',
about: 'Специальная специализация, которую специально написали и растянули на три строки',
position: 'Главный дизайнер',
verified: false,
onboarding_passed: false,
registered_conference_id: null,
reg_conf_id: null,
message_privacy: 'all_users',
mailing_policies: {},
locale: 'ru',
email: 'spe4@spe4',
avatar_url: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
speech_ids: ['3d2a60af-71ad-4097-a9b6-9c3c94a5bafc', 'ad41dc63-d924-4b47-a88a-1cab1c49e886'],
priority: 0,
created_at: 1619469432,
},
{
id: '3bb4a22f-d533-404a-8d2f-7ad4e1d89f1452',
login: 'spe4',
phone: '555-35-35',
picture: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
gender: '',
birthdate: null,
country: '',
city: '',
company_name: 'Компания',
facebook_link: '1',
vk_link: '2',
twitter_link: '3',
instagram_link: '4',
company_field_list: [],
interest_list: [],
name: 'Константин Константинопольский',
about: 'Специальная специализация, которую специально написали и растянули на три строки',
position: 'Главный дизайнер',
verified: false,
onboarding_passed: false,
registered_conference_id: null,
reg_conf_id: null,
message_privacy: 'all_users',
mailing_policies: {},
locale: 'ru',
email: 'spe4@spe4',
avatar_url: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
speech_ids: ['3d2a60af-71ad-4097-a9b6-9c3c94a5bafc', 'ad41dc63-d924-4b47-a88a-1cab1c49e886'],
priority: 0,
created_at: 1619469432,
},
{
id: '3bb4a22f-d533-404a-8d2f-7ad4e1d8149f52',
login: 'spe4',
phone: '555-35-35',
picture: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
gender: '',
birthdate: null,
country: '',
city: '',
company_name: 'Компания',
facebook_link: '1',
vk_link: '2',
twitter_link: '3',
instagram_link: '4',
company_field_list: [],
interest_list: [],
name: 'Константин Константинопольский',
about: 'Специальная специализация, которую специально написали и растянули на три строки',
position: 'Главный дизайнер',
verified: false,
onboarding_passed: false,
registered_conference_id: null,
reg_conf_id: null,
message_privacy: 'all_users',
mailing_policies: {},
locale: 'ru',
email: 'spe4@spe4',
avatar_url: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
speech_ids: ['3d2a60af-71ad-4097-a9b6-9c3c94a5bafc', 'ad41dc63-d924-4b47-a88a-1cab1c49e886'],
priority: 0,
created_at: 1619469432,
},
{
id: '3bb4a22f-d533-404a-8d2f-7ad4e1d1489f52',
login: 'spe4',
phone: '555-35-35',
picture: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
gender: '',
birthdate: null,
country: '',
city: '',
company_name: 'Компания',
facebook_link: '1',
vk_link: '2',
twitter_link: '3',
instagram_link: '4',
company_field_list: [],
interest_list: [],
name: 'Константин Константинопольский',
about: 'Специальная специализация, которую специально написали и растянули на три строки',
position: 'Главный дизайнер',
verified: false,
onboarding_passed: false,
registered_conference_id: null,
reg_conf_id: null,
message_privacy: 'all_users',
mailing_policies: {},
locale: 'ru',
email: 'spe4@spe4',
avatar_url: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
speech_ids: ['3d2a60af-71ad-4097-a9b6-9c3c94a5bafc', 'ad41dc63-d924-4b47-a88a-1cab1c49e886'],
priority: 0,
created_at: 1619469432,
},
{
id: '3bb4a22f-d533-404a-8d2f-7ad4e1d254189f52',
login: 'spe4',
phone: '555-35-35',
picture: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
gender: '',
birthdate: null,
country: '',
city: '',
company_name: 'Компания',
facebook_link: '1',
vk_link: '2',
twitter_link: '3',
instagram_link: '4',
company_field_list: [],
interest_list: [],
name: 'Константин Константинопольский',
about: 'Специальная специализация, которую специально написали и растянули на три строки',
position: 'Главный дизайнер',
verified: false,
onboarding_passed: false,
registered_conference_id: null,
reg_conf_id: null,
message_privacy: 'all_users',
mailing_policies: {},
locale: 'ru',
email: 'spe4@spe4',
avatar_url: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
speech_ids: ['3d2a60af-71ad-4097-a9b6-9c3c94a5bafc', 'ad41dc63-d924-4b47-a88a-1cab1c49e886'],
priority: 0,
created_at: 1619469432,
},
{
id: '3bb4a22f-d533-404a-8d2f-7ad2542544e1d89f52',
login: 'spe4',
phone: '555-35-35',
picture: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
gender: '',
birthdate: null,
country: '',
city: '',
company_name: 'Компания',
facebook_link: '1',
vk_link: '2',
twitter_link: '3',
instagram_link: '4',
company_field_list: [],
interest_list: [],
name: 'Константин Константинопольский',
about: 'Специальная специализация, которую специально написали и растянули на три строки',
position: 'Главный дизайнер',
verified: false,
onboarding_passed: false,
registered_conference_id: null,
reg_conf_id: null,
message_privacy: 'all_users',
mailing_policies: {},
locale: 'ru',
email: 'spe4@spe4',
avatar_url: 'https://enel.com.tr/wp-content/uploads/2019/10/mt-2.jpg',
speech_ids: ['3d2a60af-71ad-4097-a9b6-9c3c94a5bafc', 'ad41dc63-d924-4b47-a88a-1cab1c49e886'],
priority: 0,
created_at: 1619469432,
},
]
# Source Code - исходный код компонента
<template>
<section class="speaker-section" ref="main">
<ZeenContainer>
<div class="swiper">
<div class="speaker-section__actions js-program-actions">
<ZeenHeadline class="speaker-section__main-headline" v-bind="mainHeadlineAttrs">{{ title }}</ZeenHeadline>
<slot name="top-btn" />
<div v-if="arrowPosition === 'top'" class="speaker-section__buttons-group">
<button class="js-program-btn js-program-next swiper-button-disabled speaker-section__btn" ref="btnPrevTop">
<slot name="top-icon-next">
<svg width="6" height="11" viewBox="0 0 6 11" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.35667 0.252601C4.94389 -0.114317 4.31182 -0.077136 3.9449 0.335647L0.252591 4.48949C-0.0841969 4.86838 -0.0841969 5.43933 0.252591 5.81822L3.9449 9.97207C4.31182 10.3848 4.94389 10.422 5.35667 10.0551C5.76945 9.68819 5.80664 9.05612 5.43972 8.64334L2.33795 5.15386L5.43972 1.66437C5.80664 1.25159 5.76945 0.619519 5.35667 0.252601Z"
/>
</svg>
</slot>
</button>
<button class="js-program-btn js-program-prev speaker-section__btn" ref="btnNextTop">
<slot name="top-icon-prev">
<svg width="6" height="11" viewBox="0 0 6 11" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.35576 10.055C4.94298 10.4219 4.3109 10.3848 3.94399 9.97197L0.251678 5.81812C-0.0851092 5.43924 -0.0851092 4.86828 0.251678 4.4894L3.94399 0.33555C4.3109 -0.0772324 4.94298 -0.114413 5.35576 0.252505C5.76854 0.619423 5.80572 1.2515 5.4388 1.66428L2.33704 5.15376L5.4388 8.64324C5.80572 9.05603 5.76854 9.6881 5.35576 10.055Z"
/>
</svg>
</slot>
</button>
</div>
</div>
<div class="speaker-section__swiper swiper-container" ref="slider">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="speaker in speakers" :key="speaker.id">
<ZeenSpeakerCard
:speaker="speaker"
:picture-attrs="{src: speaker.picture}"
v-bind="attrsSpeaker"
v-on="speakerEvents"
>
<template v-for="(slot, slotName) in speakerSlots" v-slot:[slotName]="params">
<slot :name="`${speakerPrefix}${slotName}`" v-bind="params" />
</template>
</ZeenSpeakerCard>
</div>
<slot name="swiper-part" />
</div>
<div v-if="isPagination" class="swiper-pagination" ref="pagination"></div>
</div>
<div
v-if="arrowPosition === 'bottom'"
class="speaker-section__buttons-group speaker-section__buttons-group_bottom"
>
<button
class="js-program-btn js-program-prev swiper-button-disabled speaker-section__btn"
ref="btnPrevBottom"
>
<slot name="icon-prev">
<svg width="6" height="11" viewBox="0 0 6 11" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.335647 0.252601C0.74843 -0.114317 1.3805 -0.077136 1.74742 0.335647L5.43973 4.48949C5.77652 4.86838 5.77652 5.43933 5.43973 5.81822L1.74742 9.97207C1.3805 10.3848 0.74843 10.422 0.335647 10.0551C-0.077136 9.68819 -0.114317 9.05612 0.252601 8.64334L3.35436 5.15386L0.252601 1.66437C-0.114317 1.25159 -0.077136 0.619519 0.335647 0.252601Z"
/>
</svg>
</slot>
</button>
<button class="js-program-btn js-program-next speaker-section__btn" ref="btnNextBottom">
<slot name="icon-next">
<svg width="6" height="11" viewBox="0 0 6 11" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.334734 10.055C0.747517 10.4219 1.37959 10.3848 1.74651 9.97197L5.43882 5.81812C5.7756 5.43924 5.7756 4.86828 5.43882 4.4894L1.74651 0.33555C1.37959 -0.0772324 0.747517 -0.114413 0.334734 0.252505C-0.0780483 0.619423 -0.115229 1.2515 0.251689 1.66428L3.35345 5.15376L0.251689 8.64324C-0.115229 9.05603 -0.0780483 9.6881 0.334734 10.055Z"
/>
</svg>
</slot>
</button>
</div>
</div>
</ZeenContainer>
</section>
</template>
<script>
import Vue from 'vue'
import Swiper from 'swiper/bundle'
import ZeenHeadline from '../../components/ZeenHeadline/ZeenHeadline'
import ZeenSpeakerCard from '../../components/ZeenSpeakerCard/ZeenSpeakerCard'
import 'swiper/swiper-bundle.css'
import ZeenContainer from '../../components/ZeenContainer/ZeenContainer'
import {createSlotsFor, createEventsFor} from '../../helpers/createBlockData'
export default {
name: 'ZeenSpeakerSection',
components: {ZeenContainer, ZeenSpeakerCard, ZeenHeadline},
inheritAttrs: false,
props: {
title: {
type: String,
default: 'Спикеры',
},
arrowPosition: {
type: String,
default: 'top',
},
isPagination: {
type: Boolean,
default: false,
},
isClickableBullets: {
type: Boolean,
default: true,
},
attrsSpeaker: {
type: Object,
require: false,
},
speakers: {
type: Array,
require: true,
},
mainHeadlineAttrs: {
type: Object,
require: false,
default: () => ({type: 'dark-48'}),
},
breakpoints: {
type: Object,
require: false,
default: () => ({
1400: {
slidesPerView: 4.5,
spaceBetween: 20,
},
1200: {
slidesPerView: 4.1,
spaceBetween: 20,
},
992: {
slidesPerView: 3.5,
spaceBetween: 20,
},
768: {
slidesPerView: 3.1,
spaceBetween: 20,
},
560: {
slidesPerView: 2.4,
spaceBetween: 10,
},
480: {
slidesPerView: 1.8,
spaceBetween: 10,
},
360: {
slidesPerView: 1.4,
spaceBetween: 10,
},
300: {
slidesPerView: 1.1,
spaceBetween: 10,
},
1: {
slidesPerView: 1.1,
spaceBetween: 10,
},
// Дефолт значение, нужно чтобы карточка спикера
// не растягивалась на фулл при загрузке
0: {
slidesPerView: 4.5,
spaceBetween: 10,
},
}),
},
},
mounted() {
this.slider = new Swiper(this.$refs.slider, {
pagination: {
el: this.$refs.pagination,
type: 'bullets',
clickable: this.isClickableBullets,
},
navigation: {
prevEl: this.topPositionArrow,
nextEl: this.bottomPositionArrow,
},
breakpoints: this.breakpoints,
})
this.updateSlider()
setTimeout(() => {
this.updateSlider()
}, 1000)
},
methods: {
updateSlider() {
Vue.nextTick(() => {
setTimeout(() => {
this.slider.update()
}, 1000)
})
},
},
computed: {
speakerPrefix() {
return 'speaker_'
},
speakerSlots() {
return createSlotsFor(this, this.speakerPrefix)
},
speakerEvents() {
const {...allEvents} = createEventsFor(this, this.speakerPrefix)
return allEvents
},
topPositionArrow() {
return this.arrowPosition === 'top' ? this.$refs.btnPrevTop : this.$refs.btnPrevBottom
},
bottomPositionArrow() {
return this.arrowPosition === 'top' ? this.$refs.btnNextTop : this.$refs.btnNextBottom
},
},
watch: {
speakers() {
this.updateSlider()
},
},
}
</script>
<style lang="scss" scoped>
@import '/src/styles/mixins.scss';
.speaker-section {
width: 100%;
overflow: hidden;
&__main-headline {
font-size: var(--zeen-speaker-section-headline-size);
color: var(--zeen-speaker-section-headline-color);
}
::v-deep {
.swiper-slide {
height: auto;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.swiper-container {
overflow: visible;
padding-bottom: var(--zeen-speaker-section-padding-bottom-swiper);
}
}
&__swiper {
@include tablets {
padding-bottom: 40px;
}
}
.swiper-pagination {
text-align: var(--zeen-speaker-section-position-pagination);
}
.swiper-container-horizontal > .swiper-pagination-bullets,
.swiper-pagination-custom,
.swiper-pagination-fraction {
bottom: 0;
}
::v-deep.swiper-pagination-bullet {
background-color: var(--zeen-speaker-section-bullet-color);
opacity: initial;
width: var(--zeen-speaker-section-size-bullet);
height: var(--zeen-speaker-section-size-bullet);
&-active {
background-color: var(--zeen-speaker-section-bullet-active-color);
}
&:not(:last-child) {
margin-right: var(--zeen-speaker-section-gap-bullet);
}
}
.zeen-headline {
margin: 0;
}
.speaker-card {
::v-deep.zeen-picture {
display: block;
&__img {
max-width: 100% !important;
width: 100%;
max-height: initial !important;
}
}
::v-deep.zeen-headline {
font-size: var(--zeen-speaker-section-headline-speaker-card);
}
}
&__buttons-group {
width: fit-content;
display: flex;
margin-left: auto;
gap: var(--zeen-speaker-section-action-gap);
&_bottom {
margin-top: var(--zeen-speaker-section-action-bottom-margin-top);
}
}
&__actions {
margin-bottom: var(--zeen-speaker-section-action-margin-bottom);
align-items: center;
}
.js-program {
&-next {
margin-left: auto;
}
&-btn {
background-color: transparent;
border: none;
transform: rotate(180deg);
cursor: pointer;
transition-property: filter;
transition-duration: 0.3s;
transition-timing-function: ease;
width: var(--zeen-speaker-section-action-btn-size);
height: var(--zeen-speaker-section-action-btn-size);
border-radius: var(--zeen-speaker-section-action-btn-border-radius);
background-color: var(--gray-5);
& svg {
stroke: var(--zeen-speaker-section-arrow-main-color);
fill: var(--zeen-speaker-section-arrow-main-color);
transition-property: stroke, fill, filter;
transition-duration: 0.3s;
transition-timing-function: ease;
}
&:focus,
&:visited {
& svg {
stroke: var(--zeen-speaker-section-arrow-main-color);
fill: var(--zeen-speaker-section-arrow-main-color);
filter: brightness(0.8);
}
}
&:hover {
& svg {
stroke: var(--zeen-speaker-section-arrow-main-color);
fill: var(--zeen-speaker-section-arrow-main-color);
filter: brightness(0.8);
}
}
&:active {
& svg {
stroke: var(--zeen-speaker-section-arrow-main-color);
fill: var(--zeen-speaker-section-arrow-main-color);
filter: brightness(0.6);
}
}
}
&-next {
& svg {
transform: rotate(180deg);
}
}
&-swiper {
overflow: visible;
}
&-actions {
display: flex;
justify-content: space-between;
}
}
.swiper-button-disabled {
cursor: default;
& svg {
stroke: var(--zeen-speaker-section-arrow-disabled-color);
fill: var(--zeen-speaker-section-arrow-disabled-color);
}
&,
&:focus,
&:visited {
& svg {
stroke: var(--zeen-speaker-section-arrow-disabled-color);
fill: var(--zeen-speaker-section-arrow-disabled-color);
}
}
&:hover,
&:active {
& svg {
stroke: var(--zeen-speaker-section-arrow-disabled-color);
fill: var(--zeen-speaker-section-arrow-disabled-color);
filter: none;
}
}
}
}
</style>