You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中外部JS路由切换后无法加载的解决方案咨询

Solution for Reloading External JS on Route Changes in Vue.js

Hey there! I totally get your frustration—when using vue-script2 to load external scripts, they don’t reload automatically when routes shift because the component (like your App.vue) doesn’t remount, and the script instance gets cached. Let’s walk through a few solid fixes that fit your requirement of mounting scripts directly to components:

1. Use a Route-Dependent Key for the Script Component

The simplest fix is to bind a unique key to your Script component from vue-script2, using the current route’s full path. This tells Vue to re-render the component (and thus reload the script) every time the route changes.

Here’s how to implement this in your App.vue:

<template>
  <div id="app">
    <!-- Bind key to $route.fullPath to trigger re-render on route change -->
    <Script
      :key="$route.fullPath"
      src="https://your-external-script-url.js"
    />
    <router-view />
  </div>
</template>

<script>
import Script from 'vue-script2'

export default {
  components: {
    Script
  },
  // Optional: Add custom logic when route changes
  watch: {
    '$route' (to, from) {
      // Example: Clean up any global state left by the previous script run
      // delete window.scriptGlobalVar
    }
  }
}
</script>

2. Build a Custom Dynamic Script Loader Component

If you need more control (like handling load errors or cleaning up global variables), create a custom component that manually creates and removes script tags whenever the route changes.

Here’s a reusable component you can drop into your project:

<template>
  <div></div>
</template>

<script>
export default {
  props: {
    src: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      scriptElement: null,
      routeWatcher: null
    }
  },
  mounted() {
    this.loadScript()
    // Watch for route changes to reload the script
    this.routeWatcher = this.$watch('$route', () => {
      this.unloadScript()
      this.loadScript()
    })
  },
  beforeUnmount() {
    this.unloadScript()
    this.routeWatcher() // Clean up the watcher to avoid memory leaks
  },
  methods: {
    loadScript() {
      this.scriptElement = document.createElement('script')
      this.scriptElement.src = this.src
      this.scriptElement.async = true
      
      // Optional: Add success/error handlers
      this.scriptElement.onload = () => {
        console.log(`Script ${this.src} loaded successfully!`)
      }
      this.scriptElement.onerror = (err) => {
        console.error(`Failed to load script: ${this.src}`, err)
      }

      document.body.appendChild(this.scriptElement)
    },
    unloadScript() {
      if (this.scriptElement) {
        document.body.removeChild(this.scriptElement)
        // Clear any global variables set by the script if needed
        // delete window.scriptGlobalVar
        this.scriptElement = null
      }
    }
  }
}
</script>

Then use it in your App.vue like this:

<template>
  <div id="app">
    <CustomScriptLoader src="https://your-external-script-url.js" />
    <router-view />
  </div>
</template>

<script>
import CustomScriptLoader from './components/CustomScriptLoader.vue'

export default {
  components: {
    CustomScriptLoader
  }
}
</script>

3. Make Sure the External Script is Re-Runnable

Some external scripts only execute once (they check if their global variables exist before running). If that’s your case:

  • Clear any global variables set by the script before reloading (add this step in the unloadScript method above)
  • If you have control over the script, wrap its logic in a function that you can call manually after each load

These approaches should ensure your external scripts reload every time the route changes, without needing to import the files directly.

内容的提问来源于stack exchange,提问作者soroush fathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:42:20