基于element-plus的Dialog选择控件

翻看之前工程师写的vue2的代码,很多都是复制、粘贴,也真是搞不懂,明明可以写一个控件,不就可以重复使用。很多前端总喜欢element搞一下,ant-design也搞一下,有啥意义,控件也不是自己写的,积木也没有搭好。

选中之后将值带回去

先看看组件代码

ts 复制代码
<template>
    <el-input v-model="inputLabel" @click="showSub">
        <template #suffix>
            <i class="iconfont iconicon2-081"></i>
        </template>
    </el-input>

    <BaseDialog ref="dialog" title="选择会计科目" width="470px" :visible='visible' :showClose="true" 
        @beforeClose="visible=false">
        <el-tabs v-model="subjectName" >
            <el-tab-pane v-for="(item,index) in subjectTabs" :key="index" :name='item.name' :label="item.title" :value="index" class="tabPane">
            <el-tree :data="categoryTree[index]" node-key="id" default-expand-all highlight-current :expand-on-click-node='false' @node-click="handleSubjectClick" :props="defaultSubjecTreeProps"
            style="height: 380px;overflow-y: auto;">
                <template #default="{ node,data }">
                    <span class="custom-tree-node">
                        <i :class="data.children.length>0 ? 'iconfont iconicon2-08' : 'iconfont iconicon2-11' "></i>
                        {{ node.label }}
                    </span>
                </template>
            </el-tree>
            </el-tab-pane>
        </el-tabs>
        <template #footer>
            <div  class="dialog-footer">
                <el-button type="primary" @click="cancelDialog">返 回</el-button>
            </div>
        </template>
    </BaseDialog>
</template>
<script lang="ts" setup>
import {ref,getCurrentInstance,computed,onMounted,watch } from 'vue'
import BaseDialog from '@/components/base/BaseDialog.vue';
import { useAppStore } from '@/store'
import { de } from 'element-plus/es/locale';
const { proxy }: any = getCurrentInstance();
const appStore = useAppStore()
const userInfo = computed(() => appStore.userInfo)
const curAccountSet = computed(() => appStore.curAccountSet)
const defaultSubjecTreeProps = ref({children: 'children',label: 'label'})
const inputProps = ref({label:'name',value:'id'})
const inputLabel = ref('')
const emits = defineEmits(['update:modelValue','change'])
const visible = ref(false)
const props = defineProps<{
    modelValue:{},
}>()
const showSub = () =>{
    visible.value = true;
}
const subjectName = ref(1)
const subjectTabs = ref(curAccountSet.value?.accountingStandard=='1'?[
    {title: "资产", name: 1,},
    {title: "负债", name: 2,},
    {title: "权益", name: 3,},
    {title: "成本", name: 4,},
    {title: "损益", name: 5,},
]:[
    {title: "资产", name: 1,},
    {title: "负债", name: 2,},
    {title: "共同", name: 3,},
    {title: "权益", name: 4,},
    {title: "成本", name: 5,},
    {title: "损益", name: 6,},
])
const categoryTree = ref([])
const getCategoryTree = async (cate) =>{
    const res = await proxy.$api.acc.accountsubject.list({asId:curAccountSet.value.accId,category:cate});
    if (res.success){
        categoryTree.value[cate - 1] = res.data;
    } else{
        proxy.$message.error(res.msg);
    }
}
const handleSubjectClick = (data) => {
    if (proxy.$_.isEmpty(data.children)){
        inputLabel.value = data.name
        emits('update:modelValue',{value:data.id,label:data.name})
        visible.value = false
    }
}
const cancelDialog = () =>{
    visible.value = false;
}
watch(()=>props.modelValue,(newVal,oldVal)=>{
    if (!proxy.$_.isEmpty(newVal)){
        inputLabel.value = newVal['label']
    }
},{immediate:true,deep:true})
onMounted(()=>{
    getCategoryTree(1);
    getCategoryTree(2);
    getCategoryTree(3);
    getCategoryTree(4);
    getCategoryTree(5);
})
</script>

控件使用比较简单了

html 复制代码
<el-form-item label="应付账款" prop="yfzk">
                            <acc-account-subject v-model="orderForm.yfzk"></acc-account-subject>
                        </el-form-item>

但是在保存和加载的时候需要特殊处理,因为控件的值是{value:data.id,label:data.name}

保存之前,需要做一次深拷贝,不能直接修改orderForm.value,因为双向绑定,页面的数据会改变。

ts 复制代码
const convertParams = () =>{
    debugger
    let params = proxy.$tool.deepClone({...orderForm.value})
    // 应收账款
    params['yszk'] = orderForm.value['yszk']?.value || ''
    params['yszkName'] = orderForm.value['yszk']?.label || ''
  
    return params;
}
const save = async () => {
    orderRef.value?.validate(async valid=>{
        if (valid){
            isLoading.value = true
            const params = convertParams()
            const res = await proxy.$api.setting.psiAccConfig.save(params)
            if (res.success){
                isLoading.value = false;
                proxy.$message.success(res.msg);
            } else{
                isLoading.value = false;
                proxy.$message.error(res.msg);
            }
        }
    })
}

页面加载的时候也需要做一下处理,还是因为数据结构的缘故

ts 复制代码
const load = async () => {
    const res = await proxy.$api.setting.psiAccConfig.load({asId:userInfo.value.currentAsId})
    if (res.success){
        isLoading.value = false;
        orderForm.value = res.data;
        // 应收张狂
        if (orderForm.value['yszkName']){
            orderForm.value['yszk'] = {label:orderForm.value['yszkName'],value:orderForm.value['yszk']}
        }
        }
    } else{
        isLoading.value = false;
        proxy.$message.error(res.msg);
    }
}
相关推荐
Lysun0018 天前
vue3里面,事件触发一次,方法执行多次
javascript·vue.js·elementui·element-plus
飞雪金灵14 天前
Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开
前端·vue3·element-plus·隐藏table箭头·替换table展开箭头·点击整行展开
蟾宫曲1 个月前
在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)
前端·npm·vue3·vite·element-plus·计时器
lulu_06321 个月前
safari 浏览器输入框 focus时不显示那一闪一闪的图标
前端·css·vue·safari·element-plus
Serenity_Qin2 个月前
vue3 + ts 使用 el-tree
前端·vue.js·typescript·vue3·element-plus
虚诚2 个月前
el-selet下拉菜单自定义内容,下拉内容样式类似表格
vue.js·element-plus·下拉菜单
nothing_more_than2 个月前
draggable的el-dialog实现对话框标题可以选择
javascript·vue.js·element-plus
xChive2 个月前
优化表单交互:在 el-select 组件中嵌入表格显示选项
前端·vue.js·交互·element-plus
半度℃温热2 个月前
ERROR TypeError: AutoImport is not a function
webpack·vue3·element-plus·插件版本·autoimport
邱自强2 个月前
el-table 行列文字悬浮超出屏幕宽度不换行的问题
el-table·element-plus·el-tooltip