将数据 属性 的副本传递给 Vue JS 中的函数

Passing a copy of a data property to a function in Vue JS

我有一个简单的 vue 实例,我用它来生成 Stripe 令牌。

看起来像这样:

var vm = new Vue({
        el: '#checkout-form',
        data: {
            stripe_publishable_key: '{{ config('services.stripe.publishable') }}',
            card: {
                number: null,
                cvc: null,
                exp: null,
            },
        },
        ready: function() {    
            Stripe.setPublishableKey(this.stripe_publishable_key);
        },
        methods: {
            getStripeToken: function() {
                Stripe.card.createToken(this.card, this.stripeResponseHandler);
            },
            stripeResponseHandler: function(status, response) {
                // Process response
            },
        },       
    });

基本上我将 Vue 实例中的 card 对象(绑定到某些表单输入)传递给 Stripe 的 card.createToken 方法。这应该接受输入并调用处理程序,同时传递响应。

除了 card.createToken 正在修改卡片对象并导致我的 Vue 实例上的卡片对象发生变化外,这一切都很好 - 它插入了自己的属性并导致绑定 <inputs> 出现奇怪的行为.

有没有办法将 card vue 属性 作为未绑定到 vue 实例的副本传递给 Stripe,因此不会因此而改变?

更新

本质上这是因为 JavaScript 将对象作为 copy-of-a-reference 传递,这意味着原始对象可以被接收它的任何函数修改。显而易见的解决方案是通过循环或其他方式克隆对象,但我想知道 Vue 中是否有更好的方法。

虽然我知道的不多 Vie.js 但 this.data 只是一个 JavaScipt 对象然后你可以用这个克隆它:

function cloneObject(obj) {
  var clone = {};
  Object.keys(obj).forEach(function(key) {
    clone[key] = obj[key];
  });
  return clone;
}

或者在 ES3 领域:

function cloneObject(obj) {
  var key, clone = {};
  for (key of obj) {
    if (obj.hasOwnProperty(key) {
      clone[key] = obj[key];
    }
  }
  return clone;
}

但这是一个浅克隆,因此不会克隆作为 obj 属性的对象,但它们的引用是相同的(允许突变)。

jQuery(如果你有的话)也提供了一种方便的方法来做到这一点:

var clone = $.extend({}, this.data);

最后,正如@oleg-melashko 指出的那样,Vue.js 也有一个 Vue.util.extend(尽管 documentation 似乎没有提到这个)。

var clone = Vue.util.extend({}, this.data);

有很多方法可以复制这个对象,但只有一种来自 Vue 本身:

var cardCopy = Vue.util.extend({}, this.card);

它实际上等同于 jQuery 的 extend with deep 设置为 true。

Vue 1.0.12 中有属性的强制钩子函数

它可以像那样用于创建对象克隆(ES6)

import _ from 'lodash';
export default{
    props: {
        myObjProp: {
            type: Object,
            coerce(val) {
                return _.clone(val);
            }
        }
    }
};

您也可以像下面这样复制卡片对象

let cardCopy = JSON.parse(JSON.stringify(this.card));