function waitSelector(selector, root = document) {
const node = root.querySelector(selector);
if (node) return Promise.resolve(node);
return new Promise(resolve => {
new MutationObserver((_, observer) => {
const node = root.querySelector(selector);
if (node) {
observer.disconnect();
resolve(node);
}
}).observe(root, { childList: true, subtree: true });
})
}
let el = await waitSelector('#id');
Но это не для прода, разве что в юзерскриптах имеет смысл. <script>
export default {
data() {
return {
messages: [],
id: 0
}
},
methods: {
getId() {
return this.id++;
},
_jjj(){
this.messages.push({
id: this.getId(),
data: 'hk',
text: 'jjj!!!!'
});
},
_kkk(){
this.messages.push({
id: this.getId(),
data: 'ooooooooooo',
text: 'ha-ha-haaaa!!!'
});
}
}
}
</script>
<template>
<div v-for="{data, text, id} in messages" :key="id">
<b :data="data">{{text}}</b>
</div>
<button @click="_jjj">11</button>
<button @click="_kkk">12</button>
</template>
При spa без ssr domcontentloaded срабатывает один раз при загрузке страници до загрузки любого vue. Срабатывает он на по сути пустой странице. Любые переходы внутри spa ни на что более не влияют, это просто виртуальное изменение картинки через js.
Однако бот обычно не ходит внутри spa, а таки всё равно загружает каждую страницу заново.
Соответственно, насколько я понял механизм, тебе надо разместить первую часть кода в шаблоне в head, поифиг php там или ещё что, а isLoaded ставить после того как вся мета для конкретной страницы точно установлена, а не по рандомному тайм-ауту. Хз как она ставится в твоей хрени, сам поищи или проверь: может после роутера afterEach ижможет просто в mounted, может понадобится nextTick. Ты главное там где собираешься писать isLoaeed тупо через console.log querySelector проверь что там нужная инфа точно уже есть.
P.S. Я не слишком уверен что такой подход вообще рабочий, лучше бы тебе нагуглить мануал какой свежий на на тему "spa yandex сео 2024" и следовать ему.:)