前言
在uniapp中, 封装组件的props单向数据流更为严格, 不允许改变子组件的props属性, 所以记录下uniapp下的form表单的组件是如何封装的, 双向数据是如何绑定的.
版本: "@dcloudio/uni-ui": "^1.4.27", "vue": ">= 2.6.14 < 2.7"...
需求
实现下面这张图片这样的场景
实现代码
抽取了逻辑代码, 业务代码全部去除方便大家阅读.
父组件:
// 父组件:
<template>
// uni-app不支持v-model:formData="formData"
<hf-form-data v-model="formData" :config="config"/>
</template>
<script>
export default {
name:"fatherComp",
data() {
return {
config: [
{
type: "input",
label: "我是输入框",
key: "name",
rules: [{ required: true, errorMessage: "请选择" }]
},
{
type: "textarea",
label: "我是文本域",
key: "remark",
rules: [{ required: true, errorMessage: "请选择" }],
},
],
// 和config数组的key一一对应
formData: {
name:"",
remark: ""
}
};
},
watch: {
formData: {
handler(newVal) {
console.log('父组件更新啦', newVal);
},
deep: true,
},
}
};
</script>
子组件:
// 子组件
<template>
<uni-forms ref="form" :model="formValue">
<view v-for="(item,i)in config" :key="i">
<!-- 双向数据绑定 -->
<uni-forms-item
:name="item.key"
:label="item.label"
:rules="item.rules"
>
<input v-if="item.type === 'input'" v-model="formValue[item.key]"/>
<textarea v-else-if="item.type === 'textarea'" v-model="formValue[item.key]"/>
</uni-forms-item>
</view>
</uni-forms>
</template>
<script>
export default {
name: "childComp",
props: {
config: {
type: Array,
default: () => [],
},
value: {
type: Object,
default: () => {},
},
},
data() {
return {
formValue: {},
};
},
watch: {
// 2. 监听子组件的表单变更, 更新父组件
formValue: {
handler(newVal) {
this.$emit("input", newVal);
},
deep: true,
},
},
created() {
this.formValue= { ...this.value }; // 1. 初始化赋值, 通过拷贝去除对象引用问题
}
};
</script>