Javascript 什么';在Vue.js 2中传递道具作为初始数据的正确方法是什么?
因此,我想将道具传递给Vue组件,但我希望这些道具将来会从该组件内部更改,例如,当我使用AJAX从内部更新该Vue组件时。因此,它们仅用于组件的初始化 我的Javascript 什么';在Vue.js 2中传递道具作为初始数据的正确方法是什么?,javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,因此,我想将道具传递给Vue组件,但我希望这些道具将来会从该组件内部更改,例如,当我使用AJAX从内部更新该Vue组件时。因此,它们仅用于组件的初始化 我的汽车列表Vue组件元素,其中我将带有初始属性的道具传递给单车: // cars-list.vue <script> export default { data: function() { return { cars: [
汽车列表
Vue组件元素,其中我将带有初始属性的道具传递给单车
:
// cars-list.vue
<script>
export default {
data: function() {
return {
cars: [
{
color: 'red',
maxSpeed: 200,
},
{
color: 'blue',
maxSpeed: 195,
},
]
}
},
}
</script>
<template>
<div>
<template v-for="car in cars">
<single-car :initial-properties="car"></single-car>
</template>
</div>
</template>
但我的问题是,我不知道这样做是否正确?沿路会不会给我带来一些麻烦?或者有更好的方法吗?我相信你做得对,因为这是文件中规定的 定义使用道具初始值作为其初始值的本地数据特性 多亏了这一点,我现在知道答案了 方法1 将初始道具直接传递给数据。如更新文档中的示例:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
但请记住,如果传递的道具是在父组件状态中使用的对象或数组,则对该道具的任何修改都将导致该父组件状态的更改
警告:不建议使用此方法。这将使您的组件不可预测。如果需要从子组件设置父数据,请使用Vuex之类的状态管理或使用“v-model”
方法2
如果您的初始道具是一个对象或数组,并且不希望子级状态的更改传播到父级状态,则只需使用例如Vue.util.extend
[1]来制作道具的副本,而不是将其直接指向子级数据,如下所示:
props: ['initialCounter'],
data: function () {
return {
counter: Vue.util.extend({}, this.initialCounter)
}
}
方法3
您还可以使用spread操作符克隆道具。Igor答案中的更多详细信息:
但请记住,旧浏览器不支持spread运算符,为了更好地兼容,您需要使用babel
等传输代码
脚注
[1] 请记住,这是一个内部Vue实用程序,它可能会随着新版本而更改。您可能希望使用其他方法复制该道具,请参见“”
我测试小提琴的地方:
在@dominik serafin的回答中: 如果要传递对象,可以使用扩展运算符(ES6语法)轻松克隆该对象: 但最重要的是记住使用opt。2,以防传递的是计算值,或大于该值的值是异步值。否则,本地值将不会更新 演示:
Vue.component('card',{
模板:'#app2',
道具:{
test1:null,
test2:null
},
数据(){//opt.1
返回{
test1AsData:{…this.test1}
}
},
计算:{//opt.2
test2ascomputered(){
返回{…this.test2}
}
}
})
新Vue({
el:“附录1”,
数据(){
返回{
test1:{1:'将不更新'},
test2:{2:'将在1秒后更新'}
}
},
挂载(){
设置超时(()=>{
this.test1={1:'updated!'}
this.test2={2:'updated!'}
}, 1000)
}
})
test1作为数据:{{test1AsData}
计算的test2:{{test2AsComputed}
作为另一种方法,我是通过子组件中的观察者来实现的
这种方法非常有用,特别是在传递异步值时,并且在子组件中希望将传递的值绑定到v-model
此外,为了使其具有反应性,我将本地值发送给另一个观察程序中的父级
例如:
data() {
return {
properties: {},
};
},
props: {
initial-properties: {
type: Object,
default: {},
},
},
watch: {
initial-properties: function(newVal) {
this.properties = {...newVal};
},
properties: function(newVal) {
this.$emit('propertiesUpdated', newVal);
},
},
这样我就有了更多的控制力,也减少了意想不到的行为。例如,当父级传递的道具是异步的时,它在创建或装载生命周期时可能不可用。因此,您可以使用@Igor Parra提到的computed属性,或者观察道具,然后发射它。第二次或第三次我在返回旧的vue项目时遇到这个问题 不知道为什么在vue中会如此复杂,但我们可以通过观看来完成:
export default {
props: ["username"],
data () {
return {
usernameForLabel: "",
}
},
watch: {
username: {
immediate: true,
handler (newVal, oldVal) {
this.usernameForLabel = newVal;
}
},
},
在我看来,这是关于Vue最令人困惑的事情:每个
数据
都是双向绑定的,但您不能将数据
传递给组件,您可以传递道具
,但您不能更改收到的道具
,也不能将道具
转换为数据
。然后呢?我学到的一件事是,你应该向下传递props
,然后向上触发事件。也就是说,如果组件想要更改它接收到的道具
,它应该调用一个事件并“重新渲染”。但是剩下的是一个与React完全相同的单向
绑定,我看不到数据
的用途。非常混乱。数据主要用于组件的私人用途。组件上下文中放置在组件上的所有内容都是被动的,可以绑定到。props的概念是将值传递到组件中,但防止组件通过更改传递的值在父级中悄悄引入状态更改。最好在您指出的事件中明确说明。这是一个从Vue 1.0到2.0的理念变化。今天我尝试在这里开始一个线程:数据
是状态,道具
是参数,事件
冒泡。你可以随心所欲地装扮一个UI框架,但这三样东西仍然必须存在,并且像往常一样工作。我从来没有遇到过一个UI在引擎盖下基本上不以相同的方式运行。因此,将更改传播到父组件是一种不错的做法吗?@igor我个人会尽量避免。这将使您的组件不可预测。我认为在父组件中获得更改的更好方法是使用“v-model”方法,在该方法中,您可以将更改从子组件发送到父组件。是的,但是深的物体呢?我应该深度复制吗?我是否应该重新设计我的组件以不使用deep object?如果使用以前的任何克隆方法将属性设置为内部数据,则ie属性为:{ok:1,notOk:{meh:2}}
data() {
return {
properties: {},
};
},
props: {
initial-properties: {
type: Object,
default: {},
},
},
watch: {
initial-properties: function(newVal) {
this.properties = {...newVal};
},
properties: function(newVal) {
this.$emit('propertiesUpdated', newVal);
},
},
export default {
props: ["username"],
data () {
return {
usernameForLabel: "",
}
},
watch: {
username: {
immediate: true,
handler (newVal, oldVal) {
this.usernameForLabel = newVal;
}
},
},