v-model的实质
<input type="text" v-model="username">
其实v-model实质上就是一个语法糖,等价于
<input type="text" :value="username" @input="username=$event.target.value">
相当于对input框的input事件进行了监听,其实在vue的源码中也是这么实现的
修改props值的问题
在日常开发中,我们经常会遇到需要修改props中的某个值的场景,但是如果修改会直接报错
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “isOn”
found in
—> at src/components/OrSwitch.vue
at src/App.vue
所以我们需要在子组件中,定义对应方法,通过this.$emit
发送事件,将想修改的属性以及修改后的值传回到父组件中,再对其进行更新
子组件Children.vue
....
props: {
bool: {
type: Boolean,
default: true
}
}
methods: {
handleMsg(){
this.$emit('handleMsg', false)
}
}
....
父组件Parent.vue
<temple>
...
<children :bool="bool" @handleMsg="handleMsg">
...
</temple>
<script>
export default {
data: {
return {
bool: true
}
}
methods: {
handleMsg(value){
this.bool = value
}
}
}
</script>
显然这种办法过于麻烦,vue也为我们提供了相应的语法糖——.sycn修饰符
.sync修饰符的使用
子组件Children.vue
只需要将子组件发送时间的名称改为update:bool
(bool为想修改的属性名)
....
props: {
bool: {
type: Boolean,
default: true
}
}
methods: {
handleMsg(){
this.$emit('update:bool', false)
}
}
....
父组件Parent.vue
父组件中将:bool="visible"
改为:bool.sync="visible"
,并且不再需要自己定义方法去修改bool的值,.sync修饰符会将子组件传出的value自动的更新到bool上,也就是bool会变为false
<temple>
...
<children :bool="bool">
...
</temple>
<script>
export default {
data: {
return {
bool: true
}
}
}
</script>
v-model的另一种用法
前面我们提到了v-model的本质就是监听input事件,所以我们可以利用这个机制,用v-model去做进一步的简化,现在我们只需要在子组件发送一个名为input事件即可(记住!此时子组件接收的名字也必须是value),并且在父组件中直接使用v-model="xxx"
即可实现数据的双向绑定
子组件
<template>
<input :value="value" />
</template>
<script>
export default {
props: {
value: {
type: String,
default: ''
}
}
methods: {
handleInput(e){
this.$emit('input', e.target.value)
},
}
}
</script>
父组件
<!-- username在data中自己定义 -->
<or-input placeholder="请输入用户名" v-model="username"/>