配合keep-alive组件使用
<template>
2 <div id="app">
3 <button @click="changeComponent">切换组件</button>
4 <keep-alive>
5 <component :is="currentComponent"></component>
6 </keep-alive>
7 </div>
8</template>
配合v-for使用即可实现循环遍历组件的作用,在多步骤表单业务(跨页面跨组件表单校验)代码中,用于提升组件的抽离程度
<template>
<div>
<div>
<el-steps
:active="currentStep"
finish-status="success"
>
<el-step
finish-status="success"
:title="item.title"
v-for="(item, index) in componentsList"
:key="item.index"
></el-step>
</el-steps>
<component
v-for="(item, index) in componentsList"
:is="item.is"
:key="index"
v-show="item.isshow"
:ref="`stepForm${item.name}`"
></component>
<el-button
style="margin-top: 12px"
@click="next"
>
下一步
</el-button>
<el-button @click="submitForm">提交</el-button>
</div>
</div>
</template>
<script>
const obj = {
1: 'child1',
2: 'child2'
}
import child1 from './componennts/child1.vue'
import child2 from './componennts/child2.vue'
export default {
components: {
child1,
child2
},
data() {
return {
is: 'child1',
componentsList: [
{
title: '步骤一',
name: 1,
is: 'child1',
isshow: true
},
{
title: '步骤二',
name: 2,
is: 'child2',
isshow: false
}
],
currentStep: 1
}
},
watch: {
currentStep(value) {
this.componentsList.forEach((element, index) => {
element.isshow = index + 1 === value
})
console.log(this.componentsList, ' this.componentsList')
}
},
methods: {
handleClick() {},
next() {
this.currentStep++
if (this.currentStep > 2) {
this.currentStep = 1
}
this.is = obj[this.currentStep]
},
async submitForm() {
const formDataArray = []
let isValid = true
for (let step of this.componentsList) {
const stepRefName = `stepForm${step.name}`
const componentInstance = this.$refs[stepRefName]
console.log(componentInstance, 'componentInstance')
if (componentInstance && componentInstance[0].validate) {
const validateResult = await componentInstance[0].validate()
if (!validateResult) {
isValid = false
break
}
} else {
console.warn(`Component ${stepRefName} validation method not found.`)
}
}
const allFormData = formDataArray.reduce(
(acc, curr) => ({ ...acc, ...curr }),
{}
)
}
}
}
</script>
<template>
<div>
<h1>子组件一</h1>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm1"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item
label="活动名称"
prop="name"
>
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item
label="活动区域"
prop="region"
>
<el-select
v-model="ruleForm.region"
placeholder="请选择活动区域"
>
<el-option
label="区域一"
value="shanghai"
></el-option>
<el-option
label="区域二"
value="beijing"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label="活动时间"
required
>
<el-col :span="11">
<el-form-item prop="date1">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="ruleForm.date1"
style="width: 100%"
></el-date-picker>
</el-form-item>
</el-col>
<el-col
class="line"
:span="2"
>
-
</el-col>
<el-col :span="11">
<el-form-item prop="date2">
<el-time-picker
placeholder="选择时间"
v-model="ruleForm.date2"
style="width: 100%"
></el-time-picker>
</el-form-item>
</el-col>
</el-form-item>
<el-form-item
label="即时配送"
prop="delivery"
>
<el-switch v-model="ruleForm.delivery"></el-switch>
</el-form-item>
<el-form-item
label="活动性质"
prop="type"
>
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox
label="美食/餐厅线上活动"
name="type"
></el-checkbox>
<el-checkbox
label="地推活动"
name="type"
></el-checkbox>
<el-checkbox
label="线下主题活动"
name="type"
></el-checkbox>
<el-checkbox
label="单纯品牌曝光"
name="type"
></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item
label="特殊资源"
prop="resource"
>
<el-radio-group v-model="ruleForm.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label="活动形式"
prop="desc"
>
<el-input
type="textarea"
v-model="ruleForm.desc"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="submitForm('ruleForm')"
>
立即创建
</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
ruleForm: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
date1: [
{
type: 'date',
required: true,
message: '请选择日期',
trigger: 'change'
}
],
date2: [
{
type: 'date',
required: true,
message: '请选择时间',
trigger: 'change'
}
],
type: [
{
type: 'array',
required: true,
message: '请至少选择一个活动性质',
trigger: 'change'
}
],
resource: [
{ required: true, message: '请选择活动资源', trigger: 'change' }
],
desc: [{ required: true, message: '请填写活动形式', trigger: 'blur' }]
}
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!')
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
submit() {},
validate() {
return this.$refs['ruleForm1'].validate((valid) => {
return valid
})
}
}
}
</script>
在封装表单组件的时候,通过components可以传递组件的位置给表单组件,表单组件通过import动态引入,通过default属性的值,通过is属性进行展示(这里以vue2为例)