Pinia Store在开发环境正常,构建版本出现undefined问题
问题原因与解决方案
核心问题
你在组件中混合使用了<script setup>和选项式<script>,但<script setup>中声明的dataStore、inputDataStore是组件私有变量,不会挂载到组件实例this上。开发环境的宽松检查没触发错误,但构建时代码优化后,选项式钩子中调用this.dataStore就会直接返回undefined。
推荐解决方案:统一使用<script setup>
将所有生命周期钩子、方法移到<script setup>中,这是Vue 3推荐的组合式API写法,避免混合写法的变量作用域问题:
<script setup> import FormState1 from "@/components/FormStateStep1.vue"; import FormState2 from "@/components/FormStateStep2.vue"; import FormState3 from "@/components/FormStateStep3.vue"; import FormStateFinish from "@/components/FormStateStepFinish.vue"; import { useDataStore } from "../stores/stateData.js"; import { useInputDataStore } from "../stores/inputData.js"; import { onBeforeMount, onMounted, ref } from 'vue'; // 初始化Store实例 const dataStore = useDataStore(); const inputDataStore = useInputDataStore(); // 替代选项式的$refs const formularTop = ref(null); // 替代beforeCreate钩子 onBeforeMount(() => { if (dataStore.getAge >= 1) { localStorage.clear(); dataStore.$reset(); inputDataStore.$reset(); } }); // 替代mounted钩子 onMounted(() => { dataStore.updateTimestamp(); }); // 替代methods中的方法 const scrollToTop = () => { formularTop.value.scrollIntoView({ behavior: "smooth" }); }; </script> <template> <div class="grid-container bewerbungsform direkt"> <div ref="formularTop" style="height: 50px; position: absolute; top: -50px; pointer-events: none"></div> <div v-if="dataStore.formState == 0"> <FormState1 /> </div> <div v-else-if="dataStore.formState === 1"> <FormState2 /> </div> <div v-else-if="dataStore.formState === 2"> <FormState3 /> </div> <div v-else-if="dataStore.formState === 3"> <FormStateFinish /> </div> </div> </template>
备选方案:在选项式中重新初始化Store
如果一定要保留选项式写法,需要在选项式的钩子中重新调用useStore获取实例,而不是依赖<script setup>中的变量:
<script setup> import FormState1 from "@/components/FormStateStep1.vue"; import FormState2 from "@/components/FormStateStep2.vue"; import FormState3 from "@/components/FormStateStep3.vue"; import FormStateFinish from "@/components/FormStateStepFinish.vue"; import { useDataStore } from "../stores/stateData.js"; import { useInputDataStore } from "../stores/inputData.js"; const dataStore = useDataStore(); const inputDataStore = useInputDataStore(); </script> <template> <div class="grid-container bewerbungsform direkt"> <div ref="formular-top" style="height: 50px; position: absolute; top: -50px; pointer-events: none"></div> <div v-if="dataStore.formState == 0"> <FormState1 /> </div> <div v-else-if="dataStore.formState === 1"> <FormState2 /> </div> <div v-else-if="dataStore.formState === 2"> <FormState3 /> </div> <div v-else-if="dataStore.formState === 3"> <FormStateFinish /> </div> </div> </template> <script> import { useDataStore } from "../stores/stateData.js"; import { useInputDataStore } from "../stores/inputData.js"; export default { name: "FormView", components: { FormState1, FormState2, FormState3, FormStateFinish, }, beforeCreate() { // 直接在选项式中初始化Store实例 this.dataStore = useDataStore(); this.inputDataStore = useInputDataStore(); if (this.dataStore.getAge >= 1) { localStorage.clear(); this.dataStore.$reset(); this.inputDataStore.$reset(); } }, mounted() { this.dataStore.updateTimestamp(); }, methods: { scrollToTop() { this.$refs["formular-top"].scrollIntoView({ behavior: "smooth" }); }, }, }; </script>
内容的提问来源于stack exchange,提问作者BoxerBuffa
相关产品推荐
相关产品推荐

