vue自定义组件上使用v-model
一、表单绑定
1.1、v-model基本使用
Vue中使用v-model指令来实现表单元素和数据的双向绑定
<template> <section> <input type="text" v-model="message"> {{message}} </section> </template> <script> export default { data() { return { message: '你好啊' } } } </script>
解析:当在输入框输入内容时,因为input中的v-model绑定了message,所以会实时将输入的内容传递给message。当message发生改变时,也会将message的值插入到DOM中,所以DOM会发生响应的改变。
1.2、v-model原理
v-model其实是一个语法糖,它的背后本质上是包含两个操作:
- 1.v-bind绑定一个value属性
- 2.v-on指令给当前元素绑定input事件
也就是说上面的代码 等同于下面的代码:
<template> <section> <!-- <input type="text" v-model="message"> --> <!-- 等同于 --> <input type="text" :value="message" @input="message = $event.target.value"> <h2>{{message}}</h2> </section> </template> <script> export default { data() { return { message: '你好啊' } } } </script>
二、组件上使用v-model
2.1 官网解释:
允许一个自定义组件在使用 v-model
时定制 prop 和 event。默认情况下,一个组件上的 v-model
会把 value
用作 prop 且把 input
用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value
prop 来达到不同的目的。使用 model
选项可以回避这些情况产生的冲突。
自定义model使用示例:
model: { prop: 'myValue', // 默认是value event: 'myInput', // 默认是input }
当我们使用model的默认值的时候value作prop,input作event时,可以省略不写model。
2.2 v-model的使用
2.2.1 自定义组件代码示例
<template> <section> <!-- 自定义组件中使用v-mode指令 --> <input @input="changeInput"> </section> </template> <script> export default { name: 'CustomModel', // 当我们使用model的默认值的时候value用作prop,input用作event时,可以省略不写model。 model: { prop: 'myValue', // 默认是value event: 'myInput', // 默认是input }, props: { // 接收string和number类型的值, // 注意不能是写成字符串["String","Number"],因为此时它们是构造器,是全局变量 myValue: [String, Number], }, methods: { changeInput(e) { // 向上派发myInput事件,这样model监听myInput才有意义:当输入字符时触发input事件,进而派发触发自定义的myInput事件,然后model监听myInput,就实现了数据绑定。 // 必须注意,这里的派发事件名“myInput”必须和model中的event的值相同。 // PS: 通过watch监听 input标签的值,然后$emit派发事件,和通过@input派发事件具有一样的效果。只要能达到通信的效果即可,手段是多样的。 this.$emit('myInput', e.target.value); } } } </script>
2.2.2 在父组件中使用自定义组件
<template> <div class="home"> <h3>输入的实时内容:{{ myValue }}</h3> <custom-model v-model="myValue"></custom-model> </div> </template> <script> import CustomModel from './CustomModel'; export default { components: { CustomModel, }, data() { return { myValue: '' } } } </script>
2.3 自定义checkbox组件
2.3.1 子组件
<template> <section> <input type="checkbox" :checked="checked" @change="handleChange"> 点赞哈默视频? </section> </template> <script> export default { model: { prop: 'checked', // 默认是value,注意是prop,不带s。 event: 'change', // 默认是input }, props: ['checked'], methods: { handleChange(e) { this.$emit('change', e.target.checked); } } } </script>
2.3.2 父组件
<template> <div class="app"> <BaseCheckbox v-model="checked" /> <!-- <BaseCheckbox :checked="checked" @change="checked = $event" /> --> <p>已经赞了:{{checked}}</p> </div> </template> <script> import BaseCheckbox from './BaseCheckbox'; export default { components: { BaseCheckbox, }, data() { return { checked: true } } } </script>