今天学习了coderwhy老师的项目里的自定义组件使用v-model实现双向绑定,一般都会修改props里的属性值,这是我们不提倡的,所以我总结一些问题和解决方案,如下:
一般的方法(这些方法都会修改props的属性值,我们不提倡):
方案一:(弊端:违反了单向数据流设计原则:子组件修改了props的属性值)
父组件:
子组件:
方案二:弊端:看似改变了值是通过emit传出去让父组件修改,但是实际上这个set方法还是没有触发
子组件:
vue的父组件通过props将一些属性传给子组件,子组件里的某个元素要使用v-model绑定传进来的props,但是这里有个问题,如果子组件的某个元素,比如(input表单),他绑定的值发生变化,那么porps的属性的值就会发生变化,那么这就相当于修改了props的值,这就违反了props单向数据流的原则。那么我们需要怎么做呢?
解决方案:(这个方案没有违反props单向数据流原则)
1.拷贝一份给formData 这时formData与user里的formData没有关联
2.我们要监听formData的改变,发生改变就使用emit把事件传出去告知user里的formData修改 (因为我们要监听formData里的属性值变化 所以要深度监听)
父组件
相关代码:
setup() {
const formData = ref({
id: '',
name: '',
password: '',
sport: '',
createTime: ''
})
return { searchFormConfig, formData }
}
子组件
export default defineComponent({
props: {
modelValue: {
type: Object,
require: true
}
}
},
emits: ['update:modelValue'],
setup(props, { emit }) {
// 拷贝一份给formData 这时formData与user里的formData没有关联
const formData = ref({ ...props.modelValue })
// 我们要监听formData的改变,发生改变就使用emit把事件传出去告知user里的formData修改
// 因为我们要监听formData里的属性值变化 所以要深度监听
watch(
formData,
(newValue) => {
emit('update:modelValue', newValue)
},
{ deep: true }
)
return { formData }
}
})
</script>