vue+ Element UI 动态生成表单及校验

第一次写博客,菜的一批,只想记录自己成长道路的一路心血,毕竟快奔三的人转行过来前端不容易啊.因为喜欢看掘金的博客,大咖很多,所以选择这里向前辈看齐.

欢迎吐槽和指正!!!

实现效果:

掘金支持的快捷键:

    <el-dialog title="分配权益卡" :visible="equityVisible" width="60%" @close="$emit('close', false)" append-to-body>

<div class="contentBox">

<div class="content" v-for="(items, mainIndex) in allCardData" :key="mainIndex">

<div class="close" @click="handleDel(mainIndex)" v-show="allCardData.length > 1">

<span class="el-icon-remove"></span>

</div>

<div>

<el-select

v-model="selectItem.organId"

@change="queryOrganDatainfo($event, mainIndex, index)"

v-for="(selectItem, index) in items.organDtoList"

:key="index"

:placeholder="'请选择' + selectItem.name"

>

<el-option v-for="item in selectItem.list" :key="item.organId" :label="item.organName" :value="item.organId" clearable />

</el-select>

</div>

<el-form class="cardBox" :model="itemCard" v-for="(itemCard, cardIndex) in items.distributionDtoList" :key="cardIndex">

<div class="content_card">

<template class="destory">

<span class="el-icon-remove" @click="closeBtn(mainIndex, cardIndex)" v-if="items.distributionDtoList.length > 1"></span>

</template>

<el-form-item>

<el-select v-model="itemCard.packageId" @change="queryOrganChange(itemCard.packageId)" @focus="queryOrganCardData(itemCard.packageId)" placeholder="请选择权益卡">

<el-option v-for="item in secondtypeOptions" :key="item.packageId" :label="item.packageName" :value="item.packageId" />

</el-select>

</el-form-item>

<el-form-item

prop="numbers"

:rules="[

{ required: true, message: '输入不能为空', trigger: ['blur', 'change'] },

{ validator: (rule, value, callback) => validateSku(rule, itemCard.numbers, callback), trigger: ['blur', 'change'] },

{ type: 'number', message: '库存必须为数字' },

]"

>

<span>库存 {{ stock }}</span>

<el-input type="numbers" v-model.number="itemCard.numbers" placeholder="请输入权益卡数量" />

<span>剩余 {{ remain }}</span>

</el-form-item>

</div>

<em class="icon_bar"></em>

<el-link type="primary" v-if="items.distributionDtoList.length > 0" :disabled="items.distributionDtoList.length > 1" @click="addCard('cards', mainIndex)">

添加权益卡

</el-link>

</el-form>

</div>

<div>

<el-button type="primary" plain @click="addCard('items', allCardData.length)" class="assignBtn">添加分配对象 </el-button>

</div>

</div>

<span slot="footer">

<el-button @click="$emit('close', false)">取消</el-button>

<el-button type="primary" @click="confirm">确定</el-button>

</span>

</el-dialog>

</template>

<script>

export default {

name: 'DistributeEquityCard', // 分配权益卡

props: {

equityVisible: {

type: Boolean,

default: false,

},

agentData: {

type: Object,

default: () => {

return {};

},

},

},

data: () => {

return {

organId: 1,

secondOrgan: '',

threeOrgan: '',

secondtypeOptions: [],

threetypeOptions: [],

stock: '', // 库存

remain: '', // 剩余

showValidate: false, // 表单校验

allCardData: [

{

organDtoList: [

{

organId: '',

name: '省',

list: [],

},

{

organId: '',

name: '市',

list: [],

},

{

organId: '',

name: '支公司',

list: [],

},

{

organId: '',

name: '职场',

list: [],

},

],

distributionDtoList: [

{

packageId: '',

packageName: '',

numbers: '',

},

],

},

],

};

},

created() {

this.queryOrganDatainfo();

this.queryOrganCardData();

},

methods: {

// 获取职场列表

queryOrganDatainfo(val, mainIndex, index) {

// console.log(val, mainIndex, index);

if (val) {

this.organId = val;

}

this.$store.dispatch('Organize/queryTreeList', { organId: this.organId }).then((res) => {

if (res.code === 200) {

if (val && index < 3) {

this.cardData[mainIndex].organDtoList[index + 1].list = res.data;

} else {

this.cardData[0].organDtoList[0].list = res.data;

}

}

});

},

// 选择权益卡内存

queryOrganChange(val) {

for (const i of this.secondtypeOptions) {

if (i.packageId === val) {

this.stock = i.packageNumber;

}

}

},

// 获取权益卡

queryOrganCardData(val) {

// console.log('权益卡', val);

this.$store

.dispatch('healthPack/queryDistributionType', {

organId: this.agentData.organId,

})

.then((res) => {

const { code, data } = res;

if (code === 200) {

this.secondtypeOptions = data;

// console.log(data.packageNumber);

this.stock = data.packageNumber;

}

});

},

// 关闭单条权益卡

closeBtn(mainIndex, cardIndex) {

// console.log('mainIndex:', mainIndex, 'cardIndex:', cardIndex);

this.allCardData[mainIndex].distributionDtoList.forEach((v, i) => {

if (cardIndex === i) {

this.allCardData[mainIndex].distributionDtoList.splice(cardIndex, 1);

}

});

},

// 添加权益卡

addCard(str, index) {

// console.log(str, index);

// 添加分配对象

if (str === 'items') {

this.allCardData.push({

organDtoList: [

{

organId: '',

name: '省',

list: [],

},

{

organId: '',

name: '市',

list: [],

},

{

organId: '',

name: '支公司',

list: [],

},

{

organId: '',

name: '职场',

list: [],

},

],

distributionDtoList: [

{

packageId: '',

packageName: '',

numbers: '',

},

],

});

} else if (str === 'cards') {

// 添加权益卡

this.allCardData[index].distributionDtoList.push({

distributionDtoList: {

packageId: '',

packageName: '',

numbers: '',

},

});

}

},

// 删除分配对象盒子

handleDel(index) {

this.allCardData.splice(index, 1);

},

// 校验库存

validateSku(rule, value, callback) {

if (typeof value === 'string') {

this.remain = Number(this.stock);

callback(new Error('库存必须为数字'));

return;

}

if (value > Number(this.stock)) {

callback(new Error('数量不能大于库存'));

this.remain = Number(this.stock);

} else {

this.remain = Number(this.stock) - value;

callback();

}

},

// 确认按钮逻辑

confirm() {},

},

};

</script>

<style lang="scss" scoped>

.contentBox {

display: flex;

flex-direction: column;

justify-content: center;

align-items: center;

.content {

width: 720px;

// height: 216px;

margin-bottom: 16px;

border: 1px dashed #c7ccd9;

border-radius: 4px;

padding: 24px 40px;

position: relative;

.cardBox {

margin-top: 16px;

display: flex;

flex-direction: row;

align-items: center;

.content_card {

position: relative;

// width: 458px;

height: 56px;

border: 1px dashed #c7ccd9;

border-radius: 4px;

display: flex;

flex-direction: row;

justify-content: space-around;

align-items: center;

padding: 0 10px;

padding-top: 20px;

}

.icon_bar {

height: 20px;

width: 1px;

margin-left: 22px;

margin-right: 22px;

background-color: #c7ccd9;

}

}

}

}

.el-icon-remove {

position: absolute;

top: 0;

right: -2px;

color: #2b6fff;

}

.close {

position: absolute;

top: 0;

right: 0;

}

.el-select {

width: 148px;

margin-left: 8px;

}

.el-input {

width: 148px;

}

/deep/.el-form-item__error {

left: 33px;

}

关键代码:

参考链接:

推荐 juejin.im/post/5d4932…

blog.csdn.net/weixin_4327…

blog.csdn.net/weixin_4104…

blog.csdn.net/Beamon__/ar…

自定义校验element官网:element.eleme.io/#/zh-CN/com…

以上是 vue+ Element UI 动态生成表单及校验 的全部内容, 来源链接: utcz.com/a/24451.html

回到顶部