一、组件篇html
列表demo文件 /suppler/lamManage/productModelList
图片懒加载
<img v-lazy="'/image/banner/shengtai@2x.png'" />
<div v-lazy:background-image="{src:item.map[1].bannerResUrl}"></div>
组件插槽 用slot
<div class="note"
slot="label">
{{ item.introName}}
<i v-if="item.subIntro">({{item.subIntro}})</i>
</div>
链接加权限
<router-link tag="a"
tableLink="true"
v-validate="'btn-view'"
class="bottomline"
href="javascript:void(0)"
:to="`/suppler/lamManage/productModelList/detail?id=${scope.row.appId}&status=1`">
{{ scope.row.appName }}
</router-link>
表格table
<el-table
style="width: 700px"
v-loading="listLoading"
border
:data="list"
default-expand-all
:element-loading-text="elementLoadingText"
row-key="path"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column show-overflow-tooltip type="selection" />
<el-table-column prop="crtDate"
label="上传时间"
width="160"
align="center">
<template slot-scope="scope">
{{ scope.row.crtDate | dateAllfilter}}
</template>
</el-table-column>
<el-table-column label="重定向" prop="redirect" show-overflow-tooltip align="center"/>
<el-table-column label="标题" prop="meta.title" show-overflow-tooltip />
<el-table-column label="图标" show-overflow-tooltip>
<template #default="{ row }">
<span v-if="row.meta">
<vab-icon v-if="row.meta.icon" :icon="['fas', row.meta.icon]" />
</span>
</template>
</el-table-column>
<el-table-column label="操作" show-overflow-tooltip width="200">
<template #default="{ row }">
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
弹窗el-dialog
<el-dialog title="新建产品系列"
customClass="plusAppNameDialog"
:visible.sync="dialogVisible"
:closeOnClickModal="false"
@close="dialogVisible = false"
width="500px" >
<span slot="footer"
class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary"
@click="handleAddAppSeries('ruleForm')">确 定</el-button>
</span>
</el-dialog>
表单form
<el-form :model="formObj" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" @submit.native.prevent>
<el-form-item label="上传附件:"
prop="resId">
<upload-file :fileCustom="fileInfo"
@callback="getFileInfo"></upload-file>
</el-form-item>
<el-form-item label="研发团队人数:" prop="developmenTeamNum">
<span v-if="isRead">{{formObj.developmenTeamNum}}</span>
// 数字
<el-input v-else size="small"
style="width: 340px"
v-model.number="formObj.developmenTeamNum"
maxlength="10"
placeholder="请输入研发团队人数"
clearable>
</el-input>
// 文字
<el-input size="medium"
style="width: 340px"
v-model.trim="formObj.appName"
placeholder="请输入初步拟定的产品名称"
maxlength="20"
show-word-limit clearable>
</el-input>
</el-form-item>
<span slot="footer"
class="dialog-footer">
<el-button @click="$router.go(-1)">返回</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary"
@click="handleComfirmUpdate('ruleForm')">确 定</el-button>
</span>
</el-form>
输入框input
第一个输入框可以设置一个指令 v-focus属性,提前聚焦,也可以加上 tabindex="1" (https://blog.csdn.net/cui_angel/article/details/7677491)
<el-input v-model.trim="form.username" v-focus placeholder="请输入用户名"
tabindex="1" type="text" />
<el-input
size="medium"
style="width: 340px"
v-model.trim="formObj.appName"
placeholder="请输入初步拟定的产品名称"
maxlength="20"
show-word-limit
clearable>
</el-input>
<span><span> 详情展示 设置css属性 white-space: pre-wrap
<el-input
type="textarea"
:rows="5"
size="small"
style="width: 340px"
v-model.trim="formObj.appName"
placeholder="请输入初步拟定的产品名称"
maxlength="100"
show-word-limit
clearable>
</el-input>
选择框radio/checkbox/select
<el-radio-group v-model="formObj.productFormId">
<el-radio v-for="(obj,index) in productForm"
:label="obj.fid" :key="index + 'productFormt'">{{ obj.fname }}
</el-radio>
</el-radio-group>
<el-radio-group v-model="formObj.hasCustomer">
<el-radio label="0">否</el-radio>
<el-radio label="1">是</el-radio>
</el-radio-group>
<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-select size="small"
style="width: 90%"
v-else
v-model="formObj.position"
placeholder="请选职务(必填)"
clearable>
<el-option label="总经理" value="1"></el-option>
<el-option label="业务负责人" value="2"></el-option>
<el-option label="其他" value="3"></el-option>
</el-select>
封装组件上传
// category: 'docs', // 上传时的组件样式分类 (图片,文档,头像 )与class一一对应
// type: '', // 上传文件类型(pdf,png)
// unlimitType: true // 上传不限制类型
// size: 100, // 上传大小 单位兆
// name: '上传安装包', // 组件展示的文字
// class: 'docs-uploader', // 上传时的组件样式class
// list: [], // 上传的列表
// cat: 'xxx', // 在服务端保存的文件夹名字
// subfolder: id , // 在服务端保存的子文件夹名字
// cat: 'package/:id', 上传文件包
// cat: 'applogo' 上传应用logo
// cat: 'samplecust' 上传样板客户里面的图片
// cat: 'contract', 上传购买合同 , 里程上传凭证,卖家上传委托书
// cat: 'idCard' 上传身份证验证图片
// cat: 'transferVoucher' 客户转账凭证
// cat: 'PDLogo' 上传test
[图片上传失败...(image-58ee57-1734332820905)]
[图片上传失败...(image-21fb7d-1734332820905)]
:customeDelete="true" 是否删除文件
<upload-file :customeDelete="true" :fileCustom="fileInfo" @callback="getFileInfo"></upload-file>
fileInfo: {
category: 'docs',
type: 'ppt/pptx',
size: 100,
name: '上传文件',
class: 'agreement-uploader',
list: [],
cat: 'contract',
unlimitType: false,
},
getFileInfo (name, id, _url) {
this.formObj.roadmapResId = id
this.$refs['formName'].clearValidate('roadmapResId')
},
el-upload上传
<el-upload :action="`/api/app/uploadPassAppPatchObjects?cat=lamManage`"
:data="{deploymentType:'DT003',appId:formObj.appId}"
:on-success="handleSuccess"
:on-remove="handleRemove"
accept=".xml,.xls,.xlsx"
:multiple="false"
:limit="0"
:file-list="fileList">
<el-button size="small"
type="primary">点击上传</el-button>
</el-upload>
handleRemove (file, fileList) {
// console.log(file, fileList)
this.formObj.productModelJsonId = ''
this.fileList = []
},
handleSuccess (file, fileList) {
let { fileName, productModelJsonId } = file?.data
console.log(file, fileList)
if (file.code === 0) {
this.$refs['ruleForm'].clearValidate('resId')
this.formObj.productModelJsonId = productModelJsonId
this.fileList = [{ name: fileName, id: productModelJsonId }]
} else {
this.fileList = []
this.$message.warning(file.msg)
}
},
下载
<p @click="getDocDownloadInfo(dataInfo.initRoadmapUrl)">下载模板</p>
getDocDownloadInfo (url) {
if (url) {
this.layerglobal.downfile(url)
} else {
this.$message.warning('下载资源不存在,请上传模板后再下载')
}
},
日期date
<el-form-item label="许可授权日期:"
prop="flicenseTime">
<el-date-picker type="daterange"
range-separator="-"
style="width:340px"
format="yyyy-MM-dd"
value-format="timestamp"
v-model="formObj.flicenseTime"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"
clearable
@change="onChangeLicenseTime"
:disabled="isDisabled">
</el-date-picker>
</el-form-item>
pickerOptions: {
disabledDate (time) {
return time.getTime() < Date.now() - 3600 * 24 * 1000
}
},
pickerOptions () {
let obj = {
disabledDate: (time) => {
if (this.formObj.flicenseTime && this.formObj.flicenseTime) {
return time.getTime() < this.formObj.flicenseTime[0] || time.getTime() > this.formObj.flicenseTime[1]
} else {
return false
}
},
}
return obj
},
计数器
<el-input-number v-if="isUpdate || !status"
v-model="obj.totalUserNum"
:min="1"
:step="1"
:step-strictly="true"
size="small"
label="描述文字">
</el-input-number>
二、参数方法
rules
行内校验
<el-form-item label="开发团队:"
prop="developmenTeam"
:rules="[{ required: true, message: '请选择开发团队', trigger: 'blur' }]">
<el-select v-model="formObjContent.developmenTeam"
placeholder="请选择开发团队"
style="width:300px"
size="medium"
@change="handleChangeSuppler"
clearable>
<el-option v-for="item in supplerList"
:key="item.tid"
:label="item.name"
:value="item.tid">
</el-option>
</el-select>
</el-form-item>
rules: {
customerNumber: [
{ required: true, message: "请输入企业人数", trigger: "blur" },
{ type: 'number', message: '人数必须为数字值'}
{ pattern: /^[1-9]\d*$/, message: '企业人数必须为正整数', trigger: 'blur' },
{ type: 'email', message: '账户名应为邮箱格式', trigger: ['blur', 'change'] },
{ pattern: /^(\d+)((?:\.\d+)?)$/, message: '请输入合法金额数字',trigger: "blur" },
],
appName: [
{ required: true, message: "请输入产品名称", trigger: "blur" },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
电话为手机号或座机0745-1234567(8)
contactPhone: [
{ required: true, message: "请输入联系电话", trigger: "blur" },
{ pattern: /^(1\d{10}|(\d{4}-)(\d{8}|\d{7}))$/, message: "请填写正确的", trigger: "blur" },
],
domainIdList: [
{ required: true, message: "请选择领域", trigger: "change" },
],
plannedReleaseTime: [
{ type: 'date', required: true, message: "请选择计划发布日期", trigger: "change" },
],
hasCustomer: [
{ required: true, message: "请选择是否有原型客户", trigger: "blur" },
],
type: [
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
],
这是image文件类型
roadmapResId: [
{ required: true, message: "请上传产品规划方案", trigger: "change" }
],
新增
handleAddFeature () {
this.$refs['featureForm']?.resetFields()
this.dialogVisibleFeature = true
this.formObj = {
modelName: '',
modelNumber: '',
priceType: 'PIT001'
}
},
编辑
handleEditFeature (obj, val, index) {
this.$refs['featureForm']?.clearValidate()
this.operate = val
this.dialogVisibleFeature = true
this.featureObj = _.cloneDeep(obj)
this.editFeatureIndex = index
},
删除
handleDeleteGroup (index, name) {
this.$confirm(`确定删除分组【${name}】及对应模块?`, "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
closeOnClickModal: false,
}).then(() => {
this.groupList.splice(index, 1)
})
},
基本请求方法
handleSoldOutProduct (obj) {
this.$confirm(`确定作废产品【${obj.appName}】?`, "作废提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
closeOnClickModal: false,
}).then(() => {
this.supplierDownPassApp({ appId: obj.appId }).then((res) => {
this.partnerGetclick()
this.$message.success('产品作废成功')
}).catch((res) => {
this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetIndex", })
})
}).catch(() => { })
},
init
init (supplierId, id) {
this.basicDataWithValidInfo({ supplierId }).then((res) => {
this.basicData = res.data
this.getProjectApprovalDetail({ id }).then((res) => {
this.dataInfo = res.data
// 编辑
if (id) {
this.formObj.id = res.data.id
let { roadmapName: name, roadmapResId, roadmapResUrl: _url } = res.data
if (id && roadmapResId) {
this.fileInfo.list = [{ name, id: roadmapResId, _url }]
this.formObj.roadmapResId = roadmapResId
}
}
}).catch((res) => {
this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
})
}).catch((res) => {
this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
})
},
编辑弹窗取消逻辑
close() {
this.$refs['form']?.resetFields()
this.form = this.$options.data().form
this.dialogFormVisible = false
},
save() {
this.$refs['form'].validate(async (valid) => {
if (valid) {
const { msg } = await doEdit(this.form)
this.$baseMessage(msg, 'success')
this.$emit('fetch-data')
this.close()
} else {
return false
}
})
},
提交保存
submitForm (auditStatus) {
this.$message.closeAll()
let obj = { ...this.formObj }
if (this.formObj.hasCustomer === '0') {
delete obj.customerName
}
if (auditStatus === 'save') {
this.btnloading.savebtn = true
this.saveProjectApproval(obj).then((res) => {
if (res.code === 0) {
this.btnloading.savebtn = false
this.$message.success('保存成功')
this.$router.push('/suppler/projectManagement/list')
}
}).catch((res) => {
this.btnloading.savebtn = false
this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
})
} else {
this.$refs["formName"].validate((valid) => {
if (valid) {
this.btnloading.savebtn = true
this.submitProjectApproval(obj).then((res) => {
if (res.code === 0) {
this.btnloading.savebtn = false
this.$message.success('提交成功')
this.$router.push('/suppler/projectManagement/list')
}
}).catch((res) => {
this.btnloading.savebtn = false
this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
})
}
})
}
},
提交弹窗
this.$confirm(`<p style="font-size:15px;margin-top:20px;">请先前往开发者门户获取开发商标识,
再新建产品!</p>`, "提示",
{
customClass: 'confirmMessagePop',
confirmButtonText: "获取会员资质",
cancelButtonText: "取消",
type: "warning",//不要icon可以删除这个
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
width: 600
}
).then(() => {
this.$router.push({ name: "supplierInfo", query: { isneedskipmemberinfo: true } })
}).catch(() => { })
this.$prompt(``, '驳回变更申请', {
customClass: "delayDevlicensePop",//报错提示居左,去掉就居中
dangerouslyUseHTMLString: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
center: true,//标题居中
inputType: 'textarea',
inputPattern: /^.{1,50}$/,
inputErrorMessage: '延期理由应在1~50个字内!',
inputPlaceholder: '请输入延期理由,不超过50个字符'
}).then((obj) => {
const { id } = this.$route.params
this.kingdeeOperateAppChange({ appChangeId: id, auditStatus: 'AS004', refuseReason: obj.value }).then(res => {
this.$router.push('/amk/amkAppChangeList')
}).catch(res => {
this.$store.dispatch('VerifiFailure', { 'data': res, offset: 'offsetCustom' })
})
})
css
左右布局,左边固定,右边自适应
span {
display flex
padding 0.08rem 0.2rem
width calc(100% - 0.4rem)
>b {
display inline-block
line-height 0.22rem
width 0.9rem
font-size 0.14rem
}
>i {
flex 1
font-size 0.14rem
line-height 0.22rem //与label对齐
word-break break-word //换行
}
}
过渡动画
transition margin-top 0.2s
-webkit-transition margin-top 0.2s
多文本框(textarea)处理换行问题
回显文本样式设置
white-space pre-wrap
一行省略
.textoverflow {
white-space nowrap
overflow hidden
text-overflow ellipsis
}
多行省略
.textoverflow2 {
overflow hidden
text-overflow ellipsis
word-break break-all
display -webkit-box
-webkit-line-clamp 2
-webkit-box-orient vertical
}
checkbox 阻止冒泡事件(要包一层div才有效果)
<!-- 包一层div阻止冒泡事件 -->
<div v-on:click.stop="">
<el-checkbox v-model="checkboxList[index]"></el-checkbox>
</div>
[图片上传失败...(image-5ecb1c-1734332820905)]