浏览本文📖
你将:
- 弄明确:
v-model
是什么的语法糖?vue2
对原生组件到底做了什么非凡解决? - 弄明确:
v-model
到底是 单向数据流 还是 数据双向绑定? - 弄明确:
v-model
在语法糖之外的『副作用』? - 学会如何让你的组件也反对
v-model
语法。
一、v-model
的实质是语法糖。
『
v-model
实质上不过是语法糖。它负责监听用户的输出事件以更新数据,并对一些极其场景进行一些非凡解决。』— 官网文档
什么是语法糖?
语法糖,简略来说就是『便捷写法』。
在大部分状况下,v-model="foo"
等价于 :value="foo"
加上 @input="foo = $event"
;
<!-- 在大部分状况下,以下两种写法是等价的 -->
<el-input v-model="foo" />
<el-input :value="foo" @input="foo = $event" />
没错,在 大部分状况下 如此。
但也有例外:
vue2
给组件提供了model
属性,能够让用户自定义 传值的 prop 名 和更新值的事件名。这个暂且略过,第四节会细说。-
对于原生
html
原生元素,vue
干了大量『脏活儿』,目标是为了能让咱们漠视html
在 api 上的差异性。以下元素的左右两种写法是等价的:textarea
元素:select
下拉框:input type='radio'
单选框:input type='checkbox'
多选框:
在编程思维上,这种帮忙使用者『暗藏细节』的形式叫 封装。
二、v-model 仅仅是语法糖吗?(冷常识)
v-model
不仅仅是语法糖,它还有副作用。
副作用如下:如果 v-model
绑定的是响应式对象上某个不存在的属性,那么 vue
会悄悄地减少这个属性,并让它响应式。
举个例子,看上面的代码:
// template 中:<el-input v-model="user.tel"></el-input>
// script 中:export default {data() {
return {
user: {name: '公众号: 前端要摸鱼',}
}
}
}
响应式数据中没有定义 user.tel
属性,然而 template
里却用 v-model
绑定了 user.tel
,猜一猜当你输出时会产生什么?
看成果:
揭晓答案吧:user
上会新增 tel
属性,并且 tel
这个属性还是 响应式 的。
这就是『副作用』带来的成果,你学会了吗?
三、v-model
是双向绑定还是单向数据流?
2.1 v-model
是双向绑定吗?
是,官网说是。
『你能够用 v-model 指令在表单 <input>
、<textarea>
及 <select>
元素上创立双向数据绑定。』—— vue2 官网文档
2.2 那 v-model
是单向数据流吗?
是的,它甚至是单向数据流的典型范式。
尽管官网没有明确示意这点,但咱们能够捋一捋两者的关系。
- 什么是单项数据流?
子组件不能扭转父组件传递给它的prop
属性,举荐的做法是它抛出事件,告诉父组件自行扭转绑定的值。 v-model
的做法是怎么的?v-model
做法完全符合单项数据流。甚至于,它给出了一种在命名和事件定义上的标准。
家喻户晓 .sync
修饰符是单向数据流的另一个典型范式。
『单向数据流』总结起来其实也就 8 个字:『数据向下,事件向上』。
四、如何让你开发的组件反对 v-model
尽管不想说,但这的确是高频面试题。🤣
在定义 vue
组件时,你能够提供一个 model
属性,用来定义该组件以何种形式反对 v-model
。
model
属性自身是有默认值的,如下:
// 默认的 model 属性
export default {
model: {
prop: 'value',
event: 'input'
}
}
也就是说,如果你不定义 model
属性,或者你依照当面办法定义属性,当其他人应用你的自定义组件时,v-model="foo"
就齐全等价于 :value="foo"
加上 @input="foo = $event"
。
如果把 model
属性进行一些改装,如下:
// 默认的 model 属性
export default {
model: {
prop: 'ame',
event: 'zard'
}
}
那么,v-model="foo"
就等价于 :ame="foo"
加上 @zard="foo = $event"
。
没错,就是这么容易,让咱们看个例子。
先定义一个自定义组件:
<template>
<div>
咱们是 TI{{ame}}冠军
<el-button @click="playDota2(1)"> 加 </el-button>
<el-button @click="playDota2(-1)"> 减 </el-button>
</div>
</template>
<script>
export default {
props: {
ame: {
type: Number,
default: 8
}
},
model: { // 自定义 v -model 的格局
prop: 'ame', // 代表 v-model 绑定的 prop 名
event: 'zard' // 代码 v-model 告诉父组件更新属性的事件名
},
methods: {playDota2(step) {
const newYear = this.ame + step
this.$emit('zard', newYear)
}
}
}
</script>
而后咱们在父组件中应用该组件:
// template 中
<dota v-model="ti"></dota>
// script 中
export default {data() {
return {ti: 8}
}
}
看看成果:
让你的组件反对 v-model
就这么容易。
五、demo 和源码
获取源码请拜访 github zhangshichun 的 github
六、完结
我是 春哥
。
我酷爱 vue.js
, ElementUI
, Element Plus
相干技术栈,我的指标是给大家分享最实用、最有用的知识点,心愿大家都能够早早上班,并能够飞速实现工作,淡定摸鱼🐟。
你能够在 公众号 里找到我:前端要摸鱼
。
心愿大家玩得开心。