VUE-Data对象始终作为引用传递,还是有时被复制?
我有一个与VUE相关的概念。
我对如何将数据传递给子VUE文件感到有点困惑。 (VUE实例?诚实地说,不熟悉这个术语)
在某些情况下,子VUE文件中的数据更改不会更改父项的数据 当数据由"props"传递时。
另一方面,子VUE文件中的数据更改,实际上更改了父级的数据。
我刚刚遇到了案例2。 这是数据通过Eventbus传递的时间。
我可以按如下方式理解此性质吗?
"数据仅在以下情况下作为引用传递 数据通过Eventbus传递"While,
"当数据通过道具传递时,数据将作为单独的副本传递到子级,子级中的更改不会更改父级中的原始数据"
我可以在路上看到Vue大自然吗? 如果有人能给我举一个例子,说明子项中的更改不会影响父项中的数据,我将不胜感激。
每次我问与Vue相关的问题时,总是感到非常内疚,因为代码非常长,不同于单纯的Javascript问题。 提前感谢您。
我刚才遇到的示例如下所示。
=main.js=
import Vue from 'vue'
import App from './App.vue'
export const serverBus = new Vue()
new Vue({
el: '#app',
render: h => h(App)
})
=Servers.vue=
<template>
<div class="col-xs-12 col-sm-6">
<ul class="list-group">
<Server v-for='server in serverinfo' :serverinfo='server' :key='server.id'></Server>
</ul>
</div>
</template>
<script>
import Server from './server.vue'
export default {
components: {
Server
},
data() {
return {
serverinfo: [
{id:1, servno:'#1', servstat:'normal'},
{id:2, servno:'#2', servstat:'critical'},
{id:3, servno:'#3', servstat:'unknown'},
{id:4, servno:'#4', servstat:'error'},
{id:5, servno:'#5', servstat:'excellent'}]
}
}
}
</script>
<style>
</style>
=server.vue=
<template>
<li class='list-group-item' @click='serverselected'>
Server {{serverinfo.servno}}
</li>
</template>
<script>
import {serverBus} from '../../main.js'
export default {
props:['serverinfo'],
methods:{
serverselected(){
serverBus.$emit('serverselected', this.serverinfo)
}
}
}
</script>
<style>
</style>
=ServerDetails.vue=
<template>
<div class="col-xs-12 col-sm-6">
<p v-if='!server'>Please Select a server</p>
<p v-else>Server {{server.servno}} is selected. Status:{{server.servstat}}</p>
<button class="btn btn-primary" @click='backtonormal'>Back to Normal</button>
</div>
</template>
<script>
import {serverBus} from '../../main.js'
export default{
methods:{
backtonormal(){
this.server.servstat='normal'
}
},
data(){
return{
server:null
}
},
created(){
serverBus.$on('serverselected',(server)=>{
this.server=server
})
}
}
</script>
<style>
</style>
解决方案
当您通过道具传递对象时,Vue不获取副本。如果通过道具传递对象,则两个组件将看到相同的对象。因为它是同一对象,所以子对象所做的任何属性更改也会影响另一个父对象。
查看有关单向数据流的文档:
https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow
开头的段落有点误导,可能会让您认为副本被拿走了。它具体谈到了赋予道具新的价值,但措辞含糊不清。然而,事实并非如此,关键一句在末尾:
请注意,JavaScript中的对象和数组是通过引用传递的,因此如果属性是数组或对象,则子组件内的对象或数组本身发生变异将影响父状态。
我不知道不复印的官方原因是什么,但一些可能的原因是:
- 复制将导致性能下降。
- 在代码依赖于对象相等性的情况下,这可能会导致错误。
- 在技术上并不是所有情况下都可以复制。可以复制简单的JSON友好数据,但通常JavaScript有几个不能可靠复制的结构,例如带有闭包的函数。
关于您关于排放的问题.
发出更改事件是单向数据流和数据所有权的一部分。其想法是只有数据的所有者才能修改它。其目的是使推理和调试问题变得更容易。在实践中,没有什么可以阻止孩子按照您所描述的那样直接修改对象。您需要自行决定哪些内容最有利于代码的可维护性。
一个问题是子级耦合到父级。仅当该对象是该数据的最终真值来源时,修改子对象中的对象才有效。例如,如果对象是使用计算属性在父级中创建的,则修改它将不起作用。通过使用$emit
,我们将责任传递给数据的所有者,以决定进行所需更改的正确方式。
相关文章