大家好,我是小杨,一个干了6年前端的老司机。今天咱们聊聊Vue里那个天天用,但可能很多人没完全搞明白的东西------v-model。
别看它写起来简单,就一个v-model="xxx"
,但背后的玩法可多了去了!今天我就带大家扒一扒它的老底,顺便分享几个我实际开发中发现的骚操作。
1. v-model的本质:语法糖而已!
先抛结论:v-model本质上就是个语法糖 ,它帮我们自动处理了value
绑定和input
事件。
比如这段代码:
html
<input v-model="username" />
实际上等价于:
html
<input
:value="username"
@input="username = $event.target.value"
/>
2. 组件上也能用v-model?
当然可以!而且Vue 3里玩法还升级了。
假设我写了个自定义组件MyInput
:
html
<!-- 父组件 -->
<MyInput v-model="myValue" />
在Vue 2里,子组件需要这样:
javascript
// 子组件
export default {
props: ['value'],
methods: {
handleInput(e) {
this.$emit('input', e.target.value)
}
}
}
但在Vue 3里,更灵活了:
javascript
// 子组件
export default {
props: ['modelValue'], // 默认属性名变了!
emits: ['update:modelValue'],
methods: {
handleInput(e) {
this.$emit('update:modelValue', e.target.value)
}
}
}
3. 高级玩法:多个v-model绑定
Vue 3最爽的功能之一------一个组件可以绑定多个v-model!
比如我做个用户信息表单组件:
html
<UserForm
v-model:name="userName"
v-model:age="userAge"
v-model:email="userEmail"
/>
子组件这样接收:
javascript
export default {
props: ['name', 'age', 'email'],
emits: ['update:name', 'update:age', 'update:email']
}
4. 自定义修饰符
你知道v-model还能加修饰符吗?比如.trim
、.number
。其实我们也能自定义!
html
<MyInput v-model.capitalize="myText" />
子组件里可以这样处理:
javascript
export default {
props: {
modelValue: String,
modelModifiers: { // 自动注入的修饰符对象
default: () => ({})
}
},
methods: {
handleInput(e) {
let value = e.target.value
if (this.modelModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
this.$emit('update:modelValue', value)
}
}
}
5. 我踩过的坑
- v-model和value冲突 :如果同时写了
v-model
和value
,v-model
会覆盖value
- v-model.number不是万能的:输入法状态下可能失效,最好在提交时再做一次数字校验
- 自定义组件记得处理初始值:特别是那些不是input的组件
6. 终极骚操作
最后分享一个我在项目里用到的骚操作------用v-model实现简易状态管理:
javascript
// store.js
export const store = reactive({
state: {
count: 0
},
mutations: {
setCount(newVal) {
this.state.count = newVal
}
}
})
// 组件里
<input v-model="store.state.count" />
虽然比不上Vuex或Pinia,但在小项目里临时用用还挺方便!
结语
v-model这个看似简单的东西,其实藏着不少玄机。从Vue 2到Vue 3,它的功能越来越强大,用好了真的能大幅提升开发效率。
你在用v-model时还发现过什么骚操作?欢迎在评论区分享!如果觉得有用,别忘了点赞收藏~
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!