<div v-html="свойствоСодержащееHTML" @click="onClick">methods: {
onClick(e) {
if (e.target.tagName === 'BUTTON') {
const id = e.target.closest('.product').dataset.id;
...
}
},
...
},
ids = set(n['id'] for n in arr)
grouped = [ (i, [ n['qty'] for n in arr if n['id'] == i ]) for i in ids ]
summed = [ { 'id': k, 'qty': sum(v), 'id_count': len(v) } for k, v in grouped ]
const parseValue = str => {
const values = str.match(/[^\s,]+/g) ?? [ null ];
return values.length > 1 ? values : values[0];
};
const parseStyleStr = str =>
str.split(';').reduce((acc, n) => {
const [ k, v ] = n.split(':').map(n => n.trim());
if (k && v) {
const f = [...v.matchAll(/([\w]+?)\((.+?)\)/g)];
acc[k] = f.length
? Object.fromEntries(f.map(n => [ n[1], parseValue(n[2]) ]))
: parseValue(v);
}
return acc;
}, {});
Хорошо бы если на чистом css
но и js тоже можно
document.addEventListener('click', ({ target: { tagName, parentNode: p } }) => {
if (tagName === 'SUMMARY') {
document.querySelectorAll('details').forEach(n => n.open = n.open && n === p);
}
});
// или
const details = document.querySelectorAll('details');
const onClick = e => details.forEach(n => n.open = n.open && n === e.target.parentNode);
details.forEach(n => n.children[0].addEventListener('click', onClick));
const obj = arr.find(n => n.id === newObj.id);
if (obj) {
obj.counter++;
} else {
arr.push({ ...newObj, counter: 1 });
}
on на one. Но что если запрос окажется неудачным? Наверное, надо оставить пользователю возможность повторить действие. Вон, у вас там класс добавляется - так проверяйте его наличие, если уже есть, ничего делать не надо; также добавьте обработку неудавшихся запросов, там надо будет класс снять.
async created() {
await this.getAsyncData();
this.$watch('some_value', value => {
...
});
},
const getReversedPaths = (arr, path = []) =>
arr.reduce((acc, { childItems, ...item }) => {
path.push(item);
if (childItems) {
acc.push(...getReversedPaths(childItems, path));
} else {
acc.push(path.length > 1
? path.map(({ packingLevel }, i, a) => ({ ...a[a.length - i - 1], packingLevel }))
: [ path[0] ]
);
}
path.pop();
return acc;
}, []);const reverseThere = arr =>
getReversedPaths(arr).map(n =>
n.reduceRight((child, parent) => ({ ...parent, childItems: [ child ] }))
);const reverseBackAgain = arr =>
(function createTree(arr) {
return Object.values(arr.reduce((acc, [ head, ...tail ]) => {
if (tail.length) {
(acc[head.name] = acc[head.name] ?? { ...head, childItems: [] }).childItems.push(tail);
} else {
acc[head.name] = head;
}
return acc;
}, {})).map(n => (n.childItems && (n.childItems = createTree(n.childItems)), n));
})(getReversedPaths(arr));
<Child onChange={onChange} />useEffect(() => props.onChange(val), [ val ]);
const newArr2 = arr2.filter(n => arr1.some(m => m === n.name));
// или
const obj2 = arr2.reduce((acc, n) => (
(acc[n.name] = acc[n.name] ?? []).push(n),
acc
), {});
const newArr2 = arr1.flatMap(n => obj2[n] ?? []);
// или
const newArr2 = [];
for (const n of arr2) {
for (const m of arr1) {
if (m === n.name) {
newArr2.push(n);
break;
}
}
}arr2.reduceRight((_, n, i, a) => ~arr1.indexOf(n.name) || a.splice(i, 1), null);
// или
arr2.splice(0, arr2.length, ...arr2.filter(function(n) {
return this.has(n.name);
}, new Set(arr1)));
// или
arr2.length -= arr2.reduce((acc, n, i, a) => (
a[i - acc] = n,
acc + !arr1.includes(n.name)
), 0);
<select>
<option value="" hidden>здесь ваше описание</option>
...select.innerHTML = '<option value="" hidden>...</option>' + select.innerHTML;select.insertAdjacentHTML('afterbegin', '<option value="" hidden>...</option>');const option = document.createElement('option');
option.value = '';
option.hidden = true;
option.innerText = '...';
select.prepend(option);const option = new Option('...', '');
option.style.display = 'none';
select.insertBefore(option, select.firstElementChild);
<div id="items"></div>document.querySelector('.map__filters').addEventListener('change', function() {
const values = Array.from(
this.querySelectorAll('.map__checkbox:checked'),
n => n.value
);
const filtered = values.length
? data.filter(n => values.every(m => n.features.includes(m)))
: [];
document.querySelector('#items').innerHTML = filtered
.map(n => `<div>${JSON.stringify(n, null, 2)}</div>`)
.join('');
});
const parseDate = str =>
new Date(str.split('.').reverse().join('-'));
// или
const parseDate = str =>
new Date(str.replace(/(\d+)\.(\d+)\.(\d+)/, '$3-$2-$1'));
// или
const parseDate = str =>
(str = str.match(/\d+/g), new Date(str[2], ~-str[1], str[0]));data: () => ({
today: new Date().setHours(0, 0, 0, 0),
...
}),
computed: {
filteredList() {
return this.list.filter(n => parseDate(n.dateend) < this.today);
},
...
},
computed: {
itemsWithBullshitCounter() {
let counter = -1; /* или 0, если хотите, чтобы нулевой элемент массива получил ненулевой индекс
в том случае, если для него не выполняется условие обнуления */
return this.items.map((n, i) => ({
...n,
counter: counter = (здесь проверяете, надо ли обнулить счётчик
? 0
: counter + 1
),
}));
},
},<div v-for="n in itemsWithBullshitCounter">
вместо индекса используете значение добавленного свойства: {{ n.counter }}
</div>computed: {
chunkedItems() {
return this.items.reduce((acc, n, i) => {
if (!i || на текущем элементе надо сбросить индексацию) {
acc.push([]);
}
acc[acc.length - 1].push(n);
return acc;
}, []);
},
},<template v-for="chunk in chunkedItems">
у каждого куска индексация независимая:
<div v-for="(n, i) in chunk">{{ i }}</div>
</template>methods: {
createStrangeIndex(arr, baseIndex) {
let index = 0;
while (baseIndex > 0 && на элементе arr[baseIndex--] сбрасывать индексацию не надо) {
index++;
}
return index;
},
},<div v-for="(n, i) in items">{{ createStrangeIndex(items, i) }}</div>
есть метод orgajax - он тянет данные с сервера, в том числе и HTML код
function filter(obj, key, f) {
const keys = Object.keys(obj);
return (obj[key] || []).reduce((acc, n, i) => (
f(n) && keys.forEach(k => acc[k].push(obj[k][i])),
acc
), keys.reduce((acc, k) => (acc[k] = [], acc), {}));
}
const result = filter(obj, 'years', n => 2012 <= n && n <= 2014);function filter(obj, f) {
const keys = Object.keys(obj);
const length = keys.length && obj[keys[0]].length;
const result = Object.fromEntries(keys.map(k => [ k, [] ]));
for (let i = 0; i < length; i++) {
if (f(i, obj)) {
keys.forEach(k => result[k].push(obj[k][i]));
}
}
return result;
}
const result = filter(obj, (i, { years: { [i]: n } }) => 2012 <= n && n <= 2014);
const selector = '[type="tel"]';
const event = 'input';
const minLength = 10;
const classNames = [ 'какой-то класс', 'какой-то другой класс' ];$(selector).on(event, function() {
const isLengthOK = $(this).val().length >= minLength;
$(this)
.toggleClass(classNames[0], !isLengthOK)
.toggleClass(classNames[1], isLengthOK);
});document.querySelectorAll(selector).forEach(function(n) {
n.addEventListener(event, this);
}, ({ target: t }) => {
const isLengthOK = +(t.value.length >= minLength);
classNames.forEach((n, i) => t.classList.toggle(n, isLengthOK === i));
});