简体   繁体   中英

vue3 - can't render facebook comments

I am trying to add a Facebook comments plugin ( check it here ) to my vue app, the problem is that div is created in DOM but it sometimes shows, sometimes not(width: 0, height 0)

在此处输入图像描述

Note: I am calling XFBML.parse function, my host is added to fb app

This is my current code:

<template>
    <div
        ref="commentContainer"
        class="fb-comments"
        :data-href="onUrl()"
        :data-width="cwidth"
        :data-numposts="numposts"
    ></div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, watch } from "vue";
import router from "../../router";
export default defineComponent({
    props: {
        cwidth: {
            type: String,
            default: "100%",
        },
        numposts: {
            type: String,
            default: "2",
        },
    },
    setup({ cwidth, numposts }) {
        const commentContainer = ref(null);
        const init = () => {
            if (
                window.FB &&
                !commentContainer.value.hasAttribute("fb-xfbml-state")
            ) {
                setTimeout(() => {
                    window.FB.XFBML.parse(commentContainer.value.parentElement);
                }, 2000);
            }
        };
        onMounted(() => {
            setTimeout(() => {
                init();
            }, 1500);
        });
        const onUrl = () => {
            return document.location.origin + document.location.pathname;
        };

        watch(
            () => router.currentRoute.value,
            () => {
                init();
            }
        );

        return { cwidth, numposts, commentContainer, onUrl };
    },
});
</script>

Instead of doing setTimeout try using nextTick and not passing any params to the parse function.

Eg in the mounted function

this.$nextTick(() => {
    window.FB.XFBML.parse()
  })

Are you waiting 1.5s before running init() for a reason?

The above works using Vue2, for Vue3 example see below:

import { createApp, nextTick } from 'vue'

const app = createApp({
  setup() {
    const init = async () => {
      await nextTick()
      window.FB.XFBML.parse()
    }
  }
})

https://v3.vuejs.org/api/global-api.html#nexttick

Also, make sure you have added the SDK script and provided fb-root div to your index.html. It would not work on mine unless I added these just before the closing </body> tag.

I also had to add the the nextTick code to the route watcher to force the window to parse FB again when a new page is navigated to. I'm unsure of the Vue 3 version but I'm sure you can figure it out from this example:

watch: {
    $route (to, from) {
      if (to.fullPath !== from.fullPath) {
        this.$nextTick(() => {
          window.FB.XFBML.parse()
        })
      }
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM