Vue 的 v-model

337 阅读1分钟

1.设计思路

v-model 本质上是语法糖,负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

在大部分情况下, v-model="XXX" 等价于 :value="XXX" 加上 @input="XXX = $event"

存在以下两点特殊情况:

  1. vue2 给组件提供了 model 属性,可以让用户自定义传值的prop名更新值的事件名

  2. 对于原生 html 原生元素,vue 干了大量『脏活儿』,在原生HTML中,需要处理的事件是$event.target.value

  • textarea 元素:

  • select 下拉框:

  • input type='radio' 单选框:

  • input type='checkbox' 多选框:

在编程思想上,这种帮助使用者『隐藏细节』的方式叫封装

副作用

如果 v-model 绑定的是响应式对象上某个不存在的属性,那么 vue 会悄悄地增加这个属性,并让它响应式。

<template>
  <div id="app">
    {{user.tel}}
    <input type="text" v-model="user.tel">
  </div>
</template>

<script>


export default {
  name: "App",
  data(){
    return {
      user:{
        name:"小米"
      }
    }
  }
  }
</script>

这段代码会为user自动添加响应式的tel属性

双向绑定和单向数据流

子组件不能改变父组件传递给它的 prop 属性,推荐的做法是它抛出事件,通知父组件自行改变绑定的值,简而言之:『数据向下,事件向上』。

自定义组件的v-model

子组件

<!-- vue中的自定义组件中,若父组件中用v-model的话,其实相当于v-bind:value='***'并且v-on:input='***' -->
<!-- 因此子组件内部用props接收value值,用$emit触发input事件,默认传递value值和input事件是模拟v-model的默认规则 
@是v-on监听事件的简写,:是v-bind绑定属性的简写-->
<!--<input type="text" class="input-v-model" :value="value" @input="inputChange" /> -->


<template lang="">
    <div class="red">
        <input type="text" @input="value=$event.target.value" :value="value">
        {{value}}
    </div>
</template>
<script>
export default {
   name:"child",
   props:{
       value:{
           type:String
       }
   },
   methods:{
       inputChange(e){
           this.$emit("input",e.target.value)
       }
   }
}
</script>
<style>
    .red{
        border: 1px solid red;
    }
</style>

父组件

<template>
  <div id="app" class="blue">
    <child v-model="childName"></child>
  </div>
</template>

<script>
import Child from "./components/Child.vue"
export default {
  name: "App",
  components:{
    Child
  },
  data(){
    return{
      childName:""
    }
  },
  methods:{

  }
}
</script>

<style>
 .blue{
  border: 1px solid blue;
}
</style>