Как передать в шаблон компонента Vue асинхронно получаемые данные не делая их реактивными
Вот предельно упрощенный код:
<template>
dict_posts.length={{ dict_posts.length }}
</template>
<script lang="ts">
import axios from "axios";
export default {
setup() {
let dict_posts: { id: number; value: string }[] = [];
axios.get('http://localhost:8000/api/dict_posts').then(resp => dict_posts = resp.data);
return {dict_posts}
}
}
</script>
Мне нужен словарь должностей, для использования в шаблоне. Словарь немалый, неизменяемый. Если сделать переменную реактивной, насколько я понимаю, на это будут тратиться определенные ресурсы, а реактивность мне не нужна, т.к. он постоянный. Но он заполняется из базы, асинхронно. Как можно передать в шаблон переменную, только после того, когда она заполнится? В реактивном варианте все понятно.
const dict_posts = ref<{ id: number; value: string }[]>([]);
axios.get('http://localhost:8000/api/dict_posts').then(resp => dict_posts.value = resp.data);
Ответы (2 шт):
Вариант 1. Если вам не нужна реактивность - просто объявите обычную переменную const dict_posts: { id: number; value: string }[] = []
Вариант 2. Если вам надо положить это в store то сделайте Object.freeze(resp.data) и данные так же не будут реактивными.
Вариант 3. Вариант с Object.freeze и ref const dict_posts = ref<readonly { id: number; value: string }[]>(Object.freeze([{ id: 1, value: '' }]));
Проблема решается с помощью асинхронной функции setup
async setup() {
const dict_posts: { id: number; value: string }[] =
(await axios.get('http://localhost:8000/api/dict_posts')).data;
return {dict_posts}
}
Но при использовании компонент необходимо обрамлять тэгом suspense, иначе выходит ошибка:
runtime-dom.esm-bundler.js?830f:30 Uncaught (in promise) TypeError: Cannot read property 'parentNode' of null
Учитывая что компонент предполагается использовать во многих местах программы, это несколько нагружает код. Интересно, нельзя ли как-нибудь обойти? А то пока в голову пришло только объявить еще один компонент с шаблоном
<suspense>
<template #default>
<мой_основной_компонент/>
</template>
<template #fallback>загрузка...</template>
</suspense>
и использовать везде уже его, а это как-то не элегантно.