v-model自定义组件
<body>
<div id="root">
<base-checkbox v-model="isDone">
</div>
</body>
import Vue from "vue";
Vue.component("base-checkbox",{
model:{
prop:"checked",
event:"change"
},
props:{
checked:Boolean
},
template:'<input type="checkbox"\
v-bind:checked="checked"\
v-on:change="$emit(\'change\',$event.target.checked)"\
>',
mounted:function(){
console.log(this.checked);
},
updated:function(){
console.log(this.checked);
}
})
const vm = new Vue({
el:"#root",
data:{
isDone:true
}
})
将原生事件绑定到组件上
v-on:原生事件名称.native
,将原生事件绑定到组件上。
<body>
<div id="root">
<base-input label="用户名" value="Nicholas" v-on:focus.native="onFocus"></base-input>
</div>
</body>
import Vue from "vue";
Vue.component("base-input",{
props:{
label:String,
value:String
},
template:'<label>\
{{label}}\
<input type="text"\
v-bind="$attrs"\
v-bind:value="value"\
v-on:change="$emit(\'change\',$event.target.checked)">\
</label>',
methods:{
onFocus:function(){
console.log("now is focusing");
}
}
})
const vm = new Vue({
el:"#root",
})
但是,当输入框获得焦点时,控制台并没有打印"now is focusing"这行文本。
这是因为组件base-input
的根元素是<label></label>
,label
元素上不会触发focus
事件。
针对以上问题,解决方案如下:
<body>
<div id="root">
<base-input label="用户名" value="Nicholas"></base-input>
</div>
</body>
import Vue from "vue";
Vue.component("base-input",{
props:{
label:String,
value:String
},
computed:{
inputListeners:function(){
const self = this;
return Object.assign({},
this.$listeners,
{
input:function(event){
self.$emit("input",event.target.value);
},
focus:function(){
console.log("focusing input");
}
}
)
}
},
template:'<label>\
{{label}}\
<input type="text"\
v-bind="$attrs"\
v-bind:value="value"\
v-on="inputListeners">\
</label>'
})
const vm = new Vue({
el:"#root",
})
sync实现双向数据绑定
<body>
<div id="root">
<text-component
v-bind:title="title"
v-on:update:title="title=$event"
></text-component>
</div>
</body>
import Vue from "vue";
Vue.component("text-component",{
props:{
title:String
},
computed:{
text:function(){
return this.title
}
},
template:'<div>\
<span>{{text}}</span>\
<button v-on:click="handleClick">changeTitle</button>\
</div>',
methods:{
handleClick:function(){
this.$emit("update:title","world");
}
}
})
const vm = new Vue({
el:"#root",
data:{
title:"hello"
}
})
上面的
<text-component
v-bind:title="title"
v-on:update:title="title=$event"
></text-component>
可简写成,
<text-component v-bind:title.sync="title"></text-component>