如何让自己封装的Vue组件支持v-mode

290 阅读1分钟

1. v-mode的作用是什么?

它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理 《官方文档》

2. 使用场景

v-mode使用场景一般用于表单输入绑定(输入框,单选框,多选框,多行文本等)

3. 修饰符

自动过滤用户输入的首尾空白字符

<input v-model.trim="msg">

在“change”时而非“input”时更新

<input v-model.lazy="msg">

自动将用户的输入值转为数值类型

<input v-model.number="age" type="number"

4. 如何在自定义组件中支持v-mode?

  • 在做之前我们先看一下ElementUI中的input组件是如何使用的
// 直接将数据进行绑定了
<el-input v-model="value"></el-input>
  • 对于Element的源码这里就不展示了,下面我们参照上面例子手动简单实现一下
// input组件
<template>
      <input type="text" v-bind="{value:value}">
</template>

<script>
export default {
    name:'Vueinput',
    componentName:'Vueinput',
    props:{
         value:String
    }
}
</script>
//父组件
<template>
    <div>
        <inputsVue v-model="values"></inputsVue>
        <button @click="consclick">dianji</button>
    </div>
</template>

<script>
import inputsVue from './inputs.vue'
export default {
    data(){
         return {
             values:'asda'
         }
    },
  components:{
     inputsVue
  },
  methods:{
     consclick(){
         console.log('父组件',this.values)
     }
  }
}
</script>

这样是单项数据流,父组件不会随着子组件的输入框的内容改变而改变

image.png

  • 下面我们把上面的代码改造一下,让父组件的数据跟随子组件更新
// 子组件
<template>
      <input type="text" v-bind="{value:inputValue}" @input="updateValue">
</template>

<script>
export default {
    name:'Vueinput',
    componentName:'Vueinput',
    props:{
         inputValue:String
    },
    model:{  // 自定义v-mode属性,默认是value
          prop: 'inputValue',
          event: 'input'
    },
    methods:{
         updateValue(e){
              // 这里我们通知父级数据更新
              this.$emit('input',e.target.value);
         }
    }
    
}
</script>

// 父组件

<template>
    <div>
        <inputsVue v-model="values"></inputsVue>
        <button @click="consclick">dianji</button>
    </div>
</template>

<script>
import inputsVue from './inputs.vue'
export default {
    data(){
         return {
             values:'asda'
         }
    },
  components:{
     inputsVue
  },
  methods:{
     consclick(){
         console.log('父组件',this.values)
     }
  }
}
</script>

点击按钮,我们的父组件已经同步更新了

image.png

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的model 选项可以用来避免这样的冲突 《官方文档》

总结

v-mode 语法糖 在组件中使用相当于组件数据绑定:value="value"和事件绑定@input="value = $event"两者结合,也算是父子组件通信中的一种,在ElementUI中像el-inputdrawer 等组件都使用了v-mode语法糖,感兴趣可以去看一下ElementUI的源码