将数据 属性 的副本传递给 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));
我有一个简单的 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));