CSS
.box {
margin: 10px;
}
.floatL {
float: left;
}
.clear {
display: block;
overflow: hidden;
}
HTML
<template id="child">
<div class="box">
<div class="box">
<span>Msg中间值:</span>
<input :value="childMsg">
<span>Msg新值:</span>
<input v-model="newMsg">
</div>
<div class="box clear">
<div class="floatL">
<span>List中间值:</span>
<ul>
<li v-for="child in childList">
<div>id:{{child.id}}</div>
<div v-for="num in child.array" style="margin-left:15px">num={{num}}</div>
</li>
</ul>
</div>
<div class="floatL">
<span>List新值:</span>
<ul>
<li v-for="child in newList">
<div>id:{{child.id}}</div>
<div v-for="num in child.array" style="margin-left:15px">num={{num}}</div>
</li>
</ul>
</div>
</div>
<div class="box">
<span>obj中间值:</span>
<div>id:{{childObj.id}}</div>
<span>obj新值:</span>
<div>id:{{newObj.id}}</div>
</div>
<div class="box">
<div class="floatL">
<span>Array中间值:</span>
<ul>
<li v-for="child in childArray">{{child}}
</li>
</ul>
</div>
<div class="floatL">
<span>Array新值:</span>
<ul>
<li v-for="child in newArray">{{child}}
</li>
</ul>
</div>
</div>
</div>
</template>
<div id="parent" class="clear">
<div class="floatL box">
<div class="box">
<span>父组件Msg:</span><input v-model="parentMsg" />
</div>
<div class="box">
<span>父组件List:</span>
<ul>
<li v-for="parent in parentList">
<div>id:{{parent.id}}</div>
<div v-for="num in parent.array" style="margin-left:15px">num={{num}}</div>
</li>
</ul>
</div>
<div class="box">
<span>父组件obj:</span>
<div>id:{{parentObj.id}}</div>
</div>
<div class="box">
<span>父组件Array:</span>
<ul>
<li v-for="parent in parentArray">{{parent}}
</li>
</ul>
</div>
</div>
<child class="floatL" :child-msg.sync="parentMsg" :child-list.syne="parentList" :child-obj.syne="parentObj" :child-array.syne="parentArray"></child>
</div>
JS
父组件
var vm = new Vue({
el: '#parent',
data: {
parentMsg: "aaaa",
parentList: [{
id: 1,
array: ["1", "2"]
}, {
id: 2,
array: ["1", "2"]
}],
parentObj: {
id: 1
},
parentArray: [1, 2, 3]
}
});
子组件
Vue.component('child', {
template: "#child",
props: ['childMsg', 'childList', 'childObj', 'childArray'],
computed: {
newMsg: {
get: function() {
return this.childMsg; // 将props中的value赋值给childMsg
},
set: function(val) {
this.$emit('update:childMsg', val); // 通过$emit触发父组件
}
},
newList: {
get: function() {
return this.childList;
},
set: function(val) {
this.$emit('update:childList', val);
}
},
newObj: {
get: function() {
return this.childObj;
},
set: function(val) {
this.$emit('update:childObj', val);
}
},
newArray: {
get: function() {
return this.childArray;
},
set: function(val) {
this.$emit('update:childArray', val);
}
}
},
methods: {
changeListItemId: function(index, val) {
this.newList[index].id = val;
},
changeListItemArray: function(index, array) {
this.newList[index].array = array;
},
changeListItemArrayItem: function(index, arrayindex, val) {
Vue.set(this.newList[index].array, arrayindex, val);
},
changeObjItemId: function(val) {
this.newObj.id = val;
},
changeObjItem: function(val) {
var a = Object.assign({}, this.newObj, val);
this.newObj = a;
},
changeArrayItem: function(val) {
this.newObj = a;
},
}
});
测试结果
中间值即为子组件通过prop获取的父组件的值
测试结果表示,在input内修改中间值不会影响到子组件属性的变化,修改子组件属性会调用computed的set方法,将新值通过调用父组件中vue自带的update:属性名的方法更新父组件中的值;修改父组件中的值则直接通过prop传递给子组件,实现双向绑定。