簡體   English   中英

VueJS SSR + Quasar - 如何在 ssr 中調用“掛載”?

[英]VueJS SSR + Quasar - How to call “mounted” in ssr?

根據文檔:

https://quasar.dev/quasar-cli/developing-ssr/writing-universal-code#Component-Lifecycle-Hooks

由於沒有動態更新,在所有的 Vue 生命周期鈎子中,只有 beforeCreate 和 created 會在 SSR 期間被調用。 這意味着其他生命周期鈎子(例如 beforeMount 或mounted)中的任何代碼都只會在客戶端上執行。

我對如何進行此調用感到困惑。 我有一些無法在服務器上運行的東西。 我猜想單獨“安裝”會導致它着火,但這似乎沒有發生。

為了添加一點上下文,我正在使用基礎構建一個下拉菜單。 我讓它在標准 Vue(非 ssr)上工作。

該文件如下所示:

<template>

<ul class="vertical menu accordion-menu" data-accordion-menu data-multi-open="false">
    <li v-for="i in htmlData.sidenav" :key="i.title">
        <router-link v-bind:to=i.href>{{ i.title }}</router-link>
        <ul class="menu vertical nested" v-if="i.sub1">
            <li v-for="j in i.sub1" :key="j.name">
                <router-link v-bind:to=j.href>{{ j.name }}</router-link>
                <ul class="menu vertical nested" v-if="j.sub2">
                    <li v-for="k in j.sub2" :key="k.name">
                        <router-link v-bind:to=k.href>{{ k.name }}</router-link>
                      </li>
                  </ul>
              </li>
          </ul>
      </li>
  </ul>
</div>


</template>


<script>
import SideNav from '../store/modules/sidenav'
import $ from 'jquery'

export default {
    name: 'sidenav',

    computed: {
        htmlData () {
            this.acc()
            return this.$store.state.sn.nav
        }
    },

    // Server-side only
    serverPrefetch () {
        this.$store.registerModule('sn',  SideNav)
        return this.getData()
    },

    // Client-side only
    mounted () {
        console.log('mt')
        const doesExist = !!this.$store.state.sn.nav
        this.$store.registerModule('sn', SideNav, { preserveState: true })

        if (!doesExist) {
            this.getData()
        }
    },

    destroyed () {
        this.$store.unregisterModule('sn')
        this.menu.destroy()
    },

    methods: {
        async getData () {
            return this.$store.dispatch('sn/snav')
        },

        acc () {
            this.$nextTick(function () {
                this.menu = new this.$foundation.AccordionMenu($('.accordion-menu'))
            })
        },
    }
}

當 sidenav 渲染時,客戶端無法看到它,這會導致此錯誤:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'AccordionMenu' of undefined

這是錯誤的,因為菜單確實呈現,控制台中沒有mt的日志,盡管pref確實記錄了。 這會導致頁面呈現的許多其他問題(它並非沒有硬刷新)。

boot/sidenav下的文件如下所示:

// const SideNav = () => import('../layouts/SideNav.vue')
import SideNav from '../layouts/SideNav.vue'

export default async ({ Vue }) => {
    Vue.component('side-nav', SideNav)
}

quasar.conf 有這個:

        boot: [
            'axios',
            'sidenav',
            'notemenu',
            {
                path: 'foundation',
                server: false
            },
            {
                path: 'osmd',
                server: false
            }
        ],

客戶端看不到foundationosmd 兩者都不能在服務器上運行,因為它們都需要window才能運行。 這讓人倍感困惑,因為sidenav確實呈現並表現得像一個反應組件。

只有 beforeCreate 和 create 在 SSR 和客戶端調用。 使用此組件查看運行中的生命周期。

<template>
<div>Hello World</div>
</template>

<script>
export default {
name: "Test",
beforeCreate() {
 console.log('beforeCreate', process.env, this)
},
created() {
 console.log('created', process.env, this)
},
beforeMount() {
 console.log('created', process.env, this)
},
mounted() {
 console.log('mounted', process.env, this)
},
beforeUpdate() {
 console.log('beforeUpdate', process.env, this)
},
updated() {
 console.log('updated', process.env, this)
},
beforeDestroy() {
 console.log('beforeDestroy', process.env, this)
},
destroyed() {
 console.log('destroyed', process.env, this)
},
preFetch() {
 console.log('preFetch', process.env, this)
}
}
</script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM