浅析 Vue 的双向绑定

775 阅读1分钟

Vue 中的双向绑定是指当我们改变 data 中的一个变量时,页面中该变量也会随之跟新,我们在页面中改变一个变量时,data 中变量的值也随之变化。

通常我们使用 v-model 来实现双向绑定,并且 v-model 只能在 input、selsect、textarea 元素和 component 中使用。

1. v-model 的原理

<input type="text" v-model="value"/>
//等价于
<input type="text" :value="value" @input="value = $event.target.value" />

上面两种写法实现的效果是一致的,即我们在页面上改变变量,data 中的数据也随之改变。

首先我们将数据中的 value 绑定到 input 标签上,然后再通过 @input="value = $event.target.value" 对事件进行监听,$event.target.value 是所触发的事件的返回值。

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

2. 自己实现一个具有 v-model 功能的 input 组件

<template>
  <div class="red wrapper">
    <input :value="value" @input="onInput">
  </div>
</template>

<script>
  export default {
    name: 'MyInput',
    props:{
      value: {
        type: String
      }
    },
    methods:{
      onInput(e){
        const value = e.target.value;
        this.$emit("input", value)
      }
    }
  }
</script>

<style scoped>
  .red{
    background: red;
  }
  .wrapper{}
</style>

如上面代码所示,我们自己写的 input 标签与 v-model 原理中的第二个 input 基本相同,不同的是我们监听的事件变成了组件中的事件。

组件中的 value 通过 props 从外部引入,对 value 值的修改是通过 onInput 事件完成的。

在 onInput 事件内部,我们只需要将 e.target.value 通过 $emit 函数暴露出去,就能让使用组件的人修改 input 中的值。

我们将上面的组件命名为 MyInput,下面演示一下如何使用该组件。

<template>
  <div id="app">
    这里是value: {{value}}
    <MyInput v-model="value"/>
    // 等价于
    // <myInput :value="value" @input="value=$event"/>
  </div>
</template>

<script>
import MyInput from './MyInput'
export default {
  components: { MyInput },
  name: 'App',
  data() {
    return {
      value: ''
    }
  }
}
</script>

<style>
  #app{
    padding: 20px;
  }
</style>

当我们在输入框中输入数据时,输入框上面的值也会随之改变,说明数据和页面之间是实时响应的,也就是说我们实现了双向绑定。

效果如下图所示。

代码效果演示图

如果你想了解更多有关 v-model 的信息,可以查看官方文档 v-model