父组件:
<email-dialog v-if="showemailDialog" v-on:closeemailDialog="closeemailDialog" :multipleSelection="multipleSelection"></email-dialog>
子组件:
<template>
<div>
<el-dialog
title="发送邮件"
:visible.sync="visible"
:close-on-click-modal="false"
:destroy-on-close="true" @close="closeemailDialog"
width="500px">
<div class="emailBan">
<div class="x_form-field y_form-field">
<div class="row">
<label class="form-label light-font"><span class="required red-font">*</span>收件人</label>
</div>
<div class="row" @click="onFocus('sendemail')">
<div class="email-box" ref="email-box">
<el-tag :key="tag" size="mini" type="info" class="rowtag"
v-for="tag in oneemailList" closable :disable-transitions="false"
@close="handleClose(tag,'oneemail')">{{tag}}</el-tag>
<el-input class="inputbox" size="mini" v-model="oneemail" ref="sendIpt" id="receiptIpt"
:style="{width:oneiptWidth+'px'}"
@keyup.enter.native="handleInputConfirm('oneemail')" @blur="handleInputConfirm('oneemail')" >
</el-input>
</div>
</div>
</div>
<div class="x_form-field y_form-field">
<div class="row">
<label class="form-label light-font"><span class="required red-font"></span>抄送人</label>
</div>
<div class="row" @click="onFocus('copyemail')">
<div class="email-box" ref="email-box">
<el-tag :key="tag" size="mini" type="info" class="rowtag"
v-for="tag in twoemailList" closable :disable-transitions="false" @close="handleClose(tag,'twoemail')">{{tag}}</el-tag>
<el-input class="inputbox" size="mini" v-model="twoemail" ref="copyIpt"
:style="{width:twoiptWidth+'px'}"
@keyup.enter.native="handleInputConfirm('twoemail')" @blur="handleInputConfirm('twoemail')">
</el-input>
</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="closeemailDialog">取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch, Prop } from 'vue-property-decorator';
import FormField from '@/components/form-field.vue';
import _ from 'lodash';
import { regCheck, formatDate } from '@/utils/time';
import { getEmailAddress, billNoticeByEmail } from '@/api/email';
@Component({
components: { FormField }
})
export default class EmailDialog extends Vue {
private visible = true;
private oneemail='';
private oneemailList: Array<any>=[];
private twoemail='';
private twoemailList: Array<any>=[];
private oneiptWidth=40;
private twoiptWidth=40;
@Prop({ default: {} }) private multipleSelection !: Record<string, any>;
@Watch('oneemail')
updateoneWidth (val: string) {
this.oneiptWidth = 40 + val.length * 7;
}
@Watch('twoemail')
updatetwoWidth (val: string) {
this.twoiptWidth = 40 + val.length * 7;
}
mounted () {
this.getemailAddress();
}
async getemailAddress () {
const data = {
orderNo: this.multipleSelection.orderNo,
type: 1
};
const res = await getEmailAddress(data);
this.oneemailList = res.sendMail;
this.twoemailList = res.ccMail;
}
handleClose (tag: number, type: string) {
if (type === 'oneemail') {
this.oneemailList.splice(this.oneemailList.indexOf(tag), 1);
}
if (type === 'twoemail') {
this.twoemailList.splice(this.twoemailList.indexOf(tag), 1);
}
}
handleInputConfirm (type: string) {
const { oneprompt, twoprompt } = { oneprompt: '邮箱已存在!', twoprompt: '邮箱格式有误!' };
if (type === 'oneemail') {
if (this.oneemail === '') {
return false;
}
const email = _.trim(this.oneemail).replace(/(;$)|(;$)/g, '');
const is = (n: any) => {
return _.some(this.oneemailList, v => v === n);
};
const res = regCheck(email, 'email');
if (res) {
if (!is(email)) {
this.oneemailList.push(email);
this.oneemail = '';
} else {
this.oneemail = '';
this.$message.warning(oneprompt);
}
} else {
this.$message.warning(twoprompt);
}
}
if (type === 'twoemail') {
if (this.twoemail === '') {
return false;
}
const email = _.trim(this.twoemail).replace(/(;$)|(;$)/g, '');
const is = (n: any) => {
return _.some(this.twoemailList, v => v === n);
};
const res = regCheck(email, 'email');
if (res) {
if (!is(email)) {
this.twoemailList.push(email);
this.twoemail = '';
} else {
this.twoemail = '';
this.$message.warning(oneprompt);
}
} else {
this.$message.warning(twoprompt);
}
}
}
isEmail (val: any) {
const regEmail = /^([a-zA-Z0-9]+[_|\-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\-|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,}$/;
return regEmail.test(val);
}
closeemailDialog () {
this.$emit('closeemailDialog');
}
async confirm () {
if (this.oneemailList.length < 1) {
this.$message.warning('收件人不得为空!');
return false;
}
try {
const sendMail = this.oneemailList.join(';');
const ccMail = this.twoemailList.join(';');
const date = formatDate(this.multipleSelection.billStarttime).split(' ')[0];
const data = {
sendMail: sendMail,
ccMail: ccMail,
customName: this.multipleSelection.customerName,
date: date,
orderNo: this.multipleSelection.orderNo
};
const res = await billNoticeByEmail(data);
if (res) {
this.$message.success('发送成功!');
this.closeemailDialog();
} else {
this.$message.error('发送失败!');
}
} catch {
console.log('发送失败!');
}
}
onFocus (type: string) {
if (type === 'sendemail') {
(this.$refs.sendIpt as any).focus();
}
if (type === 'copyemail') {
(this.$refs.copyIpt as any).focus();
}
}
}
</script>
<style scoped lang="scss">
.el-dialog__body{
.form-field-container{
.oneline-field{
width:100%!important;
}
}
}
.x_form-field {
width:100%!important;
display: inline-block;
margin-bottom: .8rem;
margin-right: 1rem;
position: relative;
::v-deep .el-select {
width: 100%;
}
&.clear-margin {
margin: 0;
}
.form-label {
height: 16px;
line-height: 16px;
padding-bottom: 10px;
font-size: 14px;
text-align: left;
width: 100%;
display: inline-block;
vertical-align: middle;
box-sizing: content-box;
.required{
padding-right: 2px;
}
}
.row{
.email-box{
display: flex;
margin-top: 4px;
padding:6px 0px;
flex-wrap: wrap;
border-radius: 5px;
box-sizing: border-box;
align-items: center;
min-height: 40px;
cursor: text;
border:1px solid #606266;
div.el-input.el-input--mini {
height: 28px;
}
.rowtag{
margin-left:10px;
}
.inputbox{
width:10px;
.el-input__inner{}
}
}
.email-box--active{
border-color: #268DFF!important;
}
}
}
</style>
<style lang="scss">
.y_form-field{
.row{
.email-box{
display: flex;
.inputbox{
.el-input__inner{
border: none!important;
}
}
}
}
}
</style>
其他常用方法:正则校验
// 时间戳格式转换
export function formatDate (datetime: string | Date) {
const date = new Date(datetime);
const YY = date.getFullYear() + '-';
const MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
const DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
const hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
const mm = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
const ss = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
return YY + MM + DD + ' ' + hh + mm + ss;
}
// 枚举转换成selsect下拉数组
export function selectList (enums: any) {
let selectlist = [];
for (const i in enums) {
const temp = {
id: i,
name: enums[i]
};
selectlist.push(temp);
}
selectlist = selectlist.slice(0, selectlist.length / 2);
return selectlist;
}
// 通过id得到下拉数组内的name
export function getName (options: any, num: string|number) {
let optname = '';
options.forEach((item: any) => {
if (Number(num) === item.id) {
optname = item.name;
}
});
return optname;
}
// 校验
export function regCheck (val: any, type: string) {
// 10位数字校验(月结卡号)
if (type === 'cardnum') {
const reg = /^\d{10}$/;
return reg.test(val);
}
// 11位手机号校验
if (type === 'phone') {
const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
return reg.test(val);
}
// 电子邮箱校验
if (type === 'email') {
const reg = /^([A-Za-z0-9_\-.])+@([A-Za-z0-9_\-.])+\.([A-Za-z]{2,5})$/;
return reg.test(val);
}
// 数字及两位小数校验
if (type === 'number') {
const reg = /^-*\d+(\.\d{1,2})?$/;
return reg.test(val);
}
// 数字和字母的组合---(限20位)--(例如:客户编码,合同编码)
if (type === 'code') {
const reg = /^[A-Za-z0-9]{1,20}$/;
return reg.test(val);
}
// 数字和字母的组合---(限50位)--(例如:货主代码)
if (type === 'code_two') {
const reg = /^[A-Za-z0-9]{1,50}$/;
return reg.test(val);
}
// 纯数字---(例如:商机编码)
if (type === 'purenum') {
const reg = /^[0-9]*$/;
return reg.test(val);
}
return true;
}
// 字数限制
export function strNumber (val: string, num: number|string) {
if (val.length > num) {
return false;
}
return true;
}
// 时间大小判断---后者不能大于前者
export function timeJudeg (startTime: any, endTime: any) {
if (typeof startTime === 'string') {
startTime = new Date(startTime);
}
if (typeof endTime === 'string') {
endTime = new Date(endTime);
}
startTime = startTime.getTime();
endTime = endTime.getTime();
if (startTime > endTime) {
return false;
}
return true;
}
// 当前日期获取---默认当前日期
export function getNowTime () {
const now = new Date();
const year = now.getFullYear(); // 得到年份
let month: any = now.getMonth(); // 得到月份
let date: any = now.getDate(); // 得到日期
month = month + 1;
month = month.toString().padStart(2, '0');
date = date.toString().padStart(2, '0');
const defaultDate = `${year}-${month}-${date} 00:00:00`;
return defaultDate;
}
效果图: