VUE3 添删改查示例代码 包含高级查询 排序 字段筛选 打印 导出

7 篇文章 0 订阅
5 篇文章 0 订阅

这段实例代码是使用 ElementPlus完成的 由代码生成器生成

包含了表单验证 添删改查 表格排序 字段筛选 JS端的打印与导出

望vue3开发人员 开发越来越顺 赚钱越来越多

 由于使用了自动引用 所以没有import

看好的客观请点赞

<template>
    <!-- 搜索 -->
    <el-card>
        <el-form :inline="true">
            <el-form-item label="姓名">
                <el-input v-model="Ms.searchForm.name" placeholder="请输入姓名" clearable/>
            </el-form-item>
            <el-form-item label="年龄">
                <el-input-number v-model="Ms.searchForm.age" placeholder="请输入年龄" />
            </el-form-item>
            <el-form-item label="邮箱">
                <el-input v-model="Ms.searchForm.email" placeholder="请输入邮箱" clearable/>
            </el-form-item>

            <el-form-item label="加入时间">
                <el-date-picker v-model="Ms.searchForm.enterTime" type="datetimerange" format="YYYY/MM/DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择" clearable range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"/>
            </el-form-item>
            <el-form-item label="价格">
                <el-input-number v-model="Ms.searchForm.price" placeholder="请输入价格" />
            </el-form-item>
            <el-form-item>
                <el-button @click="searchData()" type="primary" icon="Search">查询</el-button>
                <el-button @click="resetSearchData()">重置</el-button>
            </el-form-item>
        </el-form>
    </el-card>
    <el-card style="margin-top:15px">
        <!-- 工具栏 -->
        <el-button type="primary" @click="addOrUpdateHandle()" icon="CirclePlus">新增</el-button>
        <el-button type="danger" :disabled="Ms.dataListSelections.length <= 0" @click="deleteConfirmHandle()" icon="Delete">批量删除</el-button>
        <el-button type="success" :disabled="Ms.dataListSelections.length <= 0" @click="exportExcel" icon="Download">导出</el-button>
        <el-button type="success" :disabled="Ms.dataListSelections.length <= 0" @click="printTable" icon="Printer">打印</el-button>
        <el-button @click="getDataList()" icon="Refresh">刷新</el-button>
        <el-dropdown :hide-on-click="false" trigger="click" style="float:right">
            <el-button size="small" icon="Grid"></el-button>
            <template #dropdown>
                <el-dropdown-menu>
                    <el-scrollbar style="height:200px;">
                        <el-checkbox-group v-model="Ms.selectedColList">
                            <el-dropdown-item v-for="(item,index) in Ms.colList" :key="index">
                                <el-checkbox :key="item.value" :label="item">{{item.label}}</el-checkbox>
                            </el-dropdown-item>
                        </el-checkbox-group>
                    </el-scrollbar>
                </el-dropdown-menu>
            </template>
        </el-dropdown>
        <!-- 主表 -->
        <el-table style="margin-top:15px;width: 100%;"
                  header-cell-class-name="headerStyle"
                  stripe
                  @cell-dblclick="celldblclick"
                  :data="Ms.dataList"
                  :border="true"
                  sortable="custom"
                  @sort-change="sortChangeHandle"
                  @selection-change="selectionChangeHandle">
            <el-table-column type="selection" header-align="center" align="center" width="50" />
            <el-table-column prop="id" header-align="center" align="center"  label="主键ID" v-if="showCol('id')"  sortable="custom"/>
            <el-table-column prop="name" header-align="center" align="center"  label="姓名" v-if="showCol('name')" />
            <el-table-column prop="age" header-align="center" align="center"  label="年龄" v-if="showCol('age')"  sortable="custom"/>
            <el-table-column prop="email" header-align="center" align="center"  label="邮箱" v-if="showCol('email')" />
            <el-table-column prop="createDate" header-align="center" align="center"  label="创建时间" v-if="showCol('createDate')"  sortable="custom"/>
            <el-table-column prop="photos" header-align="center" align="center"  label="照片" v-if="showCol('photos')" />
            <el-table-column prop="lat" header-align="center" align="center"  label="经度" v-if="showCol('lat')"  sortable="custom"/>
            <el-table-column prop="lng" header-align="center" align="center"  label="纬度" v-if="showCol('lng')"  sortable="custom"/>
            <el-table-column prop="enterTime" header-align="center" align="center"  label="加入时间" v-if="showCol('enterTime')"  sortable="custom"/>
            <el-table-column prop="price" header-align="center" align="center"  label="价格" v-if="showCol('price')"  sortable="custom"/>
            <el-table-column prop="mark" header-align="center" align="center"  label="备注" v-if="showCol('mark')" />
            <el-table-column fixed="right" header-align="center" align="center" width="180" label="操作">
                <template #default="scope">
                    <el-button link type="primary" size="small" @click="showHandle(scope.$index)">查看</el-button>
                    <el-button link type="primary" size="small" @click="addOrUpdateHandle(scope.$index)">修改</el-button>
                    <el-button link type="primary" size="small" @click="deleteConfirmHandle(scope.row.id)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <!-- 翻页器 -->
        <el-pagination
                style="margin-top:15px;width: 100%;"
                background
                :current-page="Ms.pageData.pageIndex"
                :page-sizes="[10, 20, 50, 100]"
                :default-page-size="Ms.pageData.pageSize"
                :total="Ms.pageData.total"
                layout="total, sizes, prev, pager, next, jumper"
                @size-change="sizeChangeHandle"
                @current-change="currentChangeHandle"
        />
    </el-card>

    <!-- 弹窗, 新增 / 修改 -->
    <el-dialog v-model="Ms.editDialog" width="75%" :close-on-click-modal="true" :append-to-body="true" :destroy-on-close="true">
        <el-form ref="formRef" :model="Ms.formData" :rules="Ms.rules" label-width="100px" @keyup.enter.native="submitHandle()">
            <el-row :gutter="15">
                <el-col :span="24">
                    <el-form-item label="姓名" prop="name">
                        <el-input v-model="Ms.formData.name" placeholder="请输入姓名" clearable/>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="年龄" prop="age">
                        <el-input-number v-model="Ms.formData.age" placeholder="请输入年龄" />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="邮箱" prop="email">
                        <el-input v-model="Ms.formData.email" type="textarea" :rows="3" placeholder="请输入邮箱" clearable/>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="创建时间" prop="createDate">
                        <el-date-picker  v-model="Ms.formData.createDate" type="datetime" format="YYYY/MM/DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择" clearable/>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="加入时间" prop="enterTime">
                        <el-date-picker  v-model="Ms.formData.enterTime" type="datetime" format="YYYY/MM/DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择" clearable/>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="价格" prop="price">
                        <el-input-number v-model="Ms.formData.price" placeholder="请输入价格" />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="备注" prop="mark">
                        <el-input v-model="Ms.formData.mark" placeholder="请输入备注" clearable/>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
        <template #footer>
            <el-button @click="Ms.editDialog=false">关闭</el-button>
            <el-button type="primary" @click="submitHandle">确定</el-button>
        </template>
    </el-dialog>

    <!-- 详细信息 -->
    <el-dialog v-model="Ms.showDialog" :close-on-click-modal="true" :append-to-body="true" :destroy-on-close="true">
        <el-descriptions  :column="2" border id="desc">
            <el-descriptions-item label="主键ID">
                {{ Ms.formData.id? Ms.formData.id : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="姓名">
                {{ Ms.formData.name? Ms.formData.name : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="年龄">
                {{ Ms.formData.age? Ms.formData.age : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="邮箱">
                {{ Ms.formData.email? Ms.formData.email : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="创建时间">
                {{ Ms.formData.createDate? Ms.formData.createDate : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="照片">
                {{ Ms.formData.photos? Ms.formData.photos : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="经度">
                {{ Ms.formData.lat? Ms.formData.lat : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="纬度">
                {{ Ms.formData.lng? Ms.formData.lng : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="加入时间">
                {{ Ms.formData.enterTime? Ms.formData.enterTime : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="价格">
                {{ Ms.formData.price? Ms.formData.price : " "}}
            </el-descriptions-item>
            <el-descriptions-item label="备注">
                {{ Ms.formData.mark? Ms.formData.mark : " "}}
            </el-descriptions-item>
        </el-descriptions>
        <template #footer>
            <el-button @click="Ms.showDialog=false">关闭</el-button>
            <el-button type="success" @click="printForm" icon="Printer">打印</el-button>
        </template>
    </el-dialog>
</template>


<script lang="ts" setup>
    import {downloadByJson,printByJson,printById} from '@/utils/excelTools'
    import {useUUID} from '@/hooks/tools'
    //=====================================>data
    const Ms:any = reactive({
        // dataList:[],
        pageData:{
            total:0,
            pageSize:20,
            pageIndex:1,
            sortProp:'createDate',
            sortOrder:'descending',
        },
        defaultSearchForm:{},
        searchForm:{},
        formData:{},
        dictMap:{},
        dataListSelections:[],
        showDialog:false,
        editDialog:false,
        colList:[
            {value:'id',label:'主键ID'},
            {value:'name',label:'姓名'},
            {value:'age',label:'年龄'},
            {value:'email',label:'邮箱'},
            {value:'createDate',label:'创建时间'},
            {value:'photos',label:'照片'},
            {value:'lat',label:'经度'},
            {value:'lng',label:'纬度'},
            {value:'enterTime',label:'加入时间'},
            {value:'price',label:'价格'},
            {value:'mark',label:'备注'},
        ],
        rules:{
            name: [
                { required: true, message: '请输入姓名', trigger: 'blur' }
            ],
            age: [
                { required: true, message: '请输入年龄', trigger: 'blur' }
            ],
            email: [
                { required: true, message: '请输入邮箱', trigger: 'blur' }
            ],
            createDate: [
                { required: true, message: '请输入创建时间', trigger: 'blur' }
            ],
            photos: [
                { required: true, message: '请输入照片', trigger: 'blur' }
            ],
            lat: [
                { required: true, message: '请输入经度', trigger: 'blur' }
            ],
            lng: [
                { required: true, message: '请输入纬度', trigger: 'blur' }
            ],
            enterTime: [
                { required: true, message: '请输入加入时间', trigger: 'blur' }
            ],
            price: [
                { required: true, message: '请输入价格', trigger: 'blur' }
            ],
            mark: [
                { required: true, message: '请输入备注', trigger: 'blur' }
            ],
        },
        // selectedColList:[]
    })


    const {proxy} = getCurrentInstance() as any
    //接受参数 route.query.name
    const route = useRoute()
    //跳转传参 router.push({path:'/path',query:{name:'ligang'}})
    const router = useRouter()

    Ms.selectedColList = [...Ms.colList]

    //=====================================>onMounted
    onMounted(() => {
        getDataList()
    });
    //=====================================>watch
    watch(Ms, (newValue, oldValue) => {
        if(import.meta.env.DEV){
            console.log('Ms 数据发生改变', newValue)
        }
    })
    //=====================================>computed
    Ms._temp=computed(()=>{
        return "bo"+"tan"
    })
    //=====================================>methods
    //获取主表数据
    const getDataList = async() => {
        const sortInfo = Ms.pageData.sortProp + (Ms.pageData.sortOrder === 'descending' ? ' desc' : ' asc')
        const {data} = await http.post("/api/greenelec_demo/findByEntity",Ms.searchForm,{params:{page:Ms.pageData.pageIndex,size:Ms.pageData.pageSize,sort:sortInfo}})
        if(data.success){
            Ms.dataList = data.data.records;
            Ms.pageData.total = data.data.total;
        }
    }

    //重置搜索
    const resetSearchData = () => {
        Ms.searchForm = {...Ms.defaultSearchForm}
        Ms.pageData.pageIndex = 1
        getDataList()
    }


    const showHandle = (index?:any) => {
        Ms.formData = Ms.dataList[index]
        Ms.showDialog=true
    }

    //打开新增或修改窗体
    const addOrUpdateHandle = (index?:any) => {
        if(index===undefined){
            Ms.formData = {}
        }else{
            Ms.formData = {...Ms.dataList[index]}
        }
        Ms.editDialog=true
    }

    //排序发生改变
    const sortChangeHandle = (sort) =>{
        Ms.pageData.sortProp = sort.prop
        Ms.pageData.sortOrder = sort.order
        Ms.pageData.pageIndex = 1
        getDataList()
    }

    //选择主表数据
    const selectionChangeHandle = (selection) =>{
        Ms.dataListSelections = selection
    }

    //搜索
    const searchData = () => {
        Ms.pageData.pageIndex = 1
        getDataList()
    }

    //页面size修改
    const sizeChangeHandle = (size) =>{
        Ms.pageData.pageSize = size
        Ms.pageData.pageIndex = 1
        getDataList()
    }

    //翻页
    const currentChangeHandle = (num) => {
        Ms.pageData.pageIndex = num
        getDataList()
    }

    //显示列
    const showCol = (colName) => {
        return Ms.selectedColList.findIndex(item=>item.value===colName)>=0;
    }

    //双击复制
    const celldblclick = (row,col) => {
        if(!col.property) return
        navigator.clipboard.writeText(row[col.property]).then(() => {
            ElMessage({message: '内容已复制',type: 'success',})
        });
    }


    //提交数据
    const submitHandle = async() =>{
        proxy.$refs['formRef'].validate(async valid => {
            if (!valid) return
            let resp:any = null
            if(!Ms.formData.id){
                resp = await http.post("/api/greenelec_demo/add",Ms.formData)
            }else{
                resp = await http.post("/api/greenelec_demo/updateById",Ms.formData)
            }
            if(resp.data.success){
                Ms.editDialog = false
                getDataList()
                ElNotification({title: '操作成功',message: '更新数据成功',type: 'success'})
            }else{
                ElMessage({type: 'error',message: '错误:'+resp.msg})
            }
        })
    }

    //删除确认
    const deleteConfirmHandle = async(id?:any) => {
        // 处理IDS
        let ids = id ? [id] : Ms.dataListSelections.map(item => {
            return item.id
        })
        ElMessageBox.confirm('确认真的删除吗?','警告',{
            confirmButtonText: '确认',
            cancelButtonText: '取消',
            type: 'warning',
        }).then(async () => {
            const resp = await http.get('/api/greenelec_demo/removeByIds', { params: { ids: ids.join(',') }})
        if(resp.data.success){
            ElNotification({title: '操作成功',message: '删除数据成功',type: 'success'})
            getDataList()
        }
    }).catch((e)=>{})
    }

    //导出excle
    const exportExcel = () => {
        downloadByJson(Ms.selectedColList,Ms.dataListSelections,useUUID()+".xlsx")
    }

    const printTable = () => {
        printByJson(Ms.selectedColList,Ms.dataListSelections,"数据报表")
    }

    const printForm = () => {
        printById("desc")
    }


</script>

<style>
    .el-table {
        --el-table-header-bg-color: #eee;
    }

    .headerStyle .cell{
        color:'#000';
        font-weight: bold !important;
    }
</style>

ExcelTools.ts  工具 使用到了 js库 print-js 和 xlsx 请自行安装


import printJS from 'print-js';
import {utils,writeFile} from 'xlsx'

/**
 * 下载选中的json数据
 * @param selectColList 选中的列
 * @param dataList 数据
 * @param fileName 文件名
 */
const downloadByJson = (selectColList,dataList,fileName) =>{
    let excelData:any = [];
    const excelHead:any = selectColList.map(item=>item.label)
    const excelCol = selectColList.map(item=>item.value)
    excelData.push(excelHead)
    for (let row of dataList) {
        let obj:any = []
        for(let col of excelCol){
            obj.push(row[col])
        }
        excelData.push(obj)
    }
    const ws = utils.json_to_sheet(excelData,{skipHeader: true});
    const wb = utils.book_new();
    utils.book_append_sheet(wb, ws, "sheet1");
    writeFile(wb, fileName);
}


/**
 * 打印选中的数据
 * @param selectColList 选中的列
 * @param dataList 数据
 */
const printByJson = (selectColList,dataList,title) =>{

    let printColumns = selectColList.map(item => {
        return {
          field: item.value,
          displayName: item.label,
        };
      });

      //整理并过滤掉null
      const printData:any = [];
      for (let row of dataList) {
        let obj:any = {}
        for(let col of selectColList){
            obj[col.value] = row[col.value]?row[col.value]:''
        }
        printData.push(obj)
    }

      printJS({
        printable: printData,
        maxWidth: 2500,
        properties: printColumns,
        header: `
          <div class="titleDiv">
            <div class="title">${title}</div>
          </div>
        `,
        //size: landscape;
        style: `@page {  margin: 0.5cm; margin-right: 0.5cm; margin-top: 0.5cm; margin-bottom: 0.3cm; padding-bottom: 0px; }
          .title {
            margin-top: 10px;
            font-size: 20px;
            text-align: center;
            padding:10px;
          }     
          `,
        gridStyle: 'text-align: center; border: 1px solid black;',
        gridHeaderStyle:
          'border-top: 1px solid black; border-right: 1px solid black; border-left: 1px solid black; border-bottom: 0px;',
        type: 'json',
      });
}

const printById = (id) => {
    printJS({
        printable:id, 
        type:'html',
        targetStyles: ['*'],
        header:'',
        style: `@page {  margin: 0.5cm; margin-right: 0.5cm; margin-top: 0.5cm; margin-bottom: 0.3cm; padding-bottom: 0px; }`
    })
}


export{
    downloadByJson,
    printByJson,
    printById
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值