items.forEach(item => item.alert = false)
const [selected, setSelected] = useState('all');
let filterdTodos;
switch(selected) {
case 'all':
filterdTodos = todos;
break;
case 'checked':
filterdTodos = todos.filter(t => t.checked);
break;
case 'notChecked':
filterdTodos = todos.filter(t => !t.checked);
break;
}
const [selected, setSelected] = useState('all');
const filterdTodos = useMemo(() => {
switch(selected) {
case 'all':
return todos;
case 'checked':
return todos.filter(t => t.checked);
case 'notChecked':
return todos.filter(t => !t.checked);
}
}, [selected, todos])
<select className="todos__filter" onChange={(event) =>setSelected(event.target.value)}>
...
{filterdTodos.map(...)}
products
должны быть ref
. Сейчас они не реактивны(никак не реагируют на изменения). При этом ты присваииваешь массиву value. То что это хоть как-то работало - очередное чудо.export const useAllMainFiltersStore = defineStore('allMainFilters', () => {
const products = ref([]);
try {
async function getStoreData() {
sidebarResizeStore.updateSidebarVisibility()
const data = await productsData();
products.value = data;
}
getStoreData()
} catch (error) {
console.error('Error:', error);
}
return {
products,
}
})
const route = useRoute();
// продукт делаем вычисляемым, чтоб не городить вотчеров
const product = computed(() => getProductById(route.params.id));
function getProductById(id) {
console.log('products component: ', mainFiltersStore.products) //при первой загрузке всё ок, при перезагрузке страницы всё ломается и пустой массив в придачу
return products.find(product => product.id == id);
}
watch(product, current => {
// проверяем что продукт есть
if (current) fetchComments(current.id);
}, { immediate: true })
inline
, тут используется кастомный иконсет settings
. input
нет свойства length
.var intxt=document.querySelector('input').length;
intxt === undefined
console.log
вообще-то должен был тебе это показать.if(intxt.length<5){
тут ты пытаешься получить свойство length
у unefined
о чем тебе и пишет ошибка.var intxt=document.querySelector('input');
....
if(intxt.value.length<5){
....
} else {
async function multiStep() {
await step1();
if (stop) throw new Error(stop);
await step2();
if (stop) throw new Error(stop);
await step3();
if (stop) throw new Error(stop);
}
и никак красивее не сделать. function* multiStep() {
yield step1();
yield step2();
yield step3();
}
import { ref, h } from 'vue';
function loadScript(options, root = document.head) {
return root.appendChild(Object.assign(document.createElement('script'), options));
}
const Comp = defineComponent(() => {
const root = ref(null);
onMounted(() => {
loadScript(
{
innerHTML: `
!(function (a, m, o, c, r, m) {
(a[o + c] = a[o + c] || {
setMeta: function (p) {
this.params = (this.params || []).concat([p]);
},
}),
(a[o + r] =
a[o + r] ||
function (f) {
a[o + r].f = (a[o + r].f || []).concat([f]);
}),
a[o + r]({
id: "....",
hash: "....",
locale: "ru",
}),
(a[o + m] =
a[o + m] ||
function (f, k) {
a[o + m].f = (a[o + m].f || []).concat([[f, k]]);
});
})(window, 0, "amo_forms_", "params", "load", "loaded");
`
},
root.value
);
loadScript(
{
id: 'amoforms_script_...',
async: 'async',
charset: 'utf-8',
src: 'https://forms.amocrm.ru/forms/assets/js/amoforms.js?...'
},
root.value
);
});
return () => h('div', { ref: root });
});
script type="module
" через import
(никаких глобальных вызовов)./browse
.<script type="importmap">
{
"imports": {
"tictic": "https://unpkg.com/tictic@0.1.0/esm/index.js",
"tslib": "https://unpkg.com/tslib@2.6.2/tslib.es6.js"
}
}
</script>
<script type="module">
import { getDate } from 'tictic';
console.log(getDate({}));
</script>
[role="row"]:has(.fraud) {
background-color: #f1f7bc;
}
[role="row"] {
position: relative;
background-color: transparent;
}
[role="row"] .fraud::before {
content: "";
display: block;
position: absolute;
z-index: -1;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: #f1f7bc;
}
MutationObserver
и следить за появлением новых [role="row"]
. const lines = [1, 2, 3];
return lines.map(line => (
<p> {line} </p>
));
function Component() {
const [lines, setLines] = useState([1, 2, 3]);
const addLine = useCallback(() => {
setLines(lines => [...lines, lines.length+1])
});
return(
<>
<button onClick={addLine} className="button">
addLine
</button>
{lines.map(line => (
<p> {line} </p>
))}
</>
}
setTimeout
(тут я обернул его в Promise
для простоты и наглядности):const delay = (ms) => new Promise(r => setTimeout(r, ms))
function Component() {
const [lines, setLines] = useState([]);
const addLines = useCallback(async () => {
let i = 0;
while(i++ < 10) {
await delay(1000);
setLines(lines => [...lines, i])
}
});
return(
<>
<button onClick={addLines} className="button">
addLine
</button>
{lines.map(line => (
<p> {line} </p>
))}
</>
);
}
fetch
в котором у Request
body
- это ReadableStream
, растянув таким образом запрос настолько - насколько надо. Но это всё же не совсем то же самое что просто медленный запрос.[class^="chat__root__"]
. Заметьте я использовал не полное имя класса, а только начало и модификатор ^=
указывающий сверять только начало(если класс не первый, то можно использовать *=
). Почему? Потому что "непонятные буковки" в конце - это генерируемый при сборке хэш, который поменяется при выпуске следующей версии фронта и если вы к нему привяжитесь - ваш скрипт очень скоро перестанет работать.// @run-at document-start
function addCss(css, root = window) {
const style = root.document.createElement('style');
style.innerHTML = css;
(root.document.head || root.document.documentElement).append(style);
return style;
}
const css = `
[class^="chat__root__"] {
dislpay: none !important;
}
`;
addCss(css);
// @run-at document-start
const css = `
[class^="chat__root__"] {
dislpay: none !important;
}
`;
// отлавливаем загрузку фреймов
new MutationObserver(() => {
document.querySelectorAll('iframe:not([us-processed]').forEach((iframe) => {
if (isAccessibleFrame(iframe)) {
// добавляем наш css
addCss(css, iframe.contentWindow);
// на случай если содержимое фрейма перепишут позднее
iframe.addEventListener('load', () => addCss(css, iframe.contentWindow));
}
// помечаем что обработали этот фрем, чтоб не повторять
iframe.setAttribute('us-processed', true);
});
}).observe(document, {childList: true, subtree: true});
// проверяем что содержимое фрейма доступно
function isAccessibleFrame(iframe) {
try {
iframe.contentWindow.test
return true
} catch (e) {
return false
}
}
Swiper
не ждёт свойства spaceBetween
. Вы уверены, что оно хоть что-то делает?Swiper
и на самом деле он такое свойство ждёт, то вам следует репортить этот баг автору компонента (предварительно обновившись до последней версии).declare module 'путь до типов компонента Swiper' {
interface SwiperProps {
spaceBetween: number;
}
}