v-model和.sync修饰符

172 阅读1分钟

1.v-model

v-model是vue实现数据双向绑定的语法糖。
什么是数据双向绑定?数据双向绑定就是这里有一个input输入框,用户输入的内容,和页面显示的内容是实时更新的。
代码:

<!-- 在大部分情况下,以下两种写法是等价的 -->
<el-input v-model="foo" />

<el-input :value="foo" @input="foo = $event" />

(1)给子组件传递一个props,名为value
(2)监听子组件上的事件input,在回调函数中,将从子组件回传的值保存在foo中

用法:

你可以用 v-model 指令在表单 <input><textarea> 及 <select> 元素上创建双向数据绑定。

注意:v-model是一个单向数据流的典型范式 单向数据流: 子组件不能改变父组件传递给它的 prop 属性,推荐的做法是它抛出事件,通知父组件自行改变绑定的值

2.所以,在前端vue面试题中,有一个必考题目就是:父子组件的通信方式?

.sync修饰符其中一个方法,它和v-model有点类似

.sync 修饰符是事件绑定的语法糖。

对于它的使用场景,用一个现实中的例子举例:正常来说,钱都是在父亲身上的,儿子要用钱是告诉父亲要用钱,然后父亲从身上拿出钱给儿子使用。如果说子组件直接操作父父组件传过来的值,等同于儿子没经过通知父亲这一步就拿钱用了,这等于是偷钱,不合理的。

其实父子组件传值的过程等同于是父亲告诉儿子,我有这么些个钱可以用,不是让子组件直接操作这个值。你要用多少,告诉我,然后把用完后会剩余多少告诉我就可以了。

child.vue(子组件)

<template>
  <div class="child">
    {{money}}
    <!-- 我要用100 -->
    <button @click="$emit('update:money', money-100)">
      <span>花钱</span>
    </button>
  </div>
</template>

<script>
export default {
  props: ["money"]
};
</script>

<style>
.child {
  border: 3px solid green;
}
</style>

parent.vue(父组件)

<template>
  <div class="app">
    App.vue 我现在有 {{total}}
    <hr>
    <!-- 语法糖式写法 -->
    <!-- <Child :money.sync="total"/> -->
    <Child :money="total" v-on:update:money="total = $event"/>
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  data() {
    return { total: 10000 };
  },
  components: { Child: Child }
};
</script>

<style>
.app {
  border: 3px solid red;
  padding: 10px;
}
</style>

这个代码就是上述内容的解释,实现的原理是利用eventBus,在子组件使用$emit('update:money', money-100) 来通知父组件去响应,而父组件则通过$event 来接收经过子组件修改后的值。

3.v-model和.sync对比

  • 书写格式不同 v-model="sum", :num.sync="sum"

  • 绑定个数不同 v-model一个组件或输入框只能绑定一个 .sync可以有多个

  • v-model 是@input + value的语法糖

  • .sync 是@update:sum 的语法糖