v-model: 用于在表单输入元素和应用状态之间 创建双向数据绑定
- 既可以 支持 原生表单元素(input select textarea )
- 也可以支持自定义组件(v2.2.0+新增)
如果你想自己实现类似 v-model 的功能,你需要理解 Vue 的自定义指令和事件处理机制。
创建一个自定义指令
// 自定义指令 'v-custom-model'
Vue.directive('custom-model', {
bind(el, binding, vnode) {
// 1.绑定时设置初始值
el.value = binding.value;
// 2.添加事件监听器来更新数据
el.addEventListener('input',
() => { vnode.context[binding.arg] = el.value; });
},
update(el, binding) {
// 当绑定值更新时,更新 DOM 元素的值
el.value = binding.value;
}
});
在组件中使用自定义指令:
<input v-custom-model="message" />
(但这种方法并不完全符合
v-model的使用习惯,因为v-model通常是一个语法糖,它结合了v-bind和事件监听)
更推荐的方案:
- 默认使用
:value="value"(props) 和 @input事件 - 可以使用
model属性 配置 prop 和event
<template>
<input :value="value" @input="$emit('input', $event.target.value)" />
</template>
<script>
export default {
props: ['value']
};
</script>
父组件的使用
<template>
<div>
<MyInput v-model="message" />
<p>{{ message }}</p>
</div>
</template>
- 父组件使用v-model="xxx"
- 子组件定义value是"switchStatus", 在子组件里使用的都是switchStatus
<span
class="switch-button"
:class="{ open: switchStatus }"
@click.stop="toggleButton"
></span>
//...
name: "BasicSwitchButton",
props: {
switchText: {
type: String,
default: "",
},
switchStatus: {
type: Boolean,
default: false,
},
},
model: {
prop: "switchStatus",
event: "change",
},
methods: {
toggleButton() {
this.$emit("change", !this.switchStatus);
},
},
//...