Nuxt.js(Vue.js)路由切换时Facebook分享按钮消失问题如何解决
问题成因
- Facebook SDK首次加载时仅会扫描一次当前页面中带有
.fb-*类名的DOM元素,将其渲染为对应的社交插件。Nuxt2默认走客户端路由跳转,不会触发整页刷新,路由切换后原有DOM被销毁,新挂载的分享按钮DOM无法被SDK自动识别渲染。 - 现有SDK加载逻辑检测到页面已存在Facebook SDK脚本时会直接返回,不会触发后续的DOM扫描流程,导致新加载的按钮DOM没有被转换为可视的分享按钮。
- 全局唯一的
fb-root元素被放在了组件内部,每次组件挂载都会重复插入该元素,会干扰SDK的正常渲染流程。
修复方案
步骤1:调整SDK加载插件逻辑
修改plugins/loadFacebookSdk.js代码,用Promise封装SDK加载流程,新增主动触发DOM扫描的全局方法:
Vue.prototype.$loadFacebookSDK = async (d, s, id) => { // 若FB对象已初始化,直接返回 if (window.FB) return Promise.resolve() return new Promise((resolve) => { const fjs = d.getElementsByTagName(s)[0] if (d.getElementById(id)) { // 监听SDK加载完成回调 window.fbAsyncInit = () => { FB.init({ version: 'v3.0', xfbml: false // 关闭自动首次扫描,由手动控制扫描时机 }) resolve(window.FB) } return } const js = d.createElement(s) js.id = id js.src = "https://connect.facebook.net/en_US/sdk.js" js.onload = () => { window.fbAsyncInit = () => { FB.init({ version: 'v3.0', xfbml: false }) resolve(window.FB) } } fjs.parentNode.insertBefore(js, fjs) }) } // 新增全局FB插件渲染方法,支持指定扫描的DOM节点 Vue.prototype.$renderFbPlugins = async (el = null) => { await this.$loadFacebookSDK(document, 'script', 'facebook-jssdk') window.FB && window.FB.XFBML.parse(el) }
步骤2:全局添加唯一fb-root元素
在全局布局文件layouts/default.vue的根节点下添加全局唯一的fb-root元素,后续所有FB组件无需再单独引入:
<template> <div class="layout-wrapper"> <div id="fb-root"></div> <Nuxt /> </div> </template>
步骤3:修改FbShareButton组件逻辑
删除组件内的fb-root元素,在DOM挂载完成后调用手动扫描方法,若使用了keep-alive缓存页面,还需在activated钩子中补充调用:
<template> <div ref="fbWrapper"> <div class="fb-share-button" data-href="https://developers.facebook.com/docs/plugins/" data-layout="button" data-size="small"> </div> </div> </template> <script> export default { async mounted () { if (process.client) { // 仅扫描当前组件内的FB元素,提升性能 await this.$renderFbPlugins(this.$refs.fbWrapper) } }, // 页面使用keep-alive缓存时需补充该钩子 async activated() { if (process.client) { await this.$renderFbPlugins(this.$refs.fbWrapper) } } } </script>
内容的提问来源于stack exchange,提问作者Mindas
相关产品推荐
相关产品推荐

