every
для пустого массива?||
? .waiting { background: yellow; }
.working { background: green; }
.completed { background: blue; }
const highlight = {
'Ожидание': 'waiting',
'Работа': 'working',
'Завершено': 'completed',
};
<el-table-column label="Процесс">
<template #default="{ row: { process } }">
<span :class="highlight[process]">{{ process }}</span>
</template>
</el-table-column>
const cellClassName = ({ column, row }) =>
column.property === 'process'
? (highlight[row.process] ?? '')
: '';
<el-table
:cell-class-name="cellClassName"
...
>
prefix-icon="calendar-icon"
function combine($ids, $keys, ...$values) {
return array_combine(
$ids,
array_map(
fn($i) => array_combine($keys, array_column($values, $i)),
array_keys($ids)
)
);
}
$result = combine($input, $params, $array1, $array2);
const months = Object.fromEntries(Array.from(
{ length: 12 },
(_, i) => [ new Date(0, i).toLocaleString('ru-RU', { month: 'long' }), i ]
));
function parseDate(str) {
const [ , month, day, year, hour, minute ] = str.match(/(\S+) (\d+), (\d+) (\d+):(\d+)/);
return +new Date(year, months[month.toLowerCase()], day, hour, minute);
}
const month = computed(() => {
const today = new Date().setHours(0, 0, 0, 0);
const m = date.value.getMonth();
const d = new Date(date.value.getFullYear(), m, 0);
d.setDate(d.getDate() - (d.getDay() || 7));
return Array.from({ length: 42 }, () => (
d.setDate(d.getDate() + 1),
{
date: d.getDate(),
currMonth: d.getMonth() === m,
today: +d === today,
}
));
});
<div class="calendar">
<div
v-for="n in weekdays"
v-text="n"
class="weekday"
></div>
<div
v-for="{ date, ...n } in month"
v-text="date"
:class="[ 'day', n ]"
></div>
</div>
.calendar {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
Вот так собираю данные с чекбоксов:
const formData = new FormData(e.currentTarget.form); const names = formData.getAll('names'); setNames(names);
const onAllSelectedChange = ({ target: { checked, form: { names } } }) => {
names.forEach(n => n.checked = checked);
setNames(checked ? Array.from(names, n => n.value) : []);
};
const onChange = ({ target: { form } }) => {
const names = new FormData(form).getAll('names');
const isAllSelected = names.length === form.names.length;
const all = form.allSelected;
all.checked = isAllSelected;
all.indeterminate = !isAllSelected && !!names.length;
setNames(names);
};
const Checkbox = forwardRef(({ label, ...props }, ref) =>
<label>
<input type="checkbox" ref={ref} {...props} />
{label}
</label>
);
function CheckboxGroup({
items,
label = item => item,
selected,
setSelected,
}) {
const onChange = ({ target: { checked, dataset: { index } } }) =>
setSelected(selected => checked
? [ ...selected, items[index] ]
: selected.filter(n => n !== items[index])
);
const allSelectedRef = useRef();
const onAllSelectedChange = ({ target: { checked } }) =>
setSelected(checked ? [...items] : []);
useEffect(() => {
const isAllSelected = items.length === selected.length;
allSelectedRef.current.checked = isAllSelected;
allSelectedRef.current.indeterminate = !isAllSelected && !!selected.length;
}, [ selected ]);
return (
<div className="checkbox-group">
<Checkbox
label="SELECT ALL"
defaultChecked={false}
onChange={onAllSelectedChange}
ref={allSelectedRef}
/>
{items.map((n, i) => (
<Checkbox
label={label(n)}
data-index={i}
checked={selected.includes(n)}
onChange={onChange}
/>
))}
</div>
);
}
const checkboxContainer = document.querySelector('.options');
const itemsContainer = document.querySelector('.box');
const hiddenClass = 'hidden';
:not
):function getCheckedSelector(container) {
const [ not, has ] = Array.prototype.reduce.call(
container.querySelectorAll('input'),
(acc, n) => (acc[+n.checked].push(`.${n.value}`), acc),
[ [], [] ]
);
return has.join('') + (not.length ? `:not(${not.join(',')})` : '');
}
checkboxContainer.addEventListener('change', function() {
const selector = getCheckedSelector(this);
for (const n of itemsContainer.children) {
n.classList.toggle(hiddenClass, !n.matches(selector));
}
});
const toggleHidden = (selector, state) => itemsContainer
.querySelectorAll(selector)
.forEach(n => n.classList.toggle(hiddenClass, state));
checkboxContainer.addEventListener('change', e => {
toggleHidden(':scope > *', true);
toggleHidden(getCheckedSelector(e.currentTarget), false);
});
const checkboxes = [...checkboxContainer.querySelectorAll('input')];
const onChange = function() {
this.forEach(({ classList: cl }) => {
cl.toggle(hiddenClass, checkboxes.some(n => n.checked !== cl.contains(n.value)));
});
}.bind([...itemsContainer.children]);
checkboxes.forEach(n => n.addEventListener('change', onChange));
const blocks = ref(Array.from({ length: 5 }, (_, i) => (-~i) ** 2));
const active = ref(0);
function next() {
active.value = (active.value + 1 + blocks.value.length) % blocks.value.length;
}
let intervalId = null;
onMounted(() => intervalId = setInterval(next, 500));
onUnmounted(() => clearInterval(intervalId));
<div
v-for="(n, i) in blocks"
v-text="n"
:class="[ 'box-item', { active: i === active } ]"
></div>
:nth-child
- не круто. Лучше сделать компонент, принимающий массив цветов и создающий блоки на его основе. Соответственно, вместо класса будет назначаться цвет фона напрямую, как-то так:<div
v-for="(n, i) in colors"
:style="{ backgroundColor: i === active ? n : '' }"
...
кликая на один список открывается и второй
почему при изменении даты передаваемой в пропс не обновляется значение в самом компоненте таймера?
targetDate
при изменении props.date
. Нет, можете себя не утруждать - ничего такого у вас нет.targetDate
, рассчитываем дни-часы-минуты-секунды сразу на основе props.date
- так при изменении props.date
не придётся предпринимать никаких дополнительных телодвижений, всё посчитается как надо при следующем вызове updateCountdown
. Вот как-то так. .data-accordion--summary-container.active > .dropdown {
display: block;
}
const itemSelector = '.data-accordion--summary-container';
const activeClass = 'active';
const toggle = el => el
.parentNode
.querySelectorAll(`:scope > ${itemSelector}`)
.forEach(n => n.classList[n === el ? 'toggle' : 'remove'](activeClass));
// применяем делегирование
document.body.addEventListener('click', ({ target: t }) =>
t.matches(itemSelector) && toggle(t)
);
// или, назначаем обработчик клика каждому элементу индивидуально
document.querySelectorAll(itemSelector).forEach(function(n) {
n.addEventListener('click', this);
}, e => e.currentTarget === e.target && toggle(e.target));