v-model
指令<input v-model="text" />
复制代码
上例不过是一个语法糖,展开来是:javascript
<input :value="text" @input="e => text = e.target.value" />
复制代码
.sync
修饰符<my-dialog :visible.sync="dialogVisible" />
复制代码
这也是一个语法糖,剥开来是:html
<my-dialog :visible="dialogVisible" @update:visible="newVisible => dialogVisible = newVisible" />
复制代码
my-dialog
组件在 visible
变化时 this.$emit('update:visible', newVisible)
便可。vue
model
属性 (JSX/渲染函数中)Vue 在 2.2.0
版本之后,容许自定义组件的 v-model
,这就致使在 JSX / 渲染函数中实现 v-model
时得考虑组件的不一样配置,不能一概如此(假使 my-dialog
组件的 model
为 { prop: 'visible', event: 'change' }
):java
{
render(h) {
return h('my-dialog', {
props: { value: this.dialogVisible },
on: { input: newVisible => this.dialogVisible = newVisible }
})
}
}
复制代码
而应如此:git
{
render(h) {
return h('my-dialog', {
props: { visible: this.dialogVisible },
on: { change: newVisible => this.dialogVisible = newVisible }
})
}
}
复制代码
然而,利用 model
属性,彻底能够作到不用管它 prop
、event
的目的:github
{
render(h) {
return h('my-dialog', {
model: {
value: this.dialogVisible,
callback: newVisible => this.dialogVisible = newVisible
}
})
}
}
复制代码
JSX 中这样使用:函数
{
render() {
return (
<my-dialog {...{ model: { value: this.dialogVisible, callback: newVisible => this.dialogVisible = newVisible } }} /> ) } } 复制代码
vue-better-sync
插件有需求如此:开发一个 Prompt 组件,要求同步用户的输入,点击按钮可关闭弹窗。 ui
<template>
<div v-show="_visible">
<div>完善我的信息</div>
<div>
<div>尊姓大名?</div>
<input v-model="_answer" />
</div>
<div>
<button @click="_visible = !_visible">确认</button>
<button @click="_visible = !_visible">取消</button>
</div>
</div>
</template>
<script> export default { name: 'prompt', props: { answer: String, visible: Boolean }, computed: { _answer: { get() { return this.answer }, set(value) { this.$emit('input', value) } }, _visible: { get() { return this.visible }, set(value) { this.$emit('update:visible', value) } } } } </script>
复制代码
写一两个组件还好,组件规模一旦扩大,写双向绑定真能写出毛病来。因而,为了解放生产力,有了 vue-better-sync
这个轮子,且看用它如何改造咱们的 Prompt 组件:this
<template>
<div v-show="actualVisible">
<div>完善我的信息</div>
<div>
<div>尊姓大名?</div>
<input v-model="actualAnswer" />
</div>
<div>
<button @click="syncVisible(!actualVisible)">确认</button>
<button @click="syncVisible(!actualVisible)">取消</button>
</div>
</div>
</template>
<script> import VueBetterSync from 'vue-better-sync' export default { name: 'prompt', mixins: [ VueBetterSync({ prop: 'answer', // 设置 v-model 的 prop event: 'input' // 设置 v-model 的 event }) ], props: { answer: String, visible: { type: Boolean, sync: true // visible 属性可用 .sync 双向绑定 } } } </script>
复制代码
vue-better-sync
统一了 v-model
和 .sync
传递数据的方式,你只需 this.actual${PropName} = newValue
或者 this.sync${PropName}(newValue)
便可将新数据传递给父组件。spa
GitHub:fjc0k/vue-better-sync