Я столкнулся с проблемой, из-за которой я уже несколько дней чешу голову. Я делаю приложение с интерфейсом vuejs3.
Из всего кода, который я предоставляю, я удалил большую часть остального кода и сохранил то, что считаю важным, чтобы сделать его более читабельным. Если вам нужна дополнительная информация, дайте мне знать, и я обновлю вопрос.
Мой основной JS:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router.js';
const app = createApp(App);
app.use(router);
app.mount('#app');
Это мой App.vue:
<template>
<div>
<!-- if I put <Userbasket /> here it works -->
<div>
<router-view v-slot = "{ Component }">
<Transition mode = "out-in">
<component :is = "Component"/>
</Transition>
</router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
Соответствующий маршрутизатор vue:
import { createRouter, createWebHistory } from 'vue-router';
import HomeView from "@/views/Home.vue";
const routes = [
{
name: 'home',
path: '/home',
component: HomeView,
},
{
name: 'root',
path: '/',
redirect: '/home',
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes: routes
});
export default router;
И мой Home.vue:
<template>
<div class = "d-flex p-2">
<div class = "row-12 mb-2">
<WeekSummary />
</div>
<div class = "row-12 mb-2">
<!-- here it doesn't work, thrown warning in console -->
<UserBasket />
<!-- OtherComp renders correctly -->
<OtherComp/>
</div>
</div>
</template>
<script>
import WeekSummary from '@/components/WeekSummary.vue'
import UserBasket from '@/components/UserBasket.vue';
import OtherComp from '@/components/OtherComp.vue';
export default {
name: 'HomeView',
components: {
WeekSummary,
UserBasket,
OtherComp,
}
};
</script>
И компонент, который я пытаюсь визуализировать UserBasket.vue:
<template>
<div>
... lots of div and span ...
</div>
</template>
<script>
// no child component
export default {
name: 'UserBasket',
}
</script>
И моя структура каталогов:
src
|-components
| |-UserBasket.vue
| |-Popup.vue
| |-WeekSummary.vue
| |-OtherComp.vue // and more
|-views
| |-Home.vue
| |-OtherView.vue // and more
|-App.vue
|-main.js
|-router.js
Итак, я пытаюсь отобразить компонент UserBasket, но получаю ошибку, указанную в заголовке. Что странно, у меня более 20 компонентов, и это единственный, который не хочет рендериться.
Компонент UserBasket на самом деле находится внутри компонента WeekSummary, но я переместил его в HomeView, пытаясь отладить это, но ошибка все еще появляется, поэтому оставил его там для простоты. Я также попытался переместить его в корневой компонент в App.vue, и там он отображается без проблем, поэтому я не думаю, что это опечатка, как предполагают другие ответы на вопросы SO. Я также скопировал оператор импорта из дочернего компонента, в котором появилась ошибка, в App.vue, чтобы убедиться, что это не опечатка.
Во время разработки я использую npm run serve
для его запуска, чтобы он автоматически перезагружался, если я меняю файл. Когда я сохраняю файл UserBasket.vue, он перезагружается и действительно может импортировать и правильно отобразить его без предупреждения, поэтому я думаю, что здесь нет опечатки. Но если я перезагрузлю страницу, компонент больше не отобразится.
Я попробовал создать приложение с помощью npm run build
, и во встроенной версии также возникла эта проблема.
Я также попытался поместить другой компонент рядом с UserBasket, и другой отобразился правильно. Другой компонент находится в той же папке, что и UserBasket, и я использовал тот же метод объявления пути. "@/comComponents/OtherComp.vue" похож на "@/comComponents/UserBasket.vue", поэтому я не думаю, что это проблема с путем. Я также попробовал путь «./comComponents/UserBasket.vue» и «./UserBasket.vue» в файле WeekSummary.vue.
Я хочу отметить, что в WeekSummary у меня есть еще один компонент «Popup.vue», который отображается правильно, а файл «Popup.vue» находится рядом с UserBasket.vue в папке компонентов.
мои версии vue:
"vue": "^3.4.31",
"vue-router": "^4.2.5",
Я также попробовал перейти на версию 3.3.0, но проблема все еще существует.
UserBasket используется в 3-х местах и ни в одном не работает.
на загруженном сайте, проверяющем HTML DOM в браузере, там, где он должен быть, есть тег <userbasket></userbasket>
.
Предупреждение консоли выводится из трех разных строк для каждого места, где я использовал UserBasket.
app.use(router);
.this.user = response.data;
Я не знаю, почему это здесь.basket.basket = data.basket;
Обратите внимание, что во втором и третьем я сохраняю данные в объект хранилища Pinia. На данный момент я не знаю, что актуально или нет.
Мой vue.config.js, если это имеет значение:
const { defineConfig } = require('@vue/cli-service');
const packageJson = require('./package.json');
module.exports = defineConfig({
chainWebpack: (config) => {
// Set environment variables for Webpack
config.plugin('define').tap((args) => {
args[0]['process.env'].VUE_APP_VERSION = JSON.stringify(packageJson.version);
return args;
})
},
configureWebpack: {
devServer: {
historyApiFallback: true
}
},
transpileDependencies: true
});
Что я пробовал из другого вопроса, связанного с SO:
components
, а не в component
shift + f5
.Спасибо, что прочитали мой вопрос, дайте мне знать, если вам нужна дополнительная информация.
Обновлять
В браузере ни одно другое предупреждение vue не отображало только один флаг функции:
Feature flag __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined. You are running the esm-bundler build of Vue, which expects these compile-time feature flags to be globally injected via the bundler config in order to get better tree-shaking in the production bundle.
Попробовав предложение @yoduh (спасибо) удалить код для упрощения компонента UserBasket, я удалил каждое использование моего хранилища pinia из моего компонента (того, где выдаются предупреждения), сохранил файл. В консоли не отображается предупреждение, и мой компонент отображается нормально. Итак, я думаю, что объект состояния Pinia где-то сломался.
Для дальнейшего расследования я попытался полностью удалить из UserBasket только свое хранилище корзин, никаких предупреждений не было, и компонент отработал нормально. Я обнаружил, что простое наличие строки импорта в компоненте каким-то образом нарушит ссылку. Я попытался удалить каждую строку из всего проекта, в которой обновляю значение корзины, но ничего не изменилось.
Я также попробовал закомментировать все методы получения и действия в магазине, но это ничего не изменило.
В WeekSummary у меня был оператор vue watch, определенный для моего хранилища аутентификации, я удалил его, и он избавился от одного из предупреждений, которое было указано на файл хранилища auth.js. Я предполагаю, что где-то я пытаюсь обновить значение хранилища корзины, но я не уверен. Единственное предупреждение (появляется 4 раза подряд) слева — это указание на строку app.use(router)
в моем main.js. Еще следует отметить, что журнал Pinia по умолчанию 🍍 "basket" store installed 🆕
не распечатывается в консоли ни в одном из моих магазинов. С помощью браузерного расширения vue devtools я вижу, что мои хранилища имеют действительные значения.
Комментирование использования UserBasket внутри WeekSummary уменьшает количество предупреждений с 4 до 1, а строки журнала Pinia регистрируются в консоли. Единственное оставшееся использование UserBasket — это файл Home.vue для целей отладки этой проблемы.
Я не нашел никаких проблем на странице GitHub Пинии по этому поводу.
Моя корзина.js, если это поможет:
import { defineStore } from 'pinia'
import { useAuth } from "@/stores/auth";
import { state as vuestate, socket } from "@/socket.js";
// other nonrelated imports...
export const useBasket = defineStore('basket', {
state: () => ({basket: {}}),
getters: {
// my getters...
},
actions: {
// my actions...
}
})
Обновление 2
Я успешно создал репродукцию на playcode.io: https://playcode.io/1932830
Что хочу отметить:
ReferenceError: setImmediate is not defined
в консоли, как на этом сайте.Обновление 3
Основная причина того, что решение было трудно найти, заключалась в том, что в моей локальной среде разработки ReferenceError
не отображался в моей консоли, что делало невозможным или, по крайней мере, очень трудным поиск подобных вопросов SO. Это был огромный намек. Ошибка была отображена в ссылке на воспроизведение, что позволило решить проблему. Надеюсь, что другие найдут это полезным.
В текущей форме вопрос не дает возможности воспроизвести проблему, что делает невозможным отладку или тестирование потенциальных исправлений. Я предлагаю создать работоспособный минимально воспроизводимый пример на codeandbox.io или аналогичном. Если вы не можете создать работоспособный фрагмент, по крайней мере, предоставьте ссылку на репозиторий.
Этот вопрос похож на: Почему ReferenceError: setImmediate не определен, когда я его вообще не использую?. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.
@tao Я обновил вопрос, почему я думаю, что это не похоже, если ты все еще думаешь, что это нормально. Как вы думаете, улучшится ли читабельность вопроса, если я удалю блоки кода? Код можно найти в ссылке на репродукцию, поэтому он будет по-прежнему доступен в вопросе. Но это будет от стороннего сервиса. Дайте мне знать
Ошибка возникает из-за socket.js
, а UserBasket.vue
импортирует ее через store/basket.js
.
Исправление в вашем случае:
setimmediate
полифил:npm i setimmediate
socket.js
:import 'setimmediate'
main.js
import { socket } from './socket'
...
export { socket }
basket.js
:import { socket } from '../main'
// not from '../socket' !!!
Смотрите работает.
Итак, везде, где я использую сокет, мне нужно импортировать его из основного, если я правильно понимаю?
@Таракос, это правильно. Я не знаю почему, но если вы загрузите socket.js
в магазин до создания экземпляра приложения, вы получите ошибку. Реэкспортируя socket
из ./main
, мы гарантируем, что экземпляр приложения существует до того, как будет использован код socket
.
Компонент, работающий после горячей перезагрузки, но не после полного обновления страницы, обычно является признаком нарушенной реактивности. Возможно, проблема где-то в коде скрипта компонента UserBasket. Есть ли какие-либо другие предупреждения или ошибки в консоли? Чтобы подтвердить, что проблема связана с кодом сценария компонента, удалите весь код из компонента и сделайте его как можно проще. Это рендерится?