Nuxt.js中window is not defined报错 求样式绑定解决方案
Hey there! The issue you're hitting is super common with Nuxt.js because of its server-side rendering (SSR) behavior. When your component renders on the server, the window object doesn’t exist yet—but you’re calling getHeight() directly in your template, which runs during the server render. Let’s fix this step by step.
Root Cause
Your template executes getHeight() during SSR, and since the server has no access to browser APIs like window, it throws the error. We need to make sure this code only runs on the client side, after the component has fully mounted.
Solution Code
Here’s how to adjust your component properly:
<template> <div class="container"> <p class="section-title">past event</p> <div class="columns is-multiline"> <div class="column is-one-third is-centered past-events" v-for="(event, index) in events.slice(0, 2)" :key="index" > <EventCard :event="event" /> </div> <div class="column is-one-third is-centered"> <!-- Bind to a data property instead of calling the method directly --> <div class="link-box" :style="{ height: linkBoxHeight }"> <nuxt-link to="/past-events"> <p style="color: #ffffff; cursor: pointer" class="see-all"> Lihat List Event Lainnya </p> </nuxt-link> </div> </div> </div> <a class="see-all-btn"></a> </div> </template> <script> import EventCard from "~/components/EventCard.vue"; export default { name: "PastEvents", components: { EventCard }, props: ["events"], data() { return { linkBoxHeight: "auto" // Set a default fallback height }; }, mounted() { this.setLinkBoxHeight(); // Optional: Update height when window resizes for responsiveness window.addEventListener("resize", this.setLinkBoxHeight); }, beforeDestroy() { // Clean up the event listener to avoid memory leaks window.removeEventListener("resize", this.setLinkBoxHeight); }, methods: { setLinkBoxHeight() { // First, check if the target element exists to avoid errors const targetElement = document.querySelector(".past-events"); if (!targetElement) return; const height = window.getComputedStyle(targetElement).height; console.log(height); this.linkBoxHeight = height; // Assign the calculated height to our data property } } }; </script>
Key Changes Explained
- Use a data property: Instead of calling
getHeight()directly in the template, we bind tolinkBoxHeight—this lets us control when the height is calculated, avoiding SSR conflicts. - Run code in
mounted: Themountedhook only runs on the client side, sowindowanddocumentare guaranteed to exist here. - Add error handling: We check if the target element exists before accessing its style, preventing unexpected errors if the element isn’t rendered yet.
- Optional resize listener: If you need the height to update when the window is resized, adding and cleaning up this listener keeps your component responsive and performant.
Extra Quick Fix (If You Don’t Need SSR for This Section)
If you’re okay with skipping SSR for the link box, you can wrap it in Nuxt’s <client-only> tag. This tells Nuxt to only render that part on the client:
<client-only> <div class="link-box" :style="{ height: getHeight() }"> <!-- Your link content here --> </div> </client-only>
Note: This approach is simpler but skips SSR for that component section, so the first method is usually better for maintainability and SEO.
内容的提问来源于stack exchange,提问作者user11760440

