简介
文章主要讲述在vue3项目中使用elementui框架实现复杂表单的方式。表单中涉及动态组件的生成、文件上传和富文本编辑器的使用,只会将在实现过程中较复杂的部分进行分享,然后提供一份完整的前端代码。
表单效果演示
基础信息
spu属性
sku详情
关键点
动态组件的处理
在spu属性步骤中,CPU型号、操作系统和生物解锁三个属性都是动态生成的。
实现原理
组件动态生成和删除的原理是通过操作v-for组件的数据源实现的。向数据源添加数据会动态生成组件,将数据源的数据减少就会删除对应的组件。
所以在点击添加属性时,只要向v-for的数据源中添加属性配置,就能实现动态生成组件的效果。
组件的类型、可选值都是提前定义的。
分析JD、淘宝等各类商城关于spu属性的展示,可以发现基本可以用自定义、单选和多选属性把所有spu属性覆盖。
因此就可以提前将商品可用的属性按类型和可选值完成定义,在页面选择对应属性添加到页面即可。
动态添加spu属性的代码
只需要重点关注 addSpuItem、rmAttr 方法和 v-for="(dynamicSpu, dspuK) in state.auxiliaries.optional.attr.spu.dynamicItems"
<el-form-item label="选择属性">
<el-select filterable v-model="state.auxiliaries.optional.attr.spu.dynamic"
style="display: inline-block;width: 198px">
<el-option label="请选择" :value="0"></el-option>
<el-option v-for="(spuAttr, spuK) in state.auxiliaries.optional.attr.list" :key="spuK" :label="spuAttr.name"
:value="spuAttr.attrId"></el-option>
</el-select>
<el-divider direction="vertical" border-style="none" />
<el-button type="primary" @click="addSpuItem">添加规格属性</el-button>
</el-form-item>
<el-form-item v-for="(dynamicSpu, dspuK) in state.auxiliaries.optional.attr.spu.dynamicItems" :key="dspuK"
:label="dynamicSpu.name">
<el-input v-model="dynamicSpu.selectedValue" v-if="dynamicSpu.type === 'CUSTOM'"
style="max-width: 40%"></el-input>
<el-radio-group v-model="dynamicSpu.selectedValue" v-else-if="dynamicSpu.type === 'SINGLE'">
<el-radio v-for="(dspuAttr, dspuaK) in dynamicSpu.value" :key="dspuaK" :label="dspuAttr">{
{ dspuAttr
}}</el-radio>
</el-radio-group>
<el-checkbox-group v-model="dynamicSpu.selectedValue" v-else-if="dynamicSpu.type === 'MULTIPLE'">
<el-checkbox v-for="(dspumAttr, dspumK) in dynamicSpu.value" :key="dspumK" :label="dspumAttr"
:value="dspumAttr"></el-checkbox>
</el-checkbox-group>
<el-divider direction="vertical"></el-divider>
<el-button type="danger" @click="rmAttr('spu', dspuK)" size="small">删除</el-button>
</el-form-item>
向spu数据源添加元素
主要是向 state.auxiliaries.optional.attr.spu.dynamicItems 这个数组中追加元素
// 动态生成SPU条目
const addSpuItem = () => {
if (state.value.auxiliaries.optional.attr.spu.dynamic === 0) {
ElMessage.error("请选择一个属性")
return
}
// 已选择的SPU属性
for (let i = 0; i < state.value.auxiliaries.optional.attr.list.length; i++) {
if (state.value.auxiliaries.optional.attr.list[i].attrId === state.value.auxiliaries.optional.attr.spu.dynamic) {
// 利用JSON实现简单对象的深拷贝
let dynamicItem = JSON.parse(JSON.stringify(state.value.auxiliaries.optional.attr.list[i]))
dynamicItem.selectedValue = []
state.value.auxiliaries.optional.attr.spu.dynamicItems.push(dynamicItem)
}
}
}
删除动态组件
将对应数据源的元素删除,就可以实现动态删除生成的组件
const rmAttr = (type: string, idx: number) => {
if (type === "spu") {
// 删除动态添加的SPU属性
state.value.auxiliaries.optional.attr.spu.dynamicItems.splice(idx, 1)
return
}
if (type === "sku") {
state.value.auxiliaries.optional.attr.sku.dynamicItems.splice(idx, 1)
}
}
文件上传组件的使用
在sku部分有上传组件的使用。
利用elementUI提供的组件实现,相对来说没有什么难度。由于是动态组件,每个上传文件的组件要设置一个单独的参数接收数据,避免出现数据覆盖的情况。
<!-- 商品轮播图 -->
<el-form-item label="商品轮播图" label-width="120">
<el-upload v-model:file-list="state.auxiliaries.configs.upload.coversForm[dDetailItemK].covers"
action="http://localhost:9900/upload/cover" multiple :headers="state.auxiliaries.configs.upload.headers"
:on-success="handleUploadCoverSuccess" :on-error="handleUploadCoverFailed" method="post"
list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove">
<el-icon>
<Plus />
</el-icon>
</el-upload>
</el-form-item>
主要用到了组件的action、headers属性。action设置上传文件的接口、headers设置调用接口时必要的请求头
定义headers
一般项目都是前后端分离的,headers通常设置调用接口的token等身份认证信息。
const state = ref({
auxiliaries: {
configs: {
upload: {
headers: {
Authorization: "Bearer " + Session.get('token')
},
coversForm: [] as Array<any>
}
}
}
})
动态使用富文本编辑器
富文本编辑器使用的是tinymce,特点就是轻量、简洁。具体使用教程可以看这里。
动态的富文本编辑器实现原理与上传组件一样,区别就是在获取富文本编辑器中的内容的方式有所不同。
在vue3中富文本编辑器的组件需要设置ref属性,在获取编辑器的内容时需要通过ref获取到编辑器的实例,然后再获取内容。
<template>
<!-- 商详 -->
<el-form-item v-for="(dynamicSku, dskuK) in state.auxiliaries.optional.attr.sku.dynamicItems"
:key="dskuK" label="商品详情" label-width&