• 20211123 点击添加按钮往table表格push一条数据以及分页功能


    效果:

     功能描述:

    添加行:点击按钮,table表格新增一条数据。
    导 入: 点击导入按钮,弹出上传文件组件,这里可以导入execl格式的表格,然后把导入的数据回显到table表格中。
    操作栏: 点击删除按钮, 删除table表格此行数据。
    table-header 搜索框: 输入内容,搜索出相对应的数据,主要用到了数组的filter方法。
    分页: 点击分页,切换上一页,下一页,显示对应的数据。

    代码:

    <template>
    <div>
    // 按钮
    <div class="btns-container">
    <el-buttom size="small" type="primary" @click="addRow">添加</el-button>
    <el-button size="small" type="primary" @click="import">导入</el-button>
    </div>

    // table 表格
    <div class="table-container">
    <el-table
    :data="tableData"
    border
    highlight-current-row
    >
    <el-table-column label="index" type="index"/>
    <template v-for="item in tableHeaders">
    <el-table-column
    :key="item.prop"
    show-overflow-tooltip
    :prop="item.prop"
    :type="item.type"
    >
    // 这里是table-header栏
    <template #header="scope"> // 这里是vue3的写法,如果是用的vue2,则可以改为: slot-scope="scope"即可
    <span>{{item.label}}</span>
    <template v-if="item.queryType==='input'">
    <el-input
    v-model="form[item.prop]"
    :placeholder=`输入${item.label}`
    />
    </template>
    </template>
    // 这里是 table - 行数据
    <template v-if="item.queryType==='input'" #default="scope">
    <el-input v-model="scope.row[item.prop]" placeholder="请输入"/>
    </template>
    </el-table-column>
    </template>
    // table - 操作栏
    <el-table-column
    label="操作"
    >
    <template #default="scope">
    <el-button type="text" @click="deleteRow(scope.$index)">删除</el-button>
    </template>
    </el-table-column>
    </el-table>
    </div>

    // 分页
    <div class="pagination-container">
    <el-pagination
    :current-page="pagination.currentPage"
    :page-sizes="pagination.pageSizes"
    :page-size="pagination.pageSize"
    :layout="pagination.layout"
    :total="pagination.total"
    background
    @size-change="handleSizeChange"
    @current-change="handleCurrentChange"
    />
    </div>

    // 导入文件组件
    <el-dialog
    title="上传文件"
    :visibile.sync="dialogVisible" // 这里的dialog组件可以进行再次封装
    >
    <upload-file
    :type="xxx"
    @submit="uploadSubmit"
    @cancel="uploadCancel"
    @getImportData="getImportData"
    />
    </el-dialog>
    </div>
    </template>
    <script>
    // 引入导入文件组件
    import uploadFile from 'xxxx -> 文件路径';

    export default{
    name:'xx',
    components:{
    uploadFile
    },
    data(){
    return {
    dialogVisible: false,
    tableHeaders:[
    {
    label:'table栏一',
    prop:'var1',
    queryType:'input'
    },{
    label:'table栏二',
    prop:'var2',
    queryType:'input'
    }
    ],
    form:{
    var1:'',
    var2:'',
    },
    pagination:{
    total:0,//总页数
    currentPage:1,
    pageSize:10,
    layout:'sizes,prev,pager,next,jumper',
    pageSizes:[10,20,30,40,50,100]
    },
    originTableData:[]
    }
    },
    computed:{
    tableData(){
    const { pageSize, currentPage } = this.pagination;
    // 当前页
    const pre = (currentPage -1) * pageSize;
    // 下一页
    const next = pageSize * currentPage;
    const formKeys = Object.keys(this.form);
    const tableList = this.originTableData.slice(pre,next);
    const tableFinally = tableList.filter((item) => {
    let flag = true;
    formKeys.forEach((key) => {
    const formValue = this.form[key];
    const itemValue = item[key];
    flag = flag && ((!itemValue && !formValue) || (itemValue && itemValue.includes(this.form[key])));
    })
    return flag;
    })
    return tableFinally;
    }
    },
    watch:{
    originTableData:{
    deep:true,
    handler(){
    this.pagination.total = this.originTableData.length;
    }
    }
    },
    methods:{
    // 设置table数据
    setOiginTableData(data){
    this.originTableData = data;
    },
    // 获取table数据
    getTableData(){
    return this.originTableData;
    },
    // 添加行
    addRow(){
    this.originTableData.push({
    var1:'',
    var2:'',
    })
    },
    // 导入
    import(){
    this.dialogVisible = true;
    },
    // 获取到导入文件的数据并追加到originTableData
    getImportData(data){
    this.dialogVisible = false;
    this.originTableData = [...this.originTableData,...data];
    },
    uploadSubmit(){
    this.dialogVisible = false;
    },
    uploadCancel(){
    this.dialogVisible = false;
    },
    // 删除行数据
    deleteRow(index){
    const {pageSize, currentPage} = this.pagination;
    const num = pageSize * (currentPage -1) + index;
    this.originTableData.splice(num,1);
    },
    // 分页功能 - 页数据
    handleCurrentChange(val){
    this.pagination.currentPage = val;
    },
    // 分页功能 - pagesize 数据
    handleSizeChange(val){
    this.pagination.pageSize = val;
    },
    }
    }
    </script>
    <style lang="scss" scoped>
    // 改变element ui 组件自带得样式可以用
    :deep .el-input {

    }
    </style>

     补充:这里可以看一下导入文件的组件,因为采用的是vue3的写法, 上才艺,哦不,上代码~~~

    <template>
    <div>
    <el-upload
    class="upload-file"
    action="#"
    :headers="headers"
    :multiple="false"
    accept=".xls,.xlsx"
    :on-change="uploadChange"
    :on-success="uploadSuccess"
    :http-request="httpRequest"
    >
    <i class="el-icon-upload" />
    <div class="el-upload__text">
    将文件拖到此处,或 <em>点击上传</em>
    </div>
    </el-upload>
    <span @click="handleDownloadTemplate">下载模板</span>
    <div class="btns">
    <el-button type="primary" @click="handleSubmit">确定</el-button>
    <el-button @click="handleCancel">取消</el-button>
    </div>
    </div>
    </template>
    <script>
    // 这里可以引入 相关api

    export default{
    name:'xxx',
    props:{
    type:{
    type:String,
    default:''
    }
    },

    emits:['getImportData','submit','cancel'],
    setup(props, {emit}){
    //定义变量
    const headers = { Authorization: token // 这里放token值哈 }
    // 点击确定按钮触发的事件
    const handleSubmit = async()=>{
    emit('submit')
    }
    // 点击取消按钮触发的事件
    const handleCancel = async()=>{
    emit('cancel')
    }
    // 上传文件触发的事件
    const uploadChange = (file)=>{
    const {status} = file;
    if(status ==='success'){
    // 导入成功
    }else if(status === 'error'){
    // 导入失败
    }
    }
    // 这个是上传成功后事件
    const uploadSuccess = ()=>{}

    // 自定义上传文件方法
    const httpRequest = async (file)=>{
    const data = new FormData();
    data.append('file',file.file);

    // 这里提一下,如果想获取props传递过来的数据,不能用 this.xxx,需要用 props.xxx,例如,
    if(props.type==='xxx'){
    // 直接请求相关api
    }else{
    // 请求api,假设该请求该api后还有返回值
    const res = await xxxapi(data);
    emit('getImportData',res); // 这里是把返回的数据通过emit上传到父组件
    }
    }

    // 下载模板触发的事件
    const handleDownloadTemplate = async ()=>{
    const params = {};//参数
    const res = await xxapi(params);
    const {downloadUrl} = res; // 获取返回的下载地址

    const DownloadLink = document.createElement('a');
    DownloadLink.href= downloadUrl;
    DownloadLink.style = 'display:none';//隐藏创建的a标签
    document.body.appendChild(Downloadlink);
    DownloadLink.click(); // 触发a标签的click事件
    document.body.removeChild(DownloadLink)
    }

    return {
    handleSubmit,
    handleCancel,
    headers,
    uploadChange,
    uploadSuccess,
    httpRequest,
    handleDownloadTemplate
    }
    }
    }
    </script>

    至此,分享完毕,vue3感觉真不戳~~

    如果快乐太难,那祝你平安。
  • 相关阅读:
    微信助力活动表结构设计
    mysql的in查询分析
    PHP从数组中找到指定元素的位置
    Java程序使用Alpine Linux报错java.lang.NoClassDefFoundError: Could not initialize class org.xerial.snappy.Snappy解决
    Eclipse/Idea 代码格式化部分忽略
    修改Linux桌面高分屏下QT程序界面的缩放
    折腾linux随笔 之 关闭Budgie默认自动隐藏应用的菜单栏 与 Gnome系桌面应用菜单无内容解决
    Debian Buster 使用Lxde在界面中打开url提示错误解决
    Portainer容器可视化管理工具使用文档
    Lxde添加触摸板双击功能、防误触
  • 原文地址:https://www.cnblogs.com/sunnyeve/p/15589785.html
Copyright © 2020-2023  润新知