시나리오
일반 양식 직접 기본 레이아웃, 즉 단일 열 레이아웃, 갑자기 인사 정보 양식, 이중 열 레이아웃 요구 사항이 필요하며 다음을 달성하고 확장하는 것이 간단합니다.
아이디어
직접 브레인리스 DIV+플렉스 레이아웃 구현
코드
<template>
<el-form ref="formRef" :model="formData" label-width="80px">
<div class="form-top">
<div class="form-top--left">
<el-form-item label="이름" 소품="name">
<el-input v-model="formData.name" placeholder="'이름을 입력하세요' />
</el-form-item>
<el-form-item label="age" prop="age">
<el-input v-model="formData.age" placeholder="'나이를 입력하세요' />
</el-form-item>
<el-form-item label="gender" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio :label="1"> </el-radio>
<el-radio :label="2"> </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="메일박스" 소품="email">
<el-input v-model="formData.email" placeholder="이메일을 입력하세요" />
</el-form-item>
<el-form-item label="정렬" 소품="sort" placeholder="정렬 번호를 입력하세요 ">
<el-input-number v-model="formData.sort" :min="1" />
</el-form-item>
</div>
<div class="form-top--right">
<el-form-item label="노트" 소품="remark">
<el-input
v-model="formData.remark"
type="textarea"
placeholder="댓글을 입력하세요 "
maxlength="100"
show-word-limit
resize="none"
/>
</el-form-item>
<el-form-item label="설명" prop="config">
<el-input
v-model="formData.config"
placeholder="설명을 입력하세요 "
type="textarea"
show-word-limit
maxlength="200"
:autosize="{ minRows: 6, maxRows: 6 }"
/>
</el-form-item>
</div>
</div>
<div class="form-bottom">
<el-form-item>
<el-button type="primary" @click="handleSubmit"> </el-button>
<el-button type="warning" @click="handleClose"> </el-button>
</el-form-item>
</div>
</el-form>
</template>
<script setup lang="ts">
const formRef = ref();
const formData = reactive({
remark: "",
age: 10,
config: "",
email: "",
sex: "",
id: null,
name: "",
sort: 0,
});
const handleClose = () => {};
const handleSubmit = () => {};
</script>
<style lang="scss" scoped>
.container {
width: 600px;
margin-top: 100px;
.form-top {
display: flex;
justify-content: space-between;
.form-top--right {
flex: 1;
}
}
.form-bottom {
display: flex;
justify-content: flex-end;
}
}
</style>
이러한 두뇌없는 구현은 투자 한 시간에 대해 정말 죄송하며 부드러운 재사용 성이 가장 큰 문제가 아닙니다.
Expand
엘폼 캡슐화, 슬롯 추가
// Form.vue
<template>
<el-form>
<slot></slot>
<div class="form-top" v-if="!slot.default">
<div class="form-top--left" v-if="slot.left">
<slot name="left"></slot>
</div>
<div class="form-top--right" v-if="slot.right">
<slot name="right"></slot>
</div>
</div>
<div class="form-bottom" v-if="slot.bottom">
<slot name="bottom"></slot>
</div>
</el-form>
</template>
<script setup lang="ts">
const slot = useSlots();
</script>
<style lang="scss" scoped>
.form-top {
display: flex;
justify-content: space-between;
.form-top--left {
flex: 1;
}
.form-top--right {
flex: 1;
}
}
.form-bottom {
display: flex;
justify-content: flex-end;
}
</style>
// index.vue
<template>
<Form ref="formRef" :model="formData" label-width="80px">
<template #left>
<el-form-item label="이름" 소품="name">
<el-input v-model="formData.name" placeholder="'이름을 입력하세요' />
</el-form-item>
<el-form-item label="age" prop="age">
<el-input v-model="formData.age" placeholder="'나이를 입력하세요' />
</el-form-item>
<el-form-item label="gender" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio :label="1"> </el-radio>
<el-radio :label="2"> </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="메일박스" 소품="email">
<el-input v-model="formData.email" placeholder="'이메일을 입력하세요' />
</el-form-item>
<el-form-item label="정렬" 소품="sort" placeholder="정렬 번호를 입력하세요 ">
<el-input-number v-model="formData.sort" :min="1" />
</el-form-item>
</template>
<template #right>
<el-form-item label="노트" 소품="remark">
<el-input
v-model="formData.remark"
type="textarea"
placeholder="댓글을 입력하세요 "
maxlength="100"
show-word-limit
resize="none"
/>
</el-form-item>
<el-form-item label="설명" prop="config">
<el-input
v-model="formData.config"
placeholder="설명을 입력하세요 "
type="textarea"
show-word-limit
maxlength="200"
:autosize="{ minRows: 6, maxRows: 6 }"
/>
</el-form-item>
</template>
<template #bottom>
<el-form-item>
<el-button type="primary" @click="handleSubmit"> </el-button>
<el-button type="warning" @click="handleClose"> </el-button>
</el-form-item>
</template>
</Form>
</template>
<script setup lang="ts">
import Form from "./Form.vue";
const formRef = ref();
//사람 양식 추가하기
const formData = reactive({
remark: "",
age: 10,
config: "",
email: "",
sex: "",
id: null,
name: "",
sort: 0,
});
const handleClose = () => {};
const handleSubmit = () => {};
</script>
<style lang="scss" scoped>
.form-top {
display: flex;
justify-content: space-between;
.form-top--right {
flex: 1;
}
}
.form-bottom {
display: flex;
justify-content: flex-end;
}
</style>
레이아웃이 고정되어 있고 다른 레이아웃을 원하면 Form.vue를 수정하거나 다시 패키징해야 하기 때문에 여전히 충분히 다양하지 않습니다.
계속 확장
레이아웃을 추출하고, Layout.vue 컴포넌트를 구성하고, 조상 기술 슬롯 패스 // Layout.vue를 꺼냅니다.
<template>
<div>
<slot></slot>
<div class="form-top" v-if="!slot.default">
<div class="form-top--left" v-if="slot.left">
<slot name="left"></slot>
</div>
<div class="form-top--right" v-if="slot.right">
<slot name="right"></slot>
</div>
</div>
<div class="form-bottom" v-if="slot.bottom">
<slot name="bottom"></slot>
</div>
</div>
</template>
<script setup lang="ts">
const slot = useSlots();
</script>
<style lang="scss" scoped>
.form-top {
display: flex;
justify-content: space-between;
.form-top--left {
flex: 1;
}
.form-top--right {
flex: 1;
}
}
.form-bottom {
display: flex;
justify-content: flex-end;
}
</style>
// Form.vue
<template>
<el-form>
<Layout>
<template v-for="item in Object.keys(slot)" :key="item" #[item]>
<slot :name="item"></slot>
</template>
</Layout>
</el-form>
</template>
<script setup lang="ts">
import Layout from "./Layout.vue";
const slot = useSlots();
</script>
<style lang="scss" scoped></style>
// index.vue
<template>
<Form ref="formRef" :model="formData" label-width="80px">
<template #left>
<el-form-item label="이름" 소품="name">
<el-input v-model="formData.name" placeholder="'이름을 입력하세요' />
</el-form-item>
<el-form-item label="age" prop="age">
<el-input v-model="formData.age" placeholder="'나이를 입력하세요' />
</el-form-item>
<el-form-item label="gender" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio :label="1"> </el-radio>
<el-radio :label="2"> </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="메일박스" 소품="email">
<el-input v-model="formData.email" placeholder="이메일을 입력하세요" />
</el-form-item>
<el-form-item label="정렬" 소품="sort" placeholder="정렬 번호를 입력하세요 ">
<el-input-number v-model="formData.sort" :min="1" />
</el-form-item>
</template>
<template #right>
<el-form-item label="노트" 소품="remark">
<el-input
v-model="formData.remark"
type="textarea"
placeholder="댓글을 입력하세요 "
maxlength="100"
show-word-limit
resize="none"
/>
</el-form-item>
<el-form-item label="설명" prop="config">
<el-input
v-model="formData.config"
placeholder="설명을 입력하세요 "
type="textarea"
show-word-limit
maxlength="200"
:autosize="{ minRows: 6, maxRows: 6 }"
/>
</el-form-item>
</template>
<template #bottom>
<el-form-item>
<el-button type="primary" @click="handleSubmit"> </el-button>
<el-button type="warning" @click="handleClose"> </el-button>
</el-form-item>
</template>
</Form>
</template>
<script setup lang="ts">
import Form from "./Form.vue";
const formRef = ref();
//사람 양식 추가하기
const formData = reactive({
remark: "",
age: 10,
config: "",
email: "",
sex: "",
id: null,
name: "",
sort: 0,
});
const handleClose = () => {};
const handleSubmit = () => {};
</script>
<style lang="scss" scoped>
.form-top {
display: flex;
justify-content: space-between;
.form-top--right {
flex: 1;
}
}
.form-bottom {
display: flex;
justify-content: flex-end;
}
</style>
요약하자면
레이아웃 및 데이터 분리
유연한 확장 레이아웃
2.1 여러 레이아웃 파일을 만들어 Form.vue로 일괄 처리할 수 있으며, Form.vue는 동적 구성 요소 구성 요소를 사용하여 각 레이아웃 파일을 로드합니다.
2.2 여러 레이아웃 파일을 생성하여 LayoutIndex.vue 파일에 일괄 도입할 수 있습니다. LayoutIndex.vue 파일은 동적 컴포넌트를 사용하여 각 레이아웃 파일을 로드한 다음 Form.vue는 레이아웃 인덱스만 렌더링하고 파라미터를 전달하여 어떤 레이아웃을 렌더링할지 결정합니다.
새 레이아웃을 추가할 때는 새 파일만 추가하면 되며, 이는 '열기와 닫기'의 원칙에 부합합니다.





