v-model
v-model 是什么
v-model:Vue框架的一种内置的API指令,本质是一种语法糖写法。它负责监听用户的输入事件以更新数据,并对一些极端场景进行特殊处理。
为什么使用v-model
可以在表单 input、textarea以及select元素上创建双向数据绑定它会根据控件类型自动选取正确的方法来更新元素。
但 v-model 本质上不过是语法糖,它可以让代码看起来更简洁一些。
那什么是语法糖呢
语法糖是指语言中的一个构件,当去掉该构件后并不影响语言的功能和表达能力。
简单的说,语法糖就是一种便捷写法。
例如:
()=>{} // function(){}
{...object} // Object.assign({},object)
v-model 原理
众所周知 vue是单向数据流 //不周知
父子组件一般都是属性事件传值,也就是v-bind 和$emit()
- 插一句 vue为什么是单向数据流
//上面不直接说插这里干嘛,第一句话什么鬼
“这是因为vue是单向数据流 也就是说,数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据的修改。 这实际上是为了更好的解耦,在开发中如果有多个子组件依赖与父组件的某个数据,万一子组件真的可以直接修改父组件的数据,那么一个子组件的变化将会引发所有依赖于这个数据的子组件的变化,所以vue不推荐子组件直接修改父组件的数据,直接修改prop会抛出警告。”
v-model 其实就是vue的 v-bind 和 v-on的语法糖
- 插一句 啥叫语法糖 ;简便来说就是一直便捷写法,用语法糖和不用语法糖的代码功能都是一样
具体怎么使用
- 声明一个组件child.vue
<template>
<div>
<button @click="$emit('change', value++)">点击 {{ value }}</button>
</div>
</template>
<script>
export default {
components: {},
props: {
value: {
type: Number,
default: 0,
},
},
};
</script>
- 在声明一个组件parent.vue
<template>
<div>
<child :value="value" @change="childChange"></child>
</div>
</template>
<script>
import child from './child.vue';
export default {
components: {
child,
},
props: {},
data() {
return {
value: 0,
};
},
methods: {
childChange(value) {
this.value = value;
},
},
};
</script>
这是一个很简单的父子组件传值 每点击一下加一
改造成 v-model的
child.vue
<template>
<div>
<button @click="$emit('change', value++)">点击 {{ value }}</button>
</div>
</template>
<script>
export default {
components: {},
model: {
event: 'change',
props: 'value',
},
props: {
value: {
type: Number,
default: 0,
},
},
};
</script>
parent
<template>
<div>
<child v-model="value"></child>
</div>
</template>
<script>
import child from './child.vue';
export default {
components: {
child,
},
props: {},
data() {
return {
value: 0,
};
},
methods: {},
};
</script>
其实页面的效果是一模一样 区别就是 child组件 增加了一个
model: { event: 'change', props: 'value', },
然后parent 就可以直接用v-model 来代替 :value @change
如果没有写默认是
model: {
event: 'input',
props: 'value',
},
vue的.sync 修饰符
说v-model 是语法糖还是遵从vue的单向数据流;
在vue1.0版本
不过vue1.0时官方依然提供了一个能够强制实现双向数据流的办法:.sync修饰符
这个修饰符在vue2.0的时候被弃用了
不过在vue2.3的时候又被添加了回来,但实现原理有所不同
贴一张源码
可以看出实现原理还是遵从单项数据流的设定
使用.sync后,感觉.sync比v-model更香
- 相同点:
1.两者的本质都是语法糖,目的都是实现组件与外部数据的双向绑定
2.两个都是通过属性+事件来实现的 - 不同点
1.一个组件只能定义一个v-model,但可以定义多个.sync
2.v-model与.sync对于的事件名称不同,v-model默认事件为input,可以通过配置model来修改,.sync事件名称固定为update:属性名
个人理解
个人理解:v-model 和.sync 可能最开始的立意不同,v-model为了表单而定制的 所以默认的方法是(value和@input), .sync为了双向绑定而生(默认方法是update:props), 导致使用上有重叠,在vue3中 这两个去长补短结合到了一起
vue3的v-model
可以看出 vue2 的 v-model和 .sync 实际使用功能类似都能实现类似的双向绑定的效果
缺点是 v-model 只可以同步一个值
在vue3中 v-model 和.sync结合到一起了