首页 > 解决方案 > 为什么 getComputedStyle() 方法在我的 Nuxt 应用程序中无法正常工作?

问题描述

我正在使用 Nuxt 应用程序,并在我的项目中使用 SSR 模式和 Vuex。在我的一个页面中,我有两列,它们的数据(它们的文本)来自 Vuex。这是我页面的代码:

<template>
    <div>
        <v-container>
            <v-row no-gutters>
                <v-col cols = "12" md="7">
                    <v-sheet>
                        <v-card class="topCard mt-12">
                            <h1 class="headTitle pb-6 px-12">
                                {{ this.title1 }}
                            </h1>
                            <h2 class="headTitle pb-6 px-12">
                                {{ this.subtitle1 }}
                            </h2>

                            <p class="px-12 py-6 paraCard">
                                <span>برچسب(ها): </span>
                                <span class="tagSpan mx-2 px-4" v-for="item in finalTags" :key="item">
                                    {{ item }}
                                </span>
                            </p>

                            <p class="paraCard pt-2">
                                نویسنده:
                                <v-chip
                                outlined
                                large
                                class="pa-5 mr-4"
                                color="var(--color3)"
                                >
                                    {{ this.author1 }}
                                </v-chip> 
                            </p>
                            
                        </v-card>
                    </v-sheet>
                </v-col>

                <v-col cols = "12" md="5">
                    <v-sheet>
                        <v-card class="topCard mt-12">
                            <v-img
                            transition="scale-transition"
                            v-show="show"
                            max-width="250"
                            :src="require(`~/assets/imgs/books/${this.idPage}.webp`)"
                            >
                            </v-img>
                        </v-card>
                    </v-sheet>
                    
                </v-col>
            </v-row>

            <v-row no-gutters class="my-16">
                <v-col cols = "12" md="7">
                    <div class="tozihClass">
                        <div>
                            <h1 class="text-center pa-5">معرفی کتاب {{ this.title1 }}</h1>
                            <p class="pa-4">
                                {{ this.kamelTozih1 }}
                            </p>
                        </div>
                    </div>
                </v-col>

                <v-col cols = "12" md="5">
                    <div class="tozihClass">
                        <div>
                            <h1 class="text-center pa-5">
                                عناوین مهم کتاب
                            </h1>
                            <ul class="px-12">
                                <li :key="item" v-for="item in titleSet">
                                    {{ item }}
                                </li>
                            </ul>
                        </div>
                    </div>
                </v-col>
            </v-row>
        </v-container>
    </div>
</template>

<script>

export default {
    data() {
        return {
            allBooks: [],
            allTags: [],
            finalTags: [],
            idPage: 3,
            title1: "",
            author1: "",
            subtitle1: "",
            kamelTozih1: "",
            titleSet: [],
            show: false
        }   
    },
    methods: {
        findData: function(inputArr) {
            this.title1 = inputArr.find(x => x.id == this.idPage).title;
            this.author1 = inputArr.find(x => x.id == this.idPage).author;
            this.kamelTozih1 = inputArr.find(x => x.id == this.idPage).kamelTozih;
            this.subtitle1 = inputArr.find(x => x.id == this.idPage).tozih;
            this.titleSet = inputArr.find(x => x.id == this.idPage).titleList;
            /* finding tag names */
            // ------------------
            let tagIds = inputArr.find(x => x.id == this.idPage).tags;
            this.findTags(tagIds);
        },

        findTags(inputTags) {
            let arrInit = [];
            inputTags.forEach(element => {
                arrInit.push( this.allTags.find(x => x.id == element).name );
            });
            this.finalTags = arrInit;
        },

        setHeight() {
            let elem = document.querySelectorAll('.tozihClass');
            let finalHeight = window.getComputedStyle(elem[1]).getPropertyValue("height");
            console.log(finalHeight);
            document.documentElement.style.setProperty("--equHeigth", finalHeight);
            document.body.style.setProperty("--equHeigth", finalHeight);
        }
    },
    mounted() {
        this.allBooks = this.$store.state.books.list;
        this.allTags = this.$store.state.books.tags;
        this.findData(this.allBooks);

        if (document.readyState === "complete") { 
            this.setHeight(); 
        }
        
    },
    created() {
        this.show = true;
    }
}
</script>

<style scoped>
.headTitle {
    color: var(--color4);
    font-size: 3rem;
    text-shadow: 2px 3px 5px var(--color1);
}

h2.headTitle {
    font-size: 1.8rem;
}

.topCard {
    min-height: 375px;
    background-color: var(--color5a);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
}

.paraCard {
    color: var(--color3);
    font-size: 1.5rem;
    border-top: 1px solid var(--color3a);
}

.tagSpan {
    border: 2px solid var(--color2);
    cursor: pointer;
}

.tagSpan:hover {
    background-color: var(--color3a);
}

.tozihClass {
    background-color: var(--color6a);
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--equHeigth);
}

.tozihClass h1 {
    color: var(--color2);
    font-size: 2.3rem;
}

.tozihClass p {
    color: var(--color4);
    font-size: 1.6rem;
    line-height: 1.7;
    text-align: justify;
}

.tozihClass ul {
    font-size: 1.5rem;
}
</style>

这是我商店文件夹中的books.js文件:

import bookData from "~/assets/json-data/bookList.json";
import tagData from "~/assets/json-data/tagList.json";
export const state = () => ({
    tags: tagData,
    list: bookData
})

它只是从json文件中获取数据并将它们加载到文档中。我想在setHeight() 页面方法中使用getComputedStyle() 方法计算较高列(包含ul元素的列)的高度,然后为其设置自定义 css 属性(--equHeigth)值。并且该值必须自动设置为其他列(因为它们具有相同的类)。但它不会计算高度并返回我设置的--equHeigth的默认值(例如 625px)。

但我注意到,如果我在没有 Vuex 的情况下设置数据,它可以正常工作:

<template>
    <div>
        <v-container>

            <v-row no-gutters class="my-16">
                <v-col cols = "12" md="7">
                    <div class="tozihClass">
                        <div>
                            <h1 class="text-center pa-5">معرفی کتاب شیب</h1>
                            <p class="pa-4">
                                خلاصه کتاب شیب از ست گودین (ترجمه کتاب The Dip) راجع‌به پدیده‌ی شیب صحبت می‌کنه توی مسیر موفقیت برای هرکسی وجود داره. چه توی زندگی شخصی و چه توی زندگی کاری، معمولا اوایل خیلی ذوق و شوق داریم و همه‌چیز بر وفق مراده، اما به‌مرور زمان عبارت مشهور «که عشق آسان نمود اول ولی افتاد مشکل‌ها» خودش رو در عمل نشون میده و سروکله‌ی مشکلات و موانع پیدا می‌شه. ست گودین توی خلاصه کتاب شیب میگه که مواجه‌شدن با چنین چیزی اجتناب‌ناپذیره، اما مهم اینه که توی بازه‌ی شیب، به‌درستی موانع رو تشخیص بدی و ببینی که آیا این موانع عادیِ مسیر هستن یا چیزهای غیرقابل‌رفعی هستن که مستقیما به ماهیت کار یا زندگیت مربوط می‌شن.
                            </p>
                        </div>
                    </div>
                </v-col>

                <v-col cols = "12" md="5">
                    <div class="tozihClass">
                        <div>
                            <h1 class="text-center pa-5">
                                عناوین مهم کتاب
                            </h1>
                            <ul class="px-12">
                                <li :key="item" v-for="item in titleSet">
                                    {{ item }}
                                </li>
                            </ul>
                            
                        </div>
                    </div>
                </v-col>
            </v-row>
        </v-container>
    </div>
</template>

<script>

export default {
    data() {
        return {
            /* arrays that must fill the li */
            titleSet: ["موضوع کتاب راجع‌به چیه؟ چرا رهاکردنِ به‌موقعِ پروژه‌ها یه اقدام هنرمندانه هست؟", "هر هدفی که داشته باشی، وقوع پدیده‌ی شیب یا دوره‌ی چالش‌برانگیز اجتناب‌ناپذیره", "بهترین‌بودن  توأم با مزیت‌های آشکار و پنهان مهمی هست ", "تخصص‌داشتن و آگاهی از نحوه‌ی خروج استراتژیک برای موفقیت ضروریه ", "چه توی زندگی کاری و چه زندگی شخصی، قطعا با پدیده‌ی شیب روبه‌رو میشی ", "موفقیت از دل پدیده‌ی شیب بیرون می‌زنه ", "شیب می‌تونه مزیت رقابتی ایجاد کنه ", "برای دَووم‌آوردن در دوران شیب باید صبور و سرسخت باشی و کم نیاری "]
            
        }   
    },
    methods: {

        setHeight() {
            /* method that must calcilate the height of lists and set them to other part */
            let elem = document.querySelectorAll('.tozihClass');
            let finalHeight = window.getComputedStyle(elem[1]).getPropertyValue("height");

            console.log(finalHeight);

            document.documentElement.style.setProperty("--equHeigth", finalHeight);
            document.body.style.setProperty("--equHeigth", finalHeight);
        }
    },
    mounted() {
        if (document.readyState === "complete") { 
            this.setHeight(); 
        }
    },
}
</script>

<style scoped>


.tozihClass {
    background-color: var(--color6a);
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: var(--equHeigth);
}

.tozihClass h1 {
    color: var(--color2);
    font-size: 2.3rem;
}

.tozihClass p {
    color: var(--color4);
    font-size: 1.6rem;
    line-height: 1.7;
    text-align: justify;
}

.tozihClass ul {
    font-size: 1.5rem;
}
</style>

在上面的代码中,我为titleSet 数据设置了一个数组,并且没有使用Vuex,它可以工作。但是为什么会出现这个问题(为什么使用Vuex时它无法计算高度?)。另外,当我刷新页面时“setHeight()”方法没有运行,只有在页面之间路由时才会运行,我不知道为什么会这样?

这是bookList.json文件中一个数据的结构:

{
        "id": 3,
        "title": "شیب",
        "tozih": "کی باید رها کنی و کی باید بچسبی",
        "author": "ست گودین",
        "tags": [10, 13],
        "kamelTozih": "خلاصه کتاب شیب از ست گودین (ترجمه کتاب The Dip) راجع‌به پدیده‌ی شیب صحبت می‌کنه توی مسیر موفقیت برای هرکسی وجود داره. چه توی زندگی شخصی و چه توی زندگی کاری، معمولا اوایل خیلی ذوق و شوق داریم و همه‌چیز بر وفق مراده، اما به‌مرور زمان عبارت مشهور «که عشق آسان نمود اول ولی افتاد مشکل‌ها» خودش رو در عمل نشون میده و سروکله‌ی مشکلات و موانع پیدا می‌شه. ست گودین توی خلاصه کتاب شیب میگه که مواجه‌شدن با چنین چیزی اجتناب‌ناپذیره، اما مهم اینه که توی بازه‌ی شیب، به‌درستی موانع رو تشخیص بدی و ببینی که آیا این موانع عادیِ مسیر هستن یا چیزهای غیرقابل‌رفعی هستن که مستقیما به ماهیت کار یا زندگیت مربوط می‌شن.",
        "titleList": ["موضوع کتاب راجع‌به چیه؟ چرا رهاکردنِ به‌موقعِ پروژه‌ها یه اقدام هنرمندانه هست؟", "هر هدفی که داشته باشی، وقوع پدیده‌ی شیب یا دوره‌ی چالش‌برانگیز اجتناب‌ناپذیره", "بهترین‌بودن  توأم با مزیت‌های آشکار و پنهان مهمی هست ", "تخصص‌داشتن و آگاهی از نحوه‌ی خروج استراتژیک برای موفقیت ضروریه ", "چه توی زندگی کاری و چه زندگی شخصی، قطعا با پدیده‌ی شیب روبه‌رو میشی ", "موفقیت از دل پدیده‌ی شیب بیرون می‌زنه ", "شیب می‌تونه مزیت رقابتی ایجاد کنه ", "برای دَووم‌آوردن در دوران شیب باید صبور و سرسخت باشی و کم نیاری "]
    },

标签: javascriptvue.jsnuxt.jsvuex

解决方案


页面刷新后它不起作用的原因是服务器端既不存在window也不存在对象。document您需要先检查您是否在客户端才能使用windowand document

我在这里看到两个选项:

  1. 检查您是否在客户端,并将您的逻辑包装在nextTick()的挂载钩子中,以确保所有内容都有机会加载。删除关于文档 readyState 的 if 语句。不过,这可能会给您带来其他问题。
  2. 更好的选择:忘记计算高度并使用 CSS 使其工作。tozihClass将包含您的div的 cols 的行设置为display: flex; align-items: stretch. 这应该使它们的高度相等。您可能需要制作 cols height: 100%

推荐阅读