Как передать в шаблон компонента 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: '' }]));

→ Ссылка
Автор решения: progervova

Проблема решается с помощью асинхронной функции 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>

и использовать везде уже его, а это как-то не элегантно.

→ Ссылка