Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Решил 5 задач из раздела компонеты #5

Merged
merged 4 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion 03-components/10-MeetupView/MeetupView.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,45 @@ export default defineComponent({
components: {
UiAlert,
UiContainer,
MeetupAgenda,
MeetupDescription,
MeetupCover,
MeetupInfo,
},

props: {
meetup: {
type: Object,
required: true,
}
},

template: `
<div>

<!-- Обложка митапа -->
<MeetupCover :title="meetup.title" :image="meetup.image" />

<UiContainer>
<div class="meetup">
<div class="meetup__content">
<h2>Описание</h2>

<!-- Описание митапа -->
<MeetupDescription :description="meetup.description" />

<h2>Программа</h2>

<!-- Программа митапа -->
<MeetupAgenda v-if="meetup.agenda.length !== 0" :agenda="meetup.agenda" />
<!-- Или при пустой программе - сообщение "Программа пока пуста..." в UiAlert -->
<UiAlert></UiAlert>
<UiAlert v-else>Программа пока пуста...</UiAlert>

</div>
<div class="meetup__aside">

<!-- Краткая информация о митапе -->
<MeetupInfo :organizer="meetup.organizer" :place="meetup.place" :date="meetup.date" />

<div class="meetup__aside-buttons"></div>
</div>
Expand Down
28 changes: 25 additions & 3 deletions 03-components/20-UiClock/UiClock.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
import { defineComponent } from 'vue'
import { defineComponent, ref, onMounted, onUnmounted } from 'vue'

export default defineComponent({
name: 'UiClock',

setup() {},
setup() {
const timeData = new Intl.DateTimeFormat(navigator.language, { timeStyle: 'medium' });

template: `<div class="clock">10:12:02</div>`,
const timeActual = ref('');

let intervalCount = 0;

onMounted(() => {
timeActual.value = timeData.format(new Date());

intervalCount = setInterval(() => {
timeActual.value = timeData.format(new Date());
}, 1000);
})

onUnmounted(() => {
clearInterval( intervalCount )
});

return {
timeActual,
}
},

template: `<div class="clock">{{ timeActual }}</div>`,
})
15 changes: 14 additions & 1 deletion 03-components/30-removable-emails/EmailList.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,27 @@ export default defineComponent({
},
},

emits: ['removeItem'],

setup(props, { emit }) {
function removeItem(index) {
emit('removeItem', index)
}

return {
removeItem
}
},

template: `
<ul class="emails-list unstyled-list" aria-label="Emails">
<EmailListItem
v-for="({ email, isMarked }, index) in emails"
:key="email"
:email="email"
:marked="isMarked"
@remove="removeItem(index)"
/>
</ul>
`,
})
})
16 changes: 14 additions & 2 deletions 03-components/30-removable-emails/EmailListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ export default defineComponent({
},
},

// emits: ['remove'],

setup(props, { emit }) {
function handleChange() {
emit('remove')
}

return {
handleChange,
}
},

template: `
<li :class="{ marked }">
{{ email }}
<button type="button" aria-label="Удалить" @click.stop>❌</button>
<button type="button" aria-label="Удалить" @click.stop="handleChange()">❌</button>
</li>
`,
})
})
4 changes: 2 additions & 2 deletions 03-components/30-removable-emails/MarkedEmailsApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default defineComponent({
<UiFormGroup>
<UiInput v-model.trim="query" type="search" placeholder="Поиск" aria-label="Поиск" small />
</UiFormGroup>
<EmailList :emails="markedEmails" />
<EmailList :emails="markedEmails" @removeItem="removeEmailByIndex" />
</div>
`,
})
})
42 changes: 37 additions & 5 deletions 03-components/40-UiCounter/UiCounter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,47 @@ export default defineComponent({
UiButton,
},

setup() {
// Рекомендуется для практики реализовать обработку событий внутри setup, а не непосредственно в шаблоне
props: {
count: {
type: Number,
required: true
},

min: {
type: Number,
required: false,
default: 0
},

max: {
type: Number,
required: false,
default: Infinity
}
},

emits: ['update:count'],

setup(props, { emit }) {
function incCounter() {
emit('update:count', props.count + 1)
}

function decCounter() {
emit('update:count', props.count - 1)
}

return {
incCounter,
decCounter
}
},

template: `
<div class="counter">
<UiButton aria-label="Decrement" disabled>➖</UiButton>
<span class="count" data-testid="count">3</span>
<UiButton aria-label="Increment">➕</UiButton>
<UiButton aria-label="Decrement" :disabled="count <= min" @click="decCounter">➖</UiButton>
<span class="count" data-testid="count">{{ count }}</span>
<UiButton aria-label="Increment" :disabled="count >= max" @click="incCounter">➕</UiButton>
</div>
`,
})
56 changes: 17 additions & 39 deletions 03-components/50-weather-components/WeatherApp.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,29 @@
import { defineComponent } from 'vue'
import { getWeatherData, WeatherConditionIcons } from './weather.service.ts'
import { getWeatherData } from './weather.service.ts'
import './WeatherApp.css'
import WeatherCard from './WeatherCard.js'

export default defineComponent({
name: 'WeatherApp',

template: `
components: {
WeatherCard
},

setup() {

const weatherData = getWeatherData();

return {
weatherData,
}
},

template: `
<div>
<h1 class="title">Погода в Средиземье</h1>

<ul class="weather-list unstyled-list">
<li class="weather-card weather-card--night">
<div class="weather-alert">
<span class="weather-alert__icon">⚠️</span>
<span class="weather-alert__description">Королевская метеослужба короля Арагорна II: Предвещается наступление сильного шторма.</span>
</div>
<div>
<h2 class="weather-card__name">
Гондор
</h2>
<div class="weather-card__time">
07:17
</div>
</div>
<div class="weather-conditions">
<div class="weather-conditions__icon" title="thunderstorm with heavy rain">⛈️</div>
<div class="weather-conditions__temp">15.0 °C</div>
</div>
<div class="weather-details">
<div class="weather-details__item">
<div class="weather-details__item-label">Давление, мм рт. ст.</div>
<div class="weather-details__item-value">754</div>
</div>
<div class="weather-details__item">
<div class="weather-details__item-label">Влажность, %</div>
<div class="weather-details__item-value">90</div>
</div>
<div class="weather-details__item">
<div class="weather-details__item-label">Облачность, %</div>
<div class="weather-details__item-value">100</div>
</div>
<div class="weather-details__item">
<div class="weather-details__item-label">Ветер, м/с</div>
<div class="weather-details__item-value">10.5</div>
</div>
</div>
</li>
<WeatherCard v-for="cardsItem in weatherData" :cards="cardsItem" />
</ul>
</div>
`,
Expand Down
92 changes: 92 additions & 0 deletions 03-components/50-weather-components/WeatherCard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { computed, defineComponent } from 'vue';
import { WeatherConditionIcons } from './weather.service.ts'
import WeatherCardAlert from './WeatherCardAlert.js';

export default defineComponent({
name: 'WeatherCard',

components: {
WeatherCardAlert,
},

props: {
cards: {
type: Object,
required: true
}
},

setup( props ) {

const weatherIcons = WeatherConditionIcons;

function roundCelcium ( num ) {
// return Math.round( num * 10 ) / 10; // плюс в том, что получаем чило, но при целых числах нет нулей после точки
return num.toFixed( 1 ); // получаем строку
};

function getTemperature( kelvin ) {
let celsius = kelvin - 273.15;
let result = `${roundCelcium ( celsius )} °C`;
return result;
};

function getPressure( value ) {
let algoritm = value * 0.75;
let result = Math.round( algoritm );
return result;
};

function findSunDay( actualTime, sunriseTime, sunsetTime ) {
return actualTime > sunriseTime && actualTime < sunsetTime;
};

return {

weatherIcons,

getTemperature,

getPressure,

findSunDay,
}
},

template: `
<li class="weather-card" :class="{ 'weather-card--night': !findSunDay( cards.current.dt, cards.current.sunrise, cards.current.sunset ) }">
<WeatherCardAlert v-if="cards.alert" :sender-name="cards.alert.sender_name" :description="cards.alert.description" />
<div>
<h2 class="weather-card__name">
{{ cards.geographic_name }}
</h2>
<div class="weather-card__time">
{{ cards.current.dt }}
</div>
</div>
<div class="weather-conditions">
<div class="weather-conditions__icon" key:="weatherIcons" :title="cards.current.weather.description">{{ weatherIcons[cards.current.weather.id] }}</div>
<div class="weather-conditions__temp">{{ getTemperature( cards.current.temp ) }}</div>
</div>
<div class="weather-details">
<div class="weather-details__item">
<div class="weather-details__item-label">Давление, мм рт. ст.</div>
<div class="weather-details__item-value">{{ getPressure( cards.current.pressure ) }}</div>
</div>
<div class="weather-details__item">
<div class="weather-details__item-label">Влажность, %</div>
<div class="weather-details__item-value">{{ cards.current.humidity }}</div>
</div>
<div class="weather-details__item">
<div class="weather-details__item-label">Облачность, %</div>
<div class="weather-details__item-value">{{ cards.current.clouds }}</div>
</div>
<div class="weather-details__item">
<div class="weather-details__item-label">Ветер, м/с</div>
<div class="weather-details__item-value">{{ cards.current.wind_speed }}</div>
</div>
</div>
</li>
`

});
24 changes: 24 additions & 0 deletions 03-components/50-weather-components/WeatherCardAlert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { defineComponent } from 'vue';

export default defineComponent({
name: 'WeatherCardAlert',

props: {
senderName: {
type: String,
required: true
},

description: {
type: String,
required: true
}
},

template: `
<div class="weather-alert">
<span class="weather-alert__icon">⚠️</span>
<span class="weather-alert__description">{{ senderName }}: {{ description }}</span>
</div>
`
})
Loading
Loading