我有一个Nuxtjs网站托管在S3桶,它有多个路由/页面。我创建的这条特殊的新路径是抛出“未能在‘node’上执行'appendChild‘:此节点类型不支持此方法.”(请查看下面的SS )。
这种情况不会发生在本地机器上,也不会抛出任何错误。显然,当我部署到prod时,这个应用程序正在抛出SS下面的错误,但是不能调试它,因为代码在构建过程中被缩小和丑陋了。
奇怪的是,当我通过单击<NuxtLink>
访问这个特定的路径时,它工作得很好,但是如果我访问的路线很笨拙,或者我单击<NuxtLink>
并到达那里并重新加载页面,那么这个问题才会出现。
您可以通过以下步骤来再现这个过程:
如果直接访问https://stackinvest.in/prime-mutual-funds路由,也可以看到此错误。
问题是,也有其他路线,你可以看到在Navbar主页上。如果我遵循以上步骤的话,它们都能正常工作。(https://www.stackinvest.in/)
我有一个默认的布局文件(由Nuxt本身创建) layouts/default.vue
。代码如下:
<template>
<div ref="layout">
<app-navbar :isMobile="isMobile" @getstack="showModal = true"/>
<nuxt />
<app-download v-if="showModal" :is-mobile="isMobile" @close="showModal=false"></app-download>
</div>
</template>
<script>
import Navbar from '../components/Navbar';
import Download from '../components/Download';
export default {
name: 'Navbar',
components: {
appNavbar: Navbar,
appDownload: Download
},
data() {
return {
showModal: false,
size: Number
};
},
computed: {
isMobile() {
return this.size < 768;
}
},
mounted() {
this.size = this.$refs.layout.clientWidth;
}
};
</script>
代码components/Navbar.vue
。它不包含.removeEventListener()
的任何代码。我确实尝试过在<client-only></client-only>
标签周围添加<app-navbar>
包装标签。什么都没用!
<template>
<nav class="nav-bar">
<div class="d-flex justify-content-center px-0 px-sm-128">
<div v-if="!isMobile" class="nav-bar-wrapper py-sm-4">
<div class="brand-logo">
<NuxtLink to="/">
<img alt="Stack Finance logo" data-not-lazy height="35px"
src="https://webstatic.stackfinance.co/website/Group 73740.svg"
>
</NuxtLink>
</div>
<div class="d-flex justify-content-center">
<div class="nav-links w-100 mr-sm-4">
<div class="nav-links-item">
<NuxtLink class="fo-link" to="/prime-mutual-funds">
stack prime
<div class="designer-line"></div>
</NuxtLink>
</div>
<div class="nav-links-item">
<NuxtLink class="fo-link gt-nav-faq" to="/faq">
faq
<div class="designer-line"></div>
</NuxtLink>
</div>
<div class="nav-links-item">
<NuxtLink class="fo-link gt-nav-blog" to="/blogs">
blog
<div class="designer-line"></div>
</NuxtLink>
</div>
</div>
<button id="nav-cta" ref="navCta" class="app-btn--sm" @click="focusSection">download stack</button>
</div>
</div>
<div v-else class="nav-bar-wrapper--mob p-3">
<div class="brand-logo">
<NuxtLink to="/">
<img alt="Stack Finance logo" data-not-lazy height="22px"
src="https://webstatic.stackfinance.co/website/Group 73740.svg"
>
</NuxtLink>
</div>
<div class="nav-links--collapsed">
<div class="menu-icon">
<input id="toggle" type="checkbox" @change="toggleMenu">
<label for="toggle"></label>
</div>
</div>
<div v-if="showMenu" class="menu-container">
<div class="nav-links-item">
<NuxtLink class="fo-link" to="/prime-mutual-funds">stack prime</NuxtLink>
</div>
<div class="nav-links-item gt-nav-faq">
<NuxtLink class="fo-link" to="/faq">faq</NuxtLink>
</div>
<div class="nav-links-item">
<NuxtLink class="fo-link gt-nav-blog" to="/blogs">blog</NuxtLink>
</div>
</div>
</div>
</div>
</nav>
</template>
<script>
export default {
name: 'Navbar',
props: {
isMobile: Boolean
},
data() {
return {
showMenu: false
};
},
methods: {
focusSection() {
this.$emit('getstack');
},
toggleMenu() {
this.showMenu = !this.showMenu;
}
}
};
</script>
<style lang="scss">
...
</style>
package.json
{
"name": "stack-web",
"version": "4.0.0",
"description": "",
"author": "XYZ,
"private": true,
"scripts": {
"dev:staging": "gulp set --env=staging && nuxt",
"dev:prod": "gulp set --env=prod && nuxt",
"build:staging": "gulp set --env=staging && nuxt build",
"build:prod": "gulp set --env=prod && nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
},
"dependencies": {
"@nuxtjs/axios": "^5.9.5",
"@nuxtjs/dayjs": "^1.4.0",
"@nuxtjs/dotenv": "^1.4.1",
"@nuxtjs/gtm": "^2.4.0",
"@nuxtjs/robots": "^2.5.0",
"@nuxtjs/sitemap": "^2.4.0",
"@tryghost/content-api": "^1.11.0",
"bootstrap-vue": "^2.2.2",
"glob-all": "^3.1.0",
"nuxt": "^2.0.0",
"nuxt-helmet": "^1.2.3",
"nuxt-lazy-load": "^1.2.9",
"purgecss-webpack-plugin": "^2.0.5",
"tinyurl": "^1.1.7",
"vue": "^2.7.14",
"vue-gtag": "^1.16.1",
"vue-loader": "^15.10.0",
"vue-slick-carousel": "^1.0.6",
"vue-social-sharing": "^3.0.9",
"vuelidate": "^0.7.7"
},
"devDependencies": {
"@nuxt/types": "^2.15.7",
"@nuxtjs/eslint-config": "^1.0.1",
"@nuxtjs/eslint-module": "^1.0.0",
"@nuxtjs/stylelint-module": "^3.1.0",
"babel-eslint": "^10.0.1",
"eslint": "^6.1.0",
"eslint-plugin-nuxt": ">=0.4.2",
"gulp": "^4.0.2",
"gulp-clean": "^0.4.0",
"gulp-rename": "^2.0.0",
"nuxt-compress": "^5.0.0",
"sass": "^1.56.1",
"sass-loader": "^10.1.1",
"stylelint": "^10.1.0",
"yargs": "^15.1.0"
}
}
nuxt.config.js
/* eslint-disable dot-notation */
// import path from 'path';
//
// import PurgecssPlugin from 'purgecss-webpack-plugin';
// import glob from 'glob-all';
// import shrinkRay from 'shrink-ray-current';
require('dotenv').config();
const keywords = `keywords`;
export default {
mode: 'universal',
server: {
port: process.env.PORT || 5100,
host: '0.0.0.0' // default: localhost
},
// render: {
// compressor: shrinkRay()
// },
router: {
scrollBehavior() {
let s;
if (process.client) {
s = { x: 0, y: 0 };
}
return s;
}
},
/*
** Headers of the page
*/
head: {
...
},
/*
** Customize the progress-bar color
*/
loading: {
color: '#fff'
},
/*
** Global CSS
*/
css: [
'@/assets/scss/app.scss'
],
/*
** Plugins to load before mounting the App
*/
plugins: [
{ src: '~/plugins/Vuelidate' },
{ src: '~/plugins/hotjar', mode: 'client' },
{ src: '~/plugins/gtag', mode: 'client' },
{ src: '~/utils', mode: 'client' },
{ src: '~/plugins/directives.js' }
],
/*
** Nuxt.js dev-modules
*/
buildModules: [
'nuxt-compress'
// // Doc: https://github.com/nuxt-community/eslint-module
// '@nuxtjs/eslint-module',
// // Doc: https://github.com/nuxt-community/stylelint-module
// '@nuxtjs/stylelint-module'
],
/*
** Nuxt.js modules
*/
modules: [
'bootstrap-vue/nuxt',
'@nuxtjs/axios',
'@nuxtjs/dotenv',
'@nuxtjs/gtm',
'nuxt-lazy-load',
'nuxt-helmet',
'@nuxtjs/robots',
'@nuxtjs/sitemap',
'vue-social-sharing/nuxt',
'@nuxtjs/dayjs'
],
robots: {
...
},
sitemap: {
...
},
gtm: {
id: '<KEY>',
pageTracking: true,
pageViewEventName: 'nuxtRoute'
},
dayjs: {
locales: ['en'],
defaultLocale: 'en',
plugins: [
'utc' // import 'dayjs/plugin/utc'
]
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
bootstrapVue: {
bootstrapCSS: false,
bootstrapVueCSS: false
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extractCSS: true,
extend(config, { isDev, isClient }) {
if (isDev && isClient) {
config.devtool = 'source-map';
config.plugins.push(
// new PurgecssPlugin({
// paths: glob.sync([
// path.join(__dirname, './pages/**/*.vue'),
// path.join(__dirname, './layouts/**/*.vue'),
// path.join(__dirname, './components/**/*.vue')
// ]),
// whitelist: ['html', 'body']
// })
);
}
}
}
};
prime-mutual-funds.vue
代码
<template>
<main ref="page" class="prime-main">
<section class="hero">
...
</section>
<section class="risk-analysis">
<div class="row">
<div v-if="!isMobile" class="col-sm">
...
</div>
<div class="col-sm d-flex align-items-center mb-4 mb-sm-0">
<div>
<a v-if="isMobile" class="text-color text-decoration-done fw-600" :href="getOS() === 'android' ? 'URL1': 'url2'">
</a>
<a v-else class="text-color text-decoration-done fw-600" @click="showModal = true" href="javascript:void(0)">
...
</a>
</div>
</div>
<div v-if="isMobile" class="col-sm">
...
</div>
</div>
</section>
<section class="prime-detail">
<div class="prime-detail-header">
<h2 class="section-heading">Lorem Lorem</h2>
<div class="d-flex mt-3 mt-sm-4">
<a href="#options" class="prime-detail-tab" @click="activeTabIndex = 0" :class="{'active': activeTabIndex === 0}">investment options</a>
<a href="#automate" class="prime-detail-tab" @click="activeTabIndex = 1" :class="{'active': activeTabIndex === 1}">automated investing</a>
<a href="#track" class="prime-detail-tab" @click="activeTabIndex = 2" :class="{'active': activeTabIndex === 2}">actionable insights from experts</a>
</div>
</div>
<section id="options" class="p-4" v-if="isMobile">
...
</section>
<section v-else class="scroller pb-sm-128">
<div class="scroller-left">
<div id="options" class="scrollable-element">
<div id="1" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
<div class="scrollable-element">
<div id="2" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
<div id="automate" class="scrollable-element">
<div id="3" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
<div class="scrollable-element">
<div id="4" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
<div class="scrollable-element">
<div id="5" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
<div id="track" class="scrollable-element">
<div id="6" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
<div class="scrollable-element">
<div id="7" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
...
</div>
</div>
</div>
<div class="scroller-right">
<div class="sticky-content">
<div class="sticky-content-box" v-if="activateText">
<span class="sticky-content-tag" :style="{backgroundColor: contentIndex[activeContentIndex].bgc}">{{ contentIndex[activeContentIndex].tag }}</span>
<h3 class="sticky-content-title mt-4">
{{ contentIndex[activeContentIndex].title }}
</h3>
</div>
<img v-else height="520px" ref="info" alt="info-img" src="https://webstatic.stackfinance.co/website/goals.webp"/>
</div>
</div>
</section>
</section>
<section class="rewards">
<h3 v-if="isMobile" class="rewards-heading">good financial habits <br> deserve <span class="text-white">great</span> rewards</h3>
<h3 v-else class="rewards-heading">good financial habits deserve <br> <span class="text-white">great</span> rewards</h3>
<h5 class="rewards-subheading">choose a free US stock with every investment.</h5>
<a :href="getOS() === 'android' ? '<url1>': '<url1>'"
v-if="isMobile" class="app-btn--sm d-block bgi-none bg-white text-color mx-auto my-4" style="width: 190px;">
download stack
</a>
<button v-else class="app-btn--white mt-sm-4" @click="showModal = true">download stack</button>
</section>
<app-grow-wealth :is-mobile="isMobile" @download="showModal = true"></app-grow-wealth>
<app-footer :is-mobile="isMobile"></app-footer>
<div v-if="isMobile" class="store-container py-2 px-4 bg-white position-fixed">
<a href="https://stack.app.link/3yAcChs5emb" rel="noopener">
<img height="40px" src="https://webstatic.stackfinance.co/website/playstore.png" alt="playstore">
</a>
<a href="https://stack.app.link/10JkMU6Xemb" rel="noopener">
<img class="float-right" height="40px" src="https://webstatic.stackfinance.co/website/appstore.png" alt="appstore">
</a>
</div>
<div v-if="showFaq" class="pop-box">
<app-faq-section :squeeze="true"></app-faq-section>
</div>
<button id="popover-button-sync" class="floating-help" @click="showFaq = !showFaq">
<img height="40px" src="https://webstatic.stackfinance.co/website/Chat 4_2x.png" alt="messenger">
</button>
<app-download v-if="showModal" :is-mobile="isMobile" @close="showModal=false"></app-download>
</main>
</template>
<script>
import Footer from '../components/Footer';
import FaqSection from '../components/Faq-Section';
import Download from '../components/Download';
import { fetchOS } from '../utils';
import GrowWealth from '../components/GrowWealth';
export default {
name: 'PrimeMutualFunds',
components: {
appFooter: Footer,
appFaqSection: FaqSection,
appDownload: Download,
appGrowWealth: GrowWealth
},
data() {
return {
size: Number,
showModal: false,
showFaq: false,
activateText: false,
activeTabIndex: 0,
imgIndex: {
1: 'URL',
2: 'URL',
6: 'URL',
7: 'URL'
},
contentIndex: {
3: {
tag: '...',
bgc: '#f9f2ea',
title: '...'
},
4: {
tag: '...',
bgc: '#e1f4f0',
title: '...'
},
5: {
tag: 'investment reminder',
bgc: '#ccebff',
title: '...'
}
},
activeContentIndex: 3
};
},
computed: {
isMobile() {
return this.size < 768;
}
},
mounted() {
this.size = this.$refs.page.clientWidth;
},
methods: {
getOS: () => fetchOS(),
updateRightContainer({ isIntersecting, target }) {
if (isIntersecting) {
const x = target.getAttribute('id');
this.activeTabIndex = 0;
const ids = [3, 4, 5];
if (ids.includes(+x)) {
this.activateText = true;
this.activeContentIndex = x;
this.activeTabIndex = 1;
return;
}
if ([6, 7].includes(+x)) {
this.activeTabIndex = 2;
}
this.activateText = false;
if (this.$refs.info) {
this.$refs.info.setAttribute('src', this.imgIndex[x]);
}
}
}
}
};
</script>
direction.js
码
Vue.directive('intersection', {
bind(el, binding) {
const threshold = binding.value.threshold || 0;
const defaultCb = () => {
console.log('No callback passed');
};
const cb = binding.value.cb || defaultCb;
if (isNaN(threshold)) {
return;
}
const observer = new IntersectionObserver((entries) => {
entries.forEach((elem) => {
cb(elem);
});
}, { threshold });
observer.observe(el);
}
});
Vue.directive('scroll', {
inserted(el, binding) {
const f = function(evt) {
if (binding.value(evt, el)) {
window.removeEventListener('scroll', f);
}
};
window.addEventListener('scroll', f);
}
});
如果我注释掉了导航栏并进行了部署,那么这个URL -https://stackinvest.in/prime-mutual-funds的重新加载工作正常,没有任何问题。
https://stackoverflow.com/questions/74574249
复制相似问题