false, всё выбрано - true, для остальных вариантов undefined, при котором в true будет выставляться indeterminate. Также у него будет сеттер - если попытаться назначить true, то выбранными должны стать все чекбоксы; если false, то никто.const items = ref([
{ id: 69, title: 'hello, world!!' },
{ id: 187, title: 'fuck the world' },
{ id: 666, title: 'fuck everything' },
]);
const checked = ref([ 187 ]);
const isAllChecked = computed({
get: () => ({
0: false,
[items.value.length]: true,
})[checked.value.length],
set: val => checked.value = val ? items.value.map(n => n.id) : [],
});<div>
<label>
<input
type="checkbox"
v-model="isAllChecked"
:indeterminate.prop="isAllChecked === undefined"
>
<b>Check all</b>
</label>
</div>
<div v-for="n in items" :key="n.id">
<label>
<input type="checkbox" v-model="checked" :value="n.id">
{{ n.title }}
</label>
</div>
Сделал вот так: str.split("/").slice(-2, -1).join(""), но думаю, что есть решение попроще./[^\/]+(?=\/$)/.exec(str)[0]
// или
str.match(/[^\/]+/g).pop()
// или
str.split('/').at(-2)
clearInterval из функции stopTheTimer результата необходимого не показал
data() { <...> }, mounted() { <...> }, stopTheTimer() { clearInterval(this.interval); }
Хук get не позволяет получить параметры вызова метода
function sequence(functions) {
return new Proxy(functions, {
get(target, key) {
const val = target[key];
return val instanceof Function
? (...args) => {
console.log(`method "${key}" called with arguments: `, args);
return val.apply(target, args);
}
: val;
},
});
}
const uniqueWithSum = arr =>
arr.reduce((acc, n) => {
const keys = n.slice(0, -1);
const item = acc.find(m => m.length === n.length && keys.every((k, i) => k === m[i]));
(item ?? (acc[acc.length] = [ ...keys, 0 ]))[keys.length] += n[keys.length];
return acc;
}, []);const uniqueWithSum = (function(arr) {
const indexTree = new Map;
return arr.reduce((acc, [...keys]) => {
const val = keys.pop();
const indexes = keys.reduce((p, c) => p.set(c, p.get(c) ?? new Map).get(c), indexTree);
const index = indexes.set(this, indexes.get(this) ?? ~-acc.push([ ...keys, 0 ])).get(this);
acc[index][keys.length] += val;
return acc;
}, []);
}).bind(Symbol());const uniqueWithSum = arr =>
[...arr.reduce((acc, n) => {
const end = n.length - 1;
const key = n.reduce((p, c, i) => i === end ? p : p.set(c, p.get(c) ?? new Map).get(c), acc[0]);
acc[1].set(key, acc[1].get(key) ?? n.map((m, i) => i !== end && m)).get(key)[end] += n[end];
return acc;
}, [ new Map, new Map ])[1].values()];
v-model:props: {
modelValue: {
type: String,
default: '',
},
...<select
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
<option
v-for="n in options"
v-text="n.label"
:value="n.value"
></option>
</select>data: () => ({
selected: Array(10).fill(null),
...
}),
methods: {
getValue(index) {
this.active = index;
console.log(this.selected[index]);
},
},<div
v-for="(n, i) in selected"
class="test__item"
:class="{ test__item_active: i === active }"
>
<span @click="getValue(i)">элемент списка</span>
<Select v-model="selected[i]" :options="options" />
</div>
const profilesSorting = computed(() => profiles
.value
.filter(n => n.id === filters.value.id)
.sort(...)
.slice(...)
);
const replaceKeys = (value, replacer) =>
value instanceof Object
? value instanceof Array
? value.map(n => replaceKeys(n, replacer))
: Object.fromEntries(Object
.entries(value)
.map(n => [ replacer(n[0]), replaceKeys(n[1], replacer) ])
)
: value;function replaceKeys(value, replacer) {
const stack = [];
const clones = new Map;
const getClone = v => v instanceof Object
? (clones.has(v) || stack.push([ v, clones.set(v, v.constructor()).get(v) ]),
clones.get(v))
: v;
for (getClone(value); stack.length;) {
const [ source, target ] = stack.pop();
const isArray = Array.isArray(source);
for (const k in source) if (Object.hasOwn(source, k)) {
target[isArray ? k : replacer(k)] = getClone(source[k]);
}
}
return getClone(value);
}const newObj = replaceKeys(obj, key => `${key}_upd`);
выбранным оказывается последний добавленный элемент, несмотря на то, что всем добавленным элементам в GetSelected я вернул ' '
v-model?
const regex = /#[a-f\d]+;$/i;
const replacement = '<span class="color" style="background: $&"></span>';
document.querySelectorAll('селектор сами сообразите').forEach(n => {
n.innerHTML = n.innerText.replace(regex, replacement);
});
const result = arr.reduce((acc, n, i, a) => (
n === a[i - 1] + 1 || acc.push([]),
acc.at(-1).push(n),
acc
), []);function* groupAdjacent(
data,
{
key = n => n,
newGroup = (c, p) => c !== p,
} = {}
) {
const iter = data[Symbol.iterator]();
const getVal = key instanceof Function ? key : n => n[key];
for (
let group = [], prev = null, n, i = -1;
!n?.done && (n = iter.next());
n.done || group.push(n.value)
) {
let groupDone = false;
if (!n.done) {
const curr = getVal(n.value, ++i);
groupDone = i && newGroup(curr, prev);
prev = curr;
}
if ((n.done && group.length) || groupDone) {
yield group;
group = [];
}
}
}const result = [...groupAdjacent(arr, { newGroup: (c, p) => c !== -~p })];
// или
const result = Array.from(groupAdjacent(arr, { key: (n, i) => n - i }));
.product. Вместо первого .product нужен тот, внутри которого находится нажатая кнопка:document.querySelector('.wrapper_product') ---> event.target
$value = array_combine($data['value_index'], $data['value'])[min($data['value_index'])];$value = $data['value'][array_search(min($data['value_index']), $data['value_index'])];$index = 0;
for ($i = 1; $i < count($data['value_index']); $i++) {
if ($data['value_index'][$i] < $data['value_index'][$index]) {
$index = $i;
}
}
$value = $data['value'][$index];
menu.addEventListener('click', ({ target: t }) => {
if (t.tagName === 'SPAN') {
const parent = t.parentNode;
parent.classList.toggle('active');
for (const n of menu.querySelectorAll('.active')) {
if (n !== parent) {
n.classList.toggle('active', n.contains(parent));
}
}
}
});- .menu_list_item.active .submenu {
+ .active > .submenu {- .submenu_list_item.active .product {
+ .active > .product {const container = document.querySelector('#menu');
const itemSelector = 'li';
const buttonSelector = `${itemSelector} span`;
const activeClass = 'active';
container.addEventListener('click', function({ target: t }) {
if (t = t.closest(buttonSelector)?.closest(itemSelector)) {
t.classList.toggle(activeClass);
this.querySelectorAll(`.${activeClass}`).forEach(n => {
if (n !== t) {
n.classList.toggle(activeClass, n.contains(t));
}
});
}
});
const items = document.querySelectorAll('.faq__input');
const onChange = ({ target: t }) => t
.closest('.faq__items')
.querySelectorAll('.faq__question--top')
.forEach(n => n.classList.toggle('active', n.nextElementSibling.checked));
items.forEach(n => n.addEventListener('change', onChange));.faq__item вместо .faq__question--top. Если в будущем задумаете стилизовать внутри выбранного .faq__item элементы, находящиеся за пределами .faq__question--top, то не придётся переписывать js-код.const itemSelector = '.faq__item';
const radioSelector = '.faq__input';
const activeClass = 'active';
const toggleActiveClass = radioGroupName => document
.querySelectorAll(`${radioSelector}[name="${radioGroupName}"]`)
.forEach(n => n.closest(itemSelector).classList.toggle(activeClass, n.checked));document.querySelectorAll(radioSelector).forEach(function(n) {
n.addEventListener('change', this);
}, e => toggleActiveClass(e.target.name));document.addEventListener('change', ({ target: t }) => {
if (t.matches(radioSelector)) {
toggleActiveClass(t.name);
}
});
$values = array_column($array2, 'value');
$result = array_filter($array1, fn($n) => in_array($n->code, $values));
из дочернего мне нужно передать именно ключ b в родительский
this.$emit('do-something').<child-component :object="objects.a" @do-something="doSomething('a')" />
<child-component :object="objects.b" @do-something="doSomething('b')" />
<!--> или <-->
<child-component v-for="(v, k) in objects" :object="v" @do-something="doSomething(k)" />methods: {
doSomething(key) {
// чего-то делаете
},
...затем пройтись по objects и при совпадении ключей (a, b или c) выполнить действия над значением
<child-component :object="objects.a" @do-something="doSomething(objects.a)" />
<child-component :object="objects.b" @do-something="doSomething(objects.b)" />
<!--> или <-->
<child-component v-for="n in objects" :object="n" @do-something="doSomething(n)" />this.$emit('do-something', this.object). Тогда не придётся дублировать обращение к нему в родителе:<child-component :object="objects.a" @do-something="doSomething" />
<child-component :object="objects.b" @do-something="doSomething" />
<!--> или <-->
<child-component v-for="n in objects" :object="n" @do-something="doSomething" />
function createTree({
data,
key = 'id',
parentKey = 'parentId',
childrenKey = 'children',
}) {
const tree = Object.fromEntries(data.map(n => [
n[key],
{ ...n, [childrenKey]: [] },
]));
return Object.values(tree).filter(n => (
!tree[n[parentKey]]?.[childrenKey].push(n)
));
}v-tree, выводящий древовидные данные:props: {
items: {
type: Array,
default: () => [],
},
maxdepth: {
type: Number,
default: Infinity,
},
},<ul v-if="Array.isArray(items) && items.length && maxdepth > 0">
<li v-for="n in items" :key="n.id">
{{ n.value }}
<v-tree :items="n.children" :maxdepth="maxdepth - 1" />
</li>
</ul>data: () => ({
treeData: createTree({
data: flatData,
parentKey: 'parent_id',
}),
}),
// или
computed: {
treeData() {
return createTree({
data: this.flatData,
parentKey: 'parent_id',
});
},
},<v-tree
:items="treeData"
:maxdepth="3"
/>