面试官:Vue中的v-model

348 阅读1分钟

v-model的使用

v-model是实现数据双向绑定的语法糖。主要的应用场景为:input标签的数据双向绑定;通过自定义model,实现父子组件之间的数据双向绑定。

1、input标签中使用

通过v-model命令,可以让input标签的value值与页面data中的变量值进行双向绑定。这是一种语法糖命令,原始写法是将input的value属性绑定一个变量(例如:val),再通过@input事件,将$event.target.value(当前input的value)的值赋值给这个变量(例如:val),从而实现数据的双向绑定。代码如下:

<input v-model='val'/>
<!-- 上面的语句是下面语句的语法糖,两者实现的功能相同 -->
<input :value='val' @input="val = $event.target.value"/>

2、父子组件之间使用

2.1、原本的方式

父子组件通常是使用emitemit和on来实现数据的双向传输。在父组件中,通过为子组件添加属性的方式来向其传递数据;在子组件中,通过props属性来接收数据,但是由于该属性是只读的,因此需要通过事件绑定的$emit来实现修改父组件中的数据。

/*父组件中*/
<template> 
    /*在子组件中传入属性值*/
    <child @change="onChange" :vlaue='val'/>
</template>
<script>
import Child from './child'
export default {
    name: 'child',
    components: {Child},
    methods:{
        onChange(val){
            this.value = val 
        }
    } 
}
</script>

/*子组件中*/
<template> 
    <dev @click='handleClik'> {{value}} </dev>
</template>
<script>
export default {
    name: 'child',
    /*通过props属性来接收父组件中的数据*/
    props: ['value'],
    methods:{
        handleClik(){
            /*通过this.$emit来绑定父组件中的自定义事件,并传参*/
            this.$emit('change', 'value1')
        }
    }   
}
</script>

2.2、通过自定义model

在父组件中,使用v-model="show"来代替:show='show' @close="show = $event"的写法,实现数据的双向绑定。并且,在子组件中使用 model: { prop: 'show', event: 'close' }来自定义触发通信的事件。

/*父组件中*/
<template>
  <div>
    <button @click="show=true">打开model</button>
    <child v-model="show" ></child>
    <!-- 等同于 -->
    <child :show='show' @close="show = $event"></child>
  </div>
</template>

<script>
  import Child from './child'
  export default {
    components: {
      Child
    },
    data () {
      return {
        show: false
      }
    }
  }
</script>

/*子组件中*/
<template>
   <div v-if="show">
      <div>
         <p>定制 v-model</p>
        <button @click='close'>关闭组件</button>
      </div>
   </div>
</template>

<script>
export default {
  model: {
    prop: 'show',
    event: 'close'
  },
  props: ['show'],
  methods: {
    close () {
      this.$emit('close',false)
    }
  }
}
</script>