попытался решить все через рекурсию
const createTree = (data, parentId = null) =>
data.reduce((acc, n) => (
parentId === n.parentId && (
acc[acc.length] = Object.assign(
{ children: createTree(data, n.id) },
n
)
),
acc
), []);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]] && tree[n[parentKey]][childrenKey].push(n)
));
}
передавать параметры <...> оставив в computed
methods: {
filterHeroes(attr) {
const s = this.searchHeroesString.toLowerCase();
return this.heroes.filter(n => n.hero_attribute === attr && n.name.toLowerCase().includes(s));
},
data: () => ({
active: false,
}),
created() {
const onClick = e => this.active = this.$refs.block.contains(e.target) && this.active;
document.addEventListener('click', onClick);
this.$on('hook:beforeDestroy', () => document.removeEventListener('click', onClick));
},<button @click.stop="active = !active">click me</button>
<div :class="{ active }" ref="block">hello, world!!</div>
state: {
opened: null,
...<Trigger :block="block">props: [ 'block' ],computed: mapState([ 'opened' ]),:class="{ 'active' : block === opened }"@click="toggleNav(block)"toggleNav(state, block) {
state.opened = state.opened === block ? null : block;
},state.opened = block (название мутации в этом случае конечно следует поменять).closeSidebarPanel(state) {
state.opened = null;
},isPanelOpen(state) {
return !!state.opened;
},<span v-if="isPanelOpen">{{ $store.state.opened.bName }}</span><slot :block="$store.state.opened"></slot><template #default="{ block }">
<div class="sidebar-panel-settings">
<div class="setting-block">
{{ block.bName }}
</div>
</div>
</template>
data-rel ссылки кладём в аналогичный атрибут:<button class="cve" data-rel="69c99408142132">S</button>
<button class="cve" data-rel="69c99408143167">M</button>
<button class="cve" data-rel="69c99408143177">L</button>if (t.classList.contains('cve')), но кто его знает, может, решите в будущем добавить внутрь кнопок ещё какие-то элементы):document.addEventListener('click', ({ target: t }) => {
if (t = t.closest('.cve')) {
document.getElementById('bodyone').dataset.rel = t.dataset.rel;
}
});const el = document.querySelector('#bodyone');
const onClick = e => el.dataset.rel = e.currentTarget.dataset.rel;
document.querySelectorAll('.cve').forEach(n => n.addEventListener('click', onClick));
const result = array
.concat(obj)
.reduceRight((acc, n) => ({
...n,
children: acc ? [ acc ] : [],
// или, если вдруг исходные массивы непустые,
// и их содержимое надо сохранить
// children: n.children.concat(acc || []),
}), null);const result = [ ...array, obj ].reduceRight(
(acc, { children, ...n }) => (n.next = acc, n),
null
);
{this.state.image}<img src={this.props.items[this.state.image].img} /><App /><App items={items} />
const isEmpty = [...inputs].some(n => !n.value);
// или
const isEmpty = !Array.prototype.every.call(inputs, n => n.value);
// или
let isEmpty = false;
for (const n of inputs) {
if (!n.value) {
isEmpty = true;
break;
}
}
// или
let isEmpty = false;
for (let i = -1; ++i < inputs.length && !(isEmpty = !inputs[i].value);) ;
// или
const isEmpty = (function isEmpty(i, n = inputs.item(i)) {
return !!n && (!n.value || isEmpty(-~i));
})(0);
const grouped = Object.entries(list.reduce((acc, n) => (
(acc[n.part] = acc[n.part] || []).push(n.title),
acc
), {}));document.body.insertAdjacentHTML('beforeend', grouped
.map(([ k, v ]) => `<div>${k}</div>${v.map(n => `<div>${n}</div>`).join('')}`)
.join('')
);document.body.append(...grouped.flat(2).map(n => {
const div = document.createElement('div');
div.innerText = n;
return div;
}));
const selector = '.form-group';
const attr = 'data-property-id-row';
const values = [ 10, 13, 15 ];const elementsToHide = document.querySelectorAll(values
.map(n => `${selector}[${attr}="${n}"]`)
.join(', ')
);for (let i = 0; i < elementsToHide.length; i++) {
elementsToHide[i].style.transform = 'scale(0)';
}
// или
(function next(i, n = elementsToHide.item(i)) {
n && (n.style.visibility = 'hidden', next(-~i));
})(0);const elements = document.querySelectorAll(selector);for (const n of elements) {
n.hidden = values.includes(Number(n.attributes[attr].value));
}
// или (в стили надо будет добавить .hidden { display: none; })
elements.forEach(function(n) {
n.classList.toggle('hidden', this.has(+n.getAttribute(attr)));
}, new Set(values));
<select v-model="selected">
<option v-for="n in deliveryPrice" :value="n">{{ n.city }}</option>
</select><div v-if="selected">
<div>{{ selected.city }}</div>
<div>{{ selected.priceFrom }}</div>
</div>[object Object], отображаемый в качестве value в разметке, то v-model пусть по-прежнему с примитивными значениями работает, а выбранный объект оформляем как computed свойство:<select v-model="city">
<option v-for="n in deliveryPrice">{{ n.city }}</option>
</select>computed: {
selected() {
return this.deliveryPrice.find(n => n.city === this.city);
},
},<select v-model="selectedIndex">
<option v-for="(n, i) in deliveryPrice" :value="i">{{ n.city }}</option>
</select>data: () => ({
selectedIndex: -1,
}),computed: {
selected() {
return this.deliveryPrice[this.selectedIndex];
},
},
let index = -1;
setInterval(() => {
index = (index + 1) % array.length;
console.log(array[index]);
}, 500);Показалось будет неудобно юзать в Вью компоненте. Мне надо при наведении мышки показывать по кругу картинки из массива и останавливать при убирании мышки.
<div
@mouseenter="установитьИнтервал"
@mouseleave="сброситьИнтервал"
>methods: {
установитьИнтервал() {
this.interval = setInterval(() => { ... }, 666);
},
сброситьИнтервал() {
clearInterval(this.interval);
},
},
function App() {
const [ values, setValues ] = useState(Array(10).fill(''));
const onChange = ({ target: t }) => {
const index = +t.dataset.index;
const value = t.value;
setValues(values.map((n, i) => i === index ? value : n));
if (index < values.length - 1 && value) {
inputRefs.current[index + 1].focus();
inputRefs.current[index + 1].select();
}
};
const inputRefs = useRef([]);
return (
<div>
{values.map((n, i) => (
<div>
<input
value={n}
data-index={i}
onChange={onChange}
ref={input => inputRefs.current[i] = input}
maxLength="1"
/>
</div>
))}
</div>
);
}
$("#changeCityInput").bind("keyup change",$('#changeCityInput').on('input',