Не могу закрыть поп-ап
dialog: [],dialog[index]= falseПри нажатии на кнопку, при выборе 3 изображения на превью открывается всегда первое.
data: () => ({
slide: null,
dialog: false,
...
}),
methods: {
openDialog(slideIndex) {
this.slide = slideIndex;
this.dialog = true;
},
...
},v-row
v-col(v-for="(n, i) in pictures")
v-item
v-img(height="100", width="100", :src="n", @click="openDialog(i)")
v-col(hidden="")
v-dialog(v-model="dialog")
v-carousel(v-model="slide")
v-carousel-item(v-for="n in pictures")
v-img(:src="n")
v-btn(@click="dialog = false") close dialog
<div className="mainWindow">
{this.props.children}
</div>
<posts :posts="$store.state.posts" /><router-link :to="{ name: 'home', params: { posts } }">home</router-link>this.$router.push({
name: 'home',
params: {
posts: this.posts,
},
});router-link или вызова $router.push. При этом, если переход осуществляется не из корневого компонента, то, чтобы дотянуться до posts, придётся ещё и $root использовать. В случае же, когда пользователь решит осуществить переход посредством адресной строки браузера, то ничего передать не получится.router-view, тогда они будут переданы как параметры в компонент текущего маршрута: <router-view :posts="post" />.$attrs). Чтобы передавать что надо только куда надо, можно оформить параметры, передаваемые в router-view, как вычисляемое свойство, значение которого будет зависеть от текущего маршрута:computed: {
routeParams() {
return что-то, в зависимости от this.$route;
},
},<router-view v-bind="routeParams" />
function Modal(props) {
const root = useRef();
useEffect(() => {
const onClick = e => root.current.contains(e.target) || закрытьОкно();
document.addEventListener('click', onClick);
return () => document.removeEventListener('click', onClick);
}, []);
return (
<div ref={root}>
...
</div>
);
}function Modal(props) {
return (
<div
className="modal-overlay"
onClick={e => (e.currentTarget === e.target) && закрытьОкно()}
>
...
</div>
);
}.modal-overlay {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
}
document.querySelector('table').addEventListener('click', ({ target: t }) => {
if (t.classList.contains('save_order')) {
const tr = t.closest('tr');
console.log(tr);
}
// или
if (t.matches('.save_order')) {
let tr = t;
while ((tr = tr.parentNode).tagName !== 'TR') ;
console.log(tr);
}
});
arr.pop();
// или
arr.length -= !!arr.length;
// или
arr.splice(-1);const count = сколько надо удалить;):for (let i = count; --i >= 0 && arr.length; arr.pop()) ;
// или
arr.length -= Math.max(0, Math.min(arr.length, count));
// или
count > 0 && arr.splice(-count);
echo implode('', array_map(function($author, $book) {
return '<p>Книга '.$book['nameBook'].', ее написал '.$author['fio'].', '.$author['email'].'</p>';
}, $arr['authors'], $arr['books']));
document.addEventListener('input', ({ target: t }) => {
if (t.classList.contains('rating__value')) {
const value = +t.value;
t.closest('.item-rating').querySelector('.rating__dynamic').innerHTML = Array
.from({ length: 5 }, (n, i) => `<span class="char">${'☆★'[+(value > i)]}</span>`)
.join('');
}
});
document.querySelectorAll('.rating__value').forEach(n => {
n.dispatchEvent(new Event('input', { bubbles: true }));
});for (const n of document.getElementsByClassName('rating__value')) {
n.previousElementSibling.innerHTML = '<span class="char"></span>'.repeat(5);
n.addEventListener('input', onRatingInput);
onRatingInput.call(n);
}
function onRatingInput() {
const value = this.value | 0;
const stars = this.previousElementSibling.children;
for (let i = 0; i < stars.length; i++) {
stars[i].innerText = value > i ? '★' : '☆';
}
}
tbody для каждой пары строк. Переносите tbody из компонента таблицы в компонент строки - будет там корневым элементом:<tbody>
<tr>... </tr>
<tr v-if="...">...</tr>
</tbody>tr сразу в компоненте таблицы:<tbody>
<template v-for="...">
<tr>... </tr>
<tr v-if="...">...</tr>
</template>
</body>
data: () => ({
formData: {},
formMeta: [
{ name: 'phone', title: 'Телефон', type: 'text', placeholder: 'Телефон' },
{ name: 'email', title: 'E-mail', type: 'text', placeholder: 'E-mail' },
{ name: 'address', title: 'Адрес', type: 'text', placeholder: 'Адрес' },
...
],
}),this.$emit('save-contact', this.formData);<div v-for="n in formMeta">
<span class="form__other-title">{{ n.title }}</span>
<div class="form__other-data">
<input
v-model="formData[n.name]"
:type="n.type"
:placeholder="n.placeholder"
>
</div>
</div>
работать с dom напрямую плохая практика
props: [ 'items', 'value' ],data: () => ({
sliderStyles: null,
}),<ul class="tabs">
<li
v-for="n in items"
:key="n.value"
@click="$emit('input', n.value)"
class="tabs-item"
>{{ n.text }}</li>
</ul>
<div
class="tabs-slider"
:style="sliderStyles"
></div>.tabs-slider) зададим абсолютное позиционирование и transition.mounted() {
this.$watch(
'value',
value => {
const index = this.items.findIndex(n => n.value === value);
const el = this.$el.querySelectorAll('.tabs-item')[index];
this.sliderStyles = el
? {
left: `${el.offsetLeft}px`,
width: `${el.offsetWidth}px`,
}
: null;
},
{
immediate: true,
}
);
},
const listTag = 'ul';
const listClass = 'list';
const itemTag = 'li';
const itemClass = 'item';
const activeClass = 'active';const list = document.createElement(listTag);
const items = arr.map(function(n) {
const item = document.createElement(itemTag);
item.textContent = n.text;
item.classList.add(itemClass);
item.addEventListener('click', this);
return item;
}, function() {
list.style.setProperty('background-image', `url(${arr[items.indexOf(this)].url})`);
items.forEach(n => n.classList.toggle(activeClass, n === this));
});
list.classList.add(listClass);
list.append(...items);
document.body.append(list);
items[0].click();document.body.insertAdjacentHTML('beforeend', `
<${listTag} class="${listClass}">${arr.map(({ url, text }) => `
<${itemTag} class="${itemClass}" data-url="${url}">${text}</${itemTag}>`).join``}
</${listTag}>
`);
const list = document.body.lastElementChild;
list.addEventListener('click', ({ target: t }) => {
if (t = t.closest(`${itemTag}.${itemClass}`)) {
list.style.backgroundImage = `url(${t.dataset.url})`;
list.querySelector(`.${activeClass}`)?.classList.remove(activeClass);
t.classList.add(activeClass);
}
});
list.children[0].dispatchEvent(new Event('click', { bubbles: true }));
const sorted = (arr, key) => arr
.map(n => [ key(n), n ])
.sort(([a], [b]) => a < b ? -1 : +(a > b))
.map(n => n[1]);const sortedArr = sorted(
arr,
n => new Date(n.date.replace(/(\d+)\.(\d+)\.(\d+)/, '$3-$2-$1'))
);
// или
const sortedArr = sorted(
arr,
n => n.date.replace(/[^T]+/, m => m.split('.').reverse().join(''))
);
const getMinimumUniqueSum = arr => [...arr]
.sort((a, b) => a - b)
.reduce((acc, n) => (acc[1] += acc[0] = Math.max(acc[0] + 1, n), acc), [ -Infinity, 0 ])
.pop();
const find = (arr, id) =>
(Array.isArray(arr) ? arr : []).reduce((found, n) =>
found || (n.id === id ? n : find(n.replies, id))
, null);