背景
- 因为要封装一个表单嘛 然后就要实现父子组件的双向绑定 使得子组件的表单值也能传递回给父组件 当时这里是踩了挺多坑的 呜呜呜呜 太难了
- 话不多说 直接来吧
基础知识
- 双向绑定 那么当然想到的就是 v-model 啊 那么有必要对这个知识点有一定的了解才好去使用
- 那么必然是上官网啊
- 也可以看我总结的 笔记 有一些官网 写的没那么详细 直达
vue3 的使用
-
这里当时踩了一个很大的坑
-
就是动态传值不能使用 基本数据类型 要使用对象才行
-
当时测试的时候怎么都不成功 一直报传递的值时只读的 不能修改
-
代码
-
// 父组件 <page-search :father-data="test" @update:father-data="test = $event" /> <el-button @click="getChildren">获取子组件 input</el-button> // 定义了 几倍呢数据类型 字符串 let test = ref('123') // 获取子组件值得测试按钮 const getChildren = function (e: any) { console.log(test.value.str, 'user', e) test.value.str = '' } // 子组件 <input v-model="props.fatherData" /> const props = defineProps({ fatherData: { type: String, default: '', }, }) const emit = defineEmits([ 'update: fatherData', ]) watchEffect(() => { emit('update: fatherData', props.fatherData) }) // 第二种写法 <input :value="props.fatherData" @input="changeInput($event)" /> const changeInput = function (e: any) { emit('update: fatherData', e.traget.value) } - 这么当时怎么都无法把值传回给父组件 各种不同写法写了好几天 哭了呜呜呜
-
-
然后我就 把数据改为 object 进行传值了
-
// 父组件 两种写法等效 <page-search :father-data="test" @update:father-data="test = $event" <page-search v-model:father-object="test" /> <el-button @click="getChildren">获取子组件 input</el-button> let test = ref({ str: '12', }) const getChildren = function (e: any) { console.log(test.value.str, 'user', e) test.value.str = '' } // 子组件 第一种写法 <input v-model="props.fatherObject.str" /> // eslint 不让这么写 下面贴出链接 const props = defineProps({ fatherObject: { type: Object, default: () => { // eslint 语法规范 传空值不行 要加一行注释 }, }, }) const emit = defineEmits([ 'update: fatherObject', ]) // 监听 依赖发生变化 更新 watchEffect(() => { emit('update: fatherObject', props.fatherObject) }) // 第二种写法 因为开启了 eslint-plugin-vue 上面不让那么写 改成下面这种写法 然后还是不让 嘻嘻嘻 真阴间 我就把它设置为不理睬这种 eslint 了 <input :value="props.fatherObject.str" @input="changeInput($event)" /> const changeInput = function (e: any) { props.fatherObject.str = e.target.value // eslint 这行不让 emit('update: fatherObject', props.fatherObject) } -
-
-
最后来说一下思路
第一种
-
父组件使用 v-model 以自定义参数得形式 传参给子元素 参数是 fatherData
-
子组件接收到参数 使用 v-model 双向绑定到 input 框
-
要使用 emits 要传递给父组件
-
但是因为是双向绑定 所以 这里使用 watch 监听数据变化执行传递得函数
- watch watchEffect computed 不太懂可以看我另一篇文章 直达
第二种
-
因为 第一种是使用双向绑定语法糖 v-model 所以要使用 侦听器
- 但是 eslint 不推荐 v-model 这种写法 所以改成第二种
-
第二种 相当于自己实现了 v-model 所以不需要 侦听
-
本来第二种是可以的 但是因为我是用得是对象得形式
-
changeInput 得到的是 e.target.value 字符串
-
而 emit('update: fatherObject', props.fatherObject) 绑定得是对象
-
所以要 props.fatherObject.str = e.target.value 赋值才能双向绑定成功
- 然后这条语句 对陈传过来得 props 直接赋值 eslint 不让
-
啊啊啊啊啊啊 死循环 不使用 对象我连值都改不了 那也没办法吧 只能这样了
-