我已经传递了几个Vue组件以及一些对象文字作为道具,例如
<child :prop1="{ foo: 'bar' }"></child>
但是,当父组件重新渲染时,如下面的最小代码和框示例所示,prop1
发生更改(由观察者检测到)并导致Child
进行更新。如果prop是对象引用,则保持不变。
为什么会发生这种情况,这是否意味着使用对象文字(可能是数组文字)作为道具可能并不“安全”?
答案 0 :(得分:2)
每次模板运行时,它将在命中该部分时创建一个新对象。相同的适用于任何引用类型,因此数组,函数等。
它类似于用JavaScript代码创建的对象等。例如
function getObject() {
return {};
}
console.log(getObject() === getObject()); // false
每次调用getObject
时,它将返回一个新对象,并且对象相等性基于引用而不是对象是否包含相同的值。这实际上是Vue在检查道具变更时所做的事情。请记住,Vue模板已编译为render
函数,而这只是普通的JavaScript。在该render
函数中,任何对象文字都将仍然是对象文字。
在您的示例中,假设模板中没有其他内容,则父级的渲染函数将如下所示:
function render(h) {
return h('child', {
props: {
prop1: {foo: 'bar'}
}
})
}
因此,每次运行时,prop1
都会有一个新对象。
正如您已经提到的那样,将对象移至data
并按名称进行引用将确保每次使用同一对象,从而避免子级更新。
是否值得担心将取决于您的方案的具体情况,但是如果有足够的子代被更新,这可能会对性能产生影响。子渲染不需要更新实际的DOM,但是如果任何计算的属性,监视或模板依赖于该道具,则它们将运行。