v-model
在自定义的组将直接绑定父组件中的数据变量,在自定义组件中将需要绑定的值发送给v-model绑定的变量。
<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++;
this.$emit('input', this.counter);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
}
})
</script>
原理
默认实现了@input='handle'
的事件,以v-model
代替
<div id='app'>
<p>{{total}}</p>
<my-component @input="handleGetTotal"></my-component>
</div>
<script>
// ...组件代码
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
handleGetTotal: function (total) {
this.total = total
}
}
})
</script>
数据双向绑定
在自定义组件中接收value
属性,当有新的值时,传递到绑定的v-model
<div id='app'>
<p>{{total}}</p>
<my-component v-model="total"></my-component>
<button @click="handelReduce"> -1 </button>
</div>
<script>
Vue.component('my-component', {
props: ['value'],
template: '<input :value="value" @input="updateValue" />',
methods: {
updateValue: function (event) {
this.$emit('input', event.target.value);
}
}
});
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
handelReduce: function () {
this.total--;
}
}
})
</script>
以modal
为例,一般在data中创建value
的副本,在watch
中监听,当改变后同步到v-modal
<template>
<div class="modal" :value="value" v-show="visible">
<div class="close" @click="cancel">X</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default:false
}
},
data () {
return {
visible:false
}
},
watch: {
value(val) {
this.visible = val;
},
visible(val) {
this.$emit('input', val);
}
},
methods: {
cancel(){
this.visible = false;
}
},
mounted() {
if (this.value) {
this.visible = true;
}
}
}
</script>
<modal v-model="isShow"></modal>
export default {
name: 'app',
data () {
return {
isShow:false
}
}
}
</script>
另一种写法
我觉得相当于重命名了value
和input
<template>
<div class="modal" :value="renameValue" v-show="visible">
<div class="close" @click="cancel">X</div>
</div>
</template>
<script>
export default {
model: {
prop: 'renameValue',
event: 'renameInput'
},
props: {
renameValue: {
type: Boolean,
default: false
}
},
data () {
return {
visible:false
}
},
watch: {
renameValue(val) {
this.visible = val;
},
visible(val) {
this.$emit('renameInput', val);
}
},
methods: {
cancel(){
this.visible = false;
}
},
mounted() {
if (this.renameValue) {
this.visible = true;
}
}
}
</script>