【问题标题】:Insert and modify a script tag inside template Vue在模板 Vue 中插入和修改脚本标签
【发布时间】:2020-12-03 20:02:57
【问题描述】:

我正在创建与支付服务的集成。 支付服务为我提供了一个带有脚本标签的表单。

我的问题是Insert a script tag inside template Vue的延续

支付服务结账表格:

<form action="http://localhost:8081/api/v1/payment/" method="POST">
      <script
        src="https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js"
        data-public-key="KEY"
        data-transaction-amount="14.90">
      </script>
</form>

我可以在 vuejs 的“mounted()”上做下一个:

<form ref="myform">
  ...
</form>

mounted() {
  let foo = document.createElement('script');    
  foo.setAttribute("src","https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js");
  foo.setAttribute("data-transaction-amount", this.newAmount)
  this.$refs.myform.appendChild(foo);
}

但是,我的问题是在安装视图之后。用户可以更改“data-transaction-amount”。

为了解决它,我尝试了:

data:()=>({
  newAmount:0
})

watch: {
    newAmount() {
      this.modifyScript();
    },
  },
  methods: {
    modifyScript() {
      let scripts = document.getElementsByTagName("script");
      for (let i = 0; i < scripts.length; i++) {
        let script = scripts[i];
        if (script.getAttribute("src") == 'https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js') {
          // we've got a match
          script.setAttribute("data-transaction-amount", this.newAmount);
        }
      }
    },

“data-transaction-amount”正在更改为新值,但支付服务的窗口结帐显示“mounted()”中使用的原始值。

【问题讨论】:

  • 你试过scripts[i].setAttribute("data-transaction-amount", this.newAmount);吗?
  • 这听起来像是您需要向该脚本的提供者提出的问题。询问他们如何动态更新交易金额
  • 是的,我做到了。正如我所说,这不是问题。在 chrome 控制台调试器中,我可以看到它正在工作。问题是窗口支付服务显示的是“挂载”周期中使用的旧值,而不是新值。
  • @Phil 我认为这不是一个选择。提供者是一个大玩家“mercadopago”。我猜他们并不担心。

标签: javascript vue.js vuejs2


【解决方案1】:

一个解决方案应该是让浏览器强制重新加载更改数量后的javascript文件。

以下是一个步骤:

  1. 在 URL 末尾添加一个版本#
  2. 更改金额时,删除之前已添加的script 元素(src=...?old_amount)
  3. 添加新的script 元素 (src=...?new_amount)

下面是一个小提琴(打开浏览器控制台,你会看到脚本web-tokenize-checkout.js在更改数量时重新下载)。

Vue.component('v-loadjs',{
    template:`
        <div>
            <p><button class="btn btn-info" v-on:click="changeAmount()">Change Amount: {{amount}}</button></p>
            <p ref="test"></p>
        </div>
    `,
    data () {
      return {
        amount: 0,
        url: 'https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js'
      }
    },
    mounted: function () {
      this.loadJS(this.amount, this.amount)
    },
    watch: {
      amount: function(newAmount, oldAmount) {
        this.loadJS(newAmount, oldAmount)
      }
    },
    methods: {
      changeAmount: function () {
        this.amount += 1
      },
      loadJS: function (newAmount, oldAmount) {
        [...document.querySelectorAll('button.mercadopago-button')].forEach(item => item.remove())
        let scripts = document.getElementsByTagName("script");
        for (let i = 0; i < scripts.length; i++) {
          if (scripts[i].getAttribute("src") == this.url + '?version=' + oldAmount) {
            scripts[i].remove()
          }
        }
        let foo = document.createElement('script');    
        foo.setAttribute("src", this.url + '?version=' + newAmount);
        foo.setAttribute("data-transaction-amount", newAmount)
        this.$refs.test.appendChild(foo);
      }
    }
})

new Vue ({
  el:'#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
    <div class="container">
        <div class="col-lg-offset-4 col-lg-4">
            <v-loadjs></v-loadjs>
        </div>
    </div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    相关资源
    最近更新 更多