image-20230104123514646
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!-- 对话框组件:在添加品牌与修改已有品牌的业务时候使用结构 -->
<!--
v-model:属性用户控制对话框的显示与隐藏的 true显示 false隐藏
title:设置对话框左上角标题
trademarkParams:对话框中的参数标题和图片
-->
<el-dialog
v-model="dialogFormVisible"
:title="trademarkParams.id ? '修改品牌' : '添加品牌'"
>
<el-form
style="width: 80%"
:model="trademarkParams"
:rules="rules"
ref="formRef"
>
<el-form-item label="品牌名称" label-width="100px" prop="tmName">
<el-input
placeholder="请您输入品牌名称"
v-model="trademarkParams.tmName"
></el-input>
</el-form-item>
<el-form-item label="品牌LOGO" label-width="100px" prop="logoUrl">
<!-- upload组件属性:action图片上传路径书写/api,代理服务器不发送这次post请求 -->
<el-upload
class="avatar-uploader"
action="/api/admin/product/fileUpload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img
v-if="trademarkParams.logoUrl"
:src="trademarkParams.logoUrl"
class="avatar"
/>
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
</el-form-item>
</el-form>
<!-- 具名插槽:footer -->
<template #footer>
<el-button type="primary" size="default" @click="cancel">
取消
</el-button>
<el-button type="primary" size="default" @click="confirm">
确定
</el-button>
</template>
</el-dialog>

通过两种方式来控制对话框组件的展开与否:

通过添加品牌按钮来打开对话框:

1
2
3
4
5
6
7
8
9
<el-button
type="primary"
size="default"
icon="Plus"
@click="addTrademark"
v-has="`btn.Trademark.add`"
>
添加品牌
</el-button>

通过编辑品牌来打开对话框

1
2
3
4
5
6
<el-button
type="primary"
size="small"
icon="Edit"
@click="updateTrademark(row)"
></el-button>

其中addTrademark函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//添加品牌按钮的回调
const addTrademark = () => {
//对话框显示
dialogFormVisible.value = true
//清空收集数据
trademarkParams.id = 0 //用来控制对话框展示是添加品牌还是修改品牌
trademarkParams.tmName = ''
trademarkParams.logoUrl = ''
//第一种写法:ts的问号语法
// formRef.value?.clearValidate('tmName');
// formRef.value?.clearValidate('logoUrl');
nextTick(() => {
formRef.value.clearValidate('tmName')
formRef.value.clearValidate('logoUrl')
})
}

updateTrademark(row)函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//修改已有品牌的按钮的回调
//row:row即为当前已有的品牌
const updateTrademark = (row: TradeMark) => {
//清空校验规则错误提示信息
nextTick(() => {
formRef.value.clearValidate('tmName')
formRef.value.clearValidate('logoUrl')
})
//对话框显示
dialogFormVisible.value = true
//ES6语法合并对象
Object.assign(trademarkParams, row)
}

图片长传成功的回调函数:

1
2
3
4
5
6
7
8
9
10
11
//图片上传成功钩子
const handleAvatarSuccess: UploadProps['onSuccess'] = (
response,
uploadFile,
) => {
//response:即为当前这次上传图片post请求服务器返回的数据
//收集上传图片的地址,添加一个新的品牌的时候带给服务器
trademarkParams.logoUrl = response.data
//图片上传成功,清除掉对应图片校验结果
formRef.value.clearValidate('logoUrl')
}

上传图片组件->上传图片之前触发的钩子函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//上传图片组件->上传图片之前触发的钩子函数
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
//钩子是在图片上传成功之前触发,上传文件之前可以约束文件类型与大小
//要求:上传文件格式png|jpg|gif 4M
if (//文件限制
rawFile.type == 'image/png' ||
rawFile.type == 'image/jpeg' ||
rawFile.type == 'image/gif'
) {
if (rawFile.size / 1024 / 1024 < 4) {//大小限制
return true
} else {
ElMessage({
type: 'error',
message: '上传文件大小小于4M',
})
return false
}
} else {
ElMessage({
type: 'error',
message: '上传文件格式务必PNG|JPG|GIF',
})
return false
}
}

表单规则如下:

1
2
3
4
5
6
7
8
9
//表单校验规则对象
const rules = {
tmName: [
//required:这个字段务必校验,表单项前面出来五角星
//trigger:代表触发校验规则时机[blur、change]
{ required: true, trigger: 'blur', validator: validatorTmName },
],
logoUrl: [{ required: true, validator: validatorLogoUrl }],
}

规则函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//品牌自定义校验规则方法
const validatorTmName = (rule: any, value: any, callBack: any) => {
//是当表单元素触发blur时候,会触发此方法
//自定义校验规则
if (value.trim().length >= 2) {
callBack()
} else {
//校验未通过返回的错误的提示信息
callBack(new Error('品牌名称位数大于等于两位'))
}
}
//品牌LOGO图片的自定义校验规则方法
const validatorLogoUrl = (rule: any, value: any, callBack: any) => {
//如果图片上传
if (value) {
callBack()
} else {
callBack(new Error('LOGO图片务必上传'))
}
}

其中确认按钮回调函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const confirm = async () => {
//在你发请求之前,要对于整个表单进行校验
//调用这个方法进行全部表单相校验,如果校验全部通过,在执行后面的语法
await formRef.value.validate() //先进行表单验证
let result: any = await reqAddOrUpdateTrademark(trademarkParams)
//添加|修改已有品牌
if (result.code == 200) {
//关闭对话框
dialogFormVisible.value = false
//弹出提示信息
ElMessage({
type: 'success',
message: trademarkParams.id ? '修改品牌成功' : '添加品牌成功',
})
//再次发请求获取已有全部的品牌数据
getHasTrademark(trademarkParams.id ? pageNo.value : 1)
} else {
//添加品牌失败
ElMessage({
type: 'error',
message: trademarkParams.id ? '修改品牌失败' : '添加品牌失败',
})
//关闭对话框
dialogFormVisible.value = false
}
}

修改请求接口如下:

1
2
3
4
5
6
7
8
9
10
//添加与修改已有品牌接口方法
export const reqAddOrUpdateTrademark = (data: TradeMark) => {
//修改已有品牌的数据
if (data.id) {
return request.put<any, any>(API.UPDATETRADEMARK_URL, data)
} else {
//新增品牌
return request.post<any, any>(API.ADDTRADEMARK_URL, data)
}
}

取消按钮如下:

1
2
3
4
5
//对话框底部取消按钮
const cancel = () => {
//对话框隐藏
dialogFormVisible.value = false
}