子组件向父组件传递数据有一下两种方式:javascript
一、自定义事件java
子组件用”$emit()
“来触发事件,父组件用”$on()
“来监听子组件事件。父组件也能够直接在子组件的自定义标签上使用” v-on ” 来监听子组件触发的自定义事件。(由于” v-on “除了监听DOM事件外,还能够用于组件间的自定义事件。)web
示例代码:express
<div id="app"> <p>{{total}}</p> <my-component @increace="getTotal" @reduce="getTotal"></my-component> </div>
<script>
Vue.component('my-component',{
template:`\
<div>\
<button @click="increaceTotal">增长</button>\
<button @click="reduceTotal">减小</button>\
</div>`,
data: function(){
return{
counter:0
}
},
methods:{
increaceTotal:function(){
this.counter ++;
this.$emit('increace',this.counter);
},
reduceTotal:function(){
this.counter --;
//$emit()第一个参数是自定义事件名称,
//第二个参数是要传递的数据,能够不填或填写多个
this.$emit('reduce',this.counter);
}
}
});
new Vue({
el:'#app',
data:{
total:0
},
methods:{
getTotal:function(total){
this.total = total;
}
}
})
</script>
上面例子中,子组件有两个按钮,实现加1和减1的效果,在改变组件的 data:”counter” 后,经过 $emit()
再把它传递给父组件,父组件经过 v-on:increace
和 v-on:reduce
(示例中使用了语法糖)来监听。app
运行效果:
svg
二、使用 v-model 指令
示例代码:this
<div id="app"> <p>总数:{{total}}</p> <my-component v-model="total"></my-component> </div>
<script>
Vue.component('my-component',{
template:`<button @click="handleClick">++1</button>`,
data: function(){
return{
counter:0
}
},
methods:{
handleClick:function(){
this.counter++;
//组件$emit()事件名是特殊的input
this.$emit('input',this.counter);
}
}
});
new Vue({
el:'#app',
data:{
total:0
}
})
/* 组件$emit()事件名是特殊的input, * 在使用组件的父级直接用了 v-model 绑定的一个数据 total. * 能够间接的用自定义事件来实现。 * */
</script>
上面的示例仍然是点击按钮加1的效果,不过此次组件$emit()
事件名是特殊的input ,在使用组件的父级,并无在<my-component>
上使用 v-on:increace = "handle"
这样的监听器,而是直接使用了 v-model 绑定的一个 total
。
这也能够称做一种语法糖,由于上例能够间接的用自定义事件来实现,以下:spa
<div id="app"> <p>总数:{{total}}</p> <my-component @input="handle"></my-component> </div>
<script> Vue.component('my-component',{ //.....省略组件代码 }); new Vue({ el:'#app', data:{ total:0 }, methods:{ handle:function(counter){ this.total = counter; } } }) </script>
运行结果和上例相同。双向绑定
v-model
建立自定义表单输入控件,进行数据双向绑定。code
示例以下:
<div id="app"> <p>总数:{{total}}</p> <my-component v-model="total"></my-component> <button @click="handleReduce">-1</button> </div>
<script>
Vue.component('my-component',{
props:['value'],
template:`\
<input :value="value" @input="updateValue"></input>`,
methods:{
updateValue:function(event){
this.$emit('input',event.target.value);
}
}
});
new Vue({
el:'#app',
data:{
total:0
},
methods:{
handleReduce:function(){
this.total--;
}
}
})
/* 实现这样一个具备双向绑定的v-model组件要知足下面两个要求 * 一、接收一个value属性 * 二、在有新的value时出发input事件 * */
</script>
运行结果: