初识Vue的双向绑定

98 阅读1分钟

Vue的双向绑定如何实现?

  • v-model可以实现绑定一个变量

  • 在变量变化的时候UI会变化

  • 用户改变UI的时候数据也会变化

举例

//App.vue
<template>
  <div id="app">
    {{user}}
    <hr/>
    <form @submit.prevent="onSubmit">
      <label>
         <span>用户名</span>
        <input type="text" v-model="user.username">
      </label>
       <label>
         <span>密码</span>
        <input type="password" v-model="user.password">
      </label>
      <button>登录</button>
    </form>
  </div>
</template>

<script>
export default {
  name: 'App',
  data(){
    return{
      user:{
        username:'',
        password:''
      }
    }
  },
  methods:{
    onSubmit(){
      console.log(this.user);
    }
  },
  components: {
  }
}
</script>

双向绑定

v-model 本质

<label>
         <span>用户名</span>
        <input type="text" :value="user.username"
        @input="user.username=$event.target.value">
      </label>

这就是v-model的本质,且这样仍能完成双向绑点,

为了更加细致了解v-model的本质

我们自己做一个input(框为红色)

//MyInput.vue
<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{
    border:2px solid red;
}

.wrapper{
    display: inline-block;
}
</style>

App.vue中引入

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

MyInput 添加v-model

 <label>
         <span>用户名</span>
        <MyInput v-model="user.username"/>
      </label>

双向绑定2

一样能完成双向绑定

但这时v-model等价于

<label>
         <span>用户名</span>
        <MyInput :value="user.username" 
        @input="user.username = $event"/>
      </label>

总结

  • v-model实际上是v-bind:valuev-on:input的语法糖
  • 在原生的组件中 v-on:input="xxx=$event.target.value"
  • 在自定义组件中 v-on:input="xxx=$event"