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

如何在Div可见时注入JS?Vue条件渲染下的脚本按需加载方案

解决Vue条件渲染中按需加载外部JS脚本的问题

我明白你的困扰——Vue的v-if条件渲染并不会阻止浏览器初始加载它包裹的<script>标签,浏览器在解析HTML的时候会扫描所有脚本标签并优先加载,不管它们是不是在条件渲染的块里。要实现真正的按需加载,我们需要通过动态创建脚本的方式来控制时机,这里有几个靠谱的方案:

方案1:通过事件/生命周期钩子动态创建Script标签

这是最通用的方法,适合大多数第三方脚本(比如Stripe、PayPal、Google Maps)。核心思路是:当触发特定条件(比如用户点击按钮、step变化到目标值)时,手动创建<script>标签并插入到DOM中,同时避免重复加载。

实现步骤:

  1. 在Vue组件中定义加载脚本的方法:
export default {
  data() {
    return {
      step: '0',
      stripe: null
    };
  },
  methods: {
    async loadStripeScript() {
      // 先检查脚本是否已加载,避免重复插入
      if (document.getElementById('stripe-script') || window.Stripe) {
        // 如果已加载,直接初始化(如果需要)
        this.stripe = window.Stripe('你的公钥');
        return;
      }

      // 创建script标签
      const script = document.createElement('script');
      script.id = 'stripe-script';
      script.src = 'https://js.stripe.com/v3/';
      script.async = true;

      // 监听脚本加载完成事件,执行后续逻辑
      script.onload = () => {
        this.stripe = window.Stripe('你的公钥');
        // 这里可以初始化支付元素、绑定事件等
        console.log('Stripe脚本加载完成');
      };

      // 监听加载失败情况
      script.onerror = () => {
        console.error('Stripe脚本加载失败');
      };

      // 将脚本添加到body中
      document.body.appendChild(script);
    }
  },
  // 可选:监听step变化,自动加载脚本
  watch: {
    step(newStep) {
      if (newStep !== '0') {
        this.loadStripeScript();
      }
    }
  }
};
  1. 在模板中触发加载逻辑:
<!-- 方式1:通过按钮点击触发 -->
<button @click="loadStripeScript">打开支付界面</button>

<!-- 条件渲染的容器 -->
<div class="container" v-if="step != '0'" v-cloak>
  <!-- 支付相关内容,依赖Stripe脚本 -->
</div>

方案2:使用ES模块动态Import(推荐现代项目)

如果第三方脚本支持ES模块(比如Stripe提供了ES模块版本),可以直接用ES的动态import()语法,这更符合模块化开发的习惯,不需要手动操作DOM。

methods: {
  async loadStripeScript() {
    if (window.Stripe) return;
    // 动态导入Stripe的ES模块
    const { default: Stripe } = await import('https://js.stripe.com/v3/dist/stripe.esm.js');
    this.stripe = Stripe('你的公钥');
    // 后续初始化逻辑
  }
}

方案3:封装为异步组件(适合复杂场景)

如果支付/地图相关的内容是一个独立的组件,可以把它封装成异步组件,并在组件的mounted钩子中加载脚本。这样只有当组件被v-if渲染时,才会触发脚本加载。

// 定义异步组件
const PaymentComponent = defineAsyncComponent(() => 
  import('./components/PaymentComponent.vue')
);

// 在父组件模板中使用
<PaymentComponent v-if="step != '0'" />

然后在PaymentComponent.vue的mounted钩子中执行脚本加载逻辑:

export default {
  mounted() {
    this.loadStripeScript();
  },
  methods: {
    // 这里放方案1或方案2的加载方法
    loadStripeScript() { /* ... */ }
  }
};

关键注意事项

  • 避免重复加载:一定要检查脚本是否已存在(通过ID或全局变量),防止用户多次触发导致脚本重复插入。
  • 异步处理:脚本加载是异步的,必须在onload或await之后再执行依赖该脚本的代码,否则会出现xxx is not defined的错误。
  • v-cloak优化:确保你已经添加了[v-cloak] { display: none; }的CSS样式,避免条件渲染块在Vue初始化前闪烁显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:29:50