Vue学习随笔三 — 表格组件

一、el-table组件使用

1、封装 表格组件

<template>
  <el-table
    stripe
    size="mini"
    border
    :data="tableData"
  >
    <el-table-column
      v-for="(item, index) in columns"
      :key="index"
      v-bind="item"
    >
    </el-table-column>
    <el-table-column
      label="操作"
      fixed="right"
      align="left"
      width="160"
    >
      <template slot-scope="scope">
        <span
          type="primary"
          size="mini"
          class="detail-btn"
          plain
          @click="emitEvent({eventName:'detail',params:scope.row})"
        >查看</span>
        
        <!-- <el-button
          v-show="scope.row.approveStatus=='0'"
          type="primary"
          size="mini"
          plain
          @click="emitEvent({eventName:'approval',params:scope.row})"
        >审批</el-button> -->
      </template>
    </el-table-column>
  </el-table>
</template>
<script>
export default {
  name: 'TableBox',
  props: {
    tableData: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      columns: [
        {
          type: 'index',
          label: '序号',
          width: '55',
          align: 'center',
          fixed: 'left'
        },
        {
          prop: 'name', // 字段1
          label: '姓名',
          'show-overflow-tooltip': true
        },
        {
          prop: 'age', // 字段2
          label: '年纪',
          'show-overflow-tooltip': true
        },
        ...
      ]
    }
  },
  methods: {
    // 触发 查询
    emitEvent ({ eventName, params }) {
      this.$emit(eventName, params)
    }
  }
}
</script>
<style lang='less' scoped>
  .detail-btn {
    color: #0049CA;
    cursor: pointer;
  }
  .el-table {
    font-size: 14px;
  }
</style>

2、在页面中使用组件

<template>
    <div class="tabel-box" v-show="isShow">
      <!-- <h3> -->
        <img src="../../../../assets/totalCount.png" alt="">
        <span> 单量为: {{ totalCount }} </span>
      <!-- </h3> -->
      <TableBox
        ref="TableBox"
        :tableData="tableData"
        @detail="detail"
      ></TableBox>
      <div class="pagination-box flex-h flex-he">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :page-sizes="pageSizes"
          :current-page="pageNum"
          :page-size="pageSize"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          background
          small
        >
        </el-pagination>
      </div> 
    </div>       
    </div>
    
  </div>
</template>

<script>
  import axios from 'axios'
  import TableBox from "./table-box"
  import { Api  } from "@/api/xxxx"
 
  export default {
    components:{
      TableBox
    },
    data() {
      return{      
        isShow: true,             
        tableData: [], // 首页表格数据
        total: 0,
        pageSize: 10,
        pageNum: 1, 
        pageSizes: [10, 20, 50, 100],
        params: {},
      }
    },
    mounted(){
      this.getTableData()
    },
    methods: {  
      // 详情页
      // 分页
      handleSizeChange  (val) {
        this.detailPageSize = val
        this.getDetailInfo()
      },
      // 当前页
      handleCurrentChange (val) {
        this.detailPageNum = val
      },    

      //  列表查询
      getTableData(params){
        Api(params).then( res => {
          this.tableData = res.data
          if (res.data.length > 0 ) {
            this.totalCount = res.data[0].totalCount
          } else {
            this.totalCount = 0
          }
        })
      },    
      detail(row) {
		console.log("该行数据“, row)
	  }           
    }
  }

</script>

<style lang="scss" scoped>
  .main {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
    margin: 0;
  }
  .query {
    height: 10%;
    width: 100%;
    padding: 15px;
    background-color: #FFFFFF;
    border-radius: 5px;
  }
  .tabel-box {
    height: 90%;
    width: 100%;
    padding: 20px;
    margin: 5px 0;
    background-color: #FFFFFF;
    border-radius: 5px;
  }
  span {
    font-size: 14px;
    font-weight: 600;
    margin: 0 0 10px 5px;
    display: inline-block;
    vertical-align: middle;
  }
  >img {    
      height: 10px;
      width: 12px;
      display: inline-block;
  }
  .detail-box {
    background-color: #FFFFFF;
    padding: 10px 20px;
    border-radius: 5px;
  }
  .pagination-box {
    margin-top: 20px;
    float: right;
  }
  :deep .pagination-box .el-select--mini .el-input--mini .el-input__inner {
    height: 22px;
    line-height: 22px;
  }

  :deep .pagination-box .el-select--mini .el-input--mini .el-input__icon {
    line-height: 22px;
  }
</style>

二、表格组件中使用 input 编辑框

1. 封装表格组件

<template>
  <el-dialog
  custom-class="custom-dialog"
  :title="dialogTitle"
  :visible.sync="visible"
  :close-on-click-modal="false"
  :close-on-press-escape="false"
  :before-close="resetForm"
  width="70%"
  >

  <el-table
    border
    :data="tableData"
    :cell-style="{color: '#515A6E'}"
    :header-cell-style="{background: '#F8F8F9', color: '#515A6E'}"
  >
  <el-table-column
    label="序号"
    type="index"
    width="50"
    align="center"
  ></el-table-column>
  <el-table-column
    label='城市'
    prop="city"
  ></el-table-column>
  >
  <el-table-column
    label="中等酒店价格"
    prop="price"
  > 
 	// 加入input框
    <template slot-scope="scope">
      <el-input
        size="small"
        clearable
        v-model.number = "scope.row.price"
        oninput="value=value.replace(/[^0-9]/g, '')"
        :min="0"
      ></el-input>
      <span>元/天/间</span>
    </template>
  </el-table-column>
  
<el-table-column
    label="其他酒店价格"
    prop="price"
  > 
 	// 加入input框
    <template slot-scope="scope">
      <el-input
        size="small"
        clearable
        v-model.number = "scope.row.price"
        oninput="value=value.replace(/[^0-9]/g, '')"
        :min="0"
      ></el-input>
      <span>元/天/间</span>
    </template>
  </el-table-column>
  
  </el-table> 
  
  <!-- <div class="pagination-box flex-h flex-he">
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :page-sizes="pageSizes"
      :current-page="pageNum"
      :page-size="pageSize"
      :total="total"
      layout="total, sizes, prev, pager, next, jumper"
      background
      small
    >
    </el-pagination>
  </div> -->

  <div slot="footer" class="dialog-footer">
    <el-button size="small" type="primary" class="submit" @click="submit()">确 定</el-button>
    <el-button size="small" @click="resetForm()">取 消</el-button>
  </div>

  </el-dialog>
</template>

<script>

  import { Api} from '@/api/Api'

  export default {
    data(){
      return {
        visible: false,
        tableData: [
          {
            id: '1',
            city: '北京、上海',
            price: "",
          },
          {
            id: '1',
            city: '重庆、天津、广州、大连、青岛、宁波、深圳及省会城市',
            price: "600",
          },
          {
            id: '1',
            city: '其他城市',
            price: "550",
          },
          
        ],
        dialogTitle: "住宿",
        ruleConfigId: "",
        pageNum: 0,
        pageSize: 10,
        pageSizes: [10, 20, 50, 100],
        total: 0,         
      }
    },
    methods: {
      handleSizeChange(val){
        this.pageSize = val
        this.getData()
      },
      handleCurrentChange(val){
        this.pageNum = val
        this.getData()
      },
      open(value) {
        this.visible = true
        console.log("value==", value)
        const params = {}
        getApi(params).then( res => {
          console.log("酒店价格 res", res)
        })
      },
      // 取消
      resetForm(){
        this.visible = false
      },
     
      // 数据校验
      submit() {
        // 获取表格数据    
        const params = this.tableData
        Api(params).then( res => {
			console.log("修改后的数据", res)
        })
      }
    }
  }

</script>

<style lang="scss" scoped>
  // 分页
  .pagination-box {
    margin-top: 15px;
    float: right;
  }
  :deep .pagination-box .el-select--mini .el-input--mini .el-input__inner {
    height: 22px;
    line-height: 22px;
  }
  :deep .pagination-box .el-select--mini .el-input--mini .el-input__icon {
    line-height: 22px;
  }
  .el-input {
    width: 60%;
    margin-right: 10px;
  }
  .submit {
    background-color: #0049CA;
    color: #FFFFFF;
  }
  .el-button {
    font-size: 14px;
  }
</style>

2. 展示效果

在这里插入图片描述

三、可复用表格组件封装

1、组件封装

<template>
  <el-table
    border
    stripe
    :data="tableData"
    :columns="columns"
  >
  <el-table-column
    type="index"
    label="序号"
    align="center"
    width="55"
  >
  </el-table-column>
  <template >
    <el-table-column
      v-for="(item, index) in columns"
      :key="index"
      :prop="item.prop"
      :label="item.label"
      :align="item.align || 'center' "
      :show-overflow-tootip="item.overHidden || true "
    >   
      <template slot-scope="scope">
        <slot
          v-if="item.slot"
          :name="scope.cloumn.property"
          :row="scope.row"
          :$index="scope.$index"
        />
        <span v-else> {{ scope.row[scope.column.property] }}</span>       
      </template>
    </el-table-column>

  </template>

  <!-- 表格操作 -->
  <!-- <el-table-column
    v-if="operation"
    label="操作"
    align="center"
  >
  <el-table-column label="操作">
    <template slot-scope="scope">
      <el-button 
      type="primary" 
      v-for="(value, index) in operation" 
      @click="value.click(scope.row, value)"
      :key="index"
      >
      {{ value.text }}
    </el-button>
    </template>

  </el-table-column>
  </el-table>

</template>

<script>

  export default {
    props: {
      tableData: {
        type: Array,
        default: () => {
          return []
        }
      },
      columns: {
        type: Array,
        default: () => {
          return []
        }
      },
      operation: {
        type: Array,
        default: () => {
          return []
        }
      },
    },
    data() {
      return {
        
      }
    }
  }

</script>

<style>
  span {
    
  }
</style>

2、组件调用

<template>
  <div class="index">
    <QueryForm
      ref="queryForm"
      :form="form"
      :form-config="formConfig"
      @query="query"
      @refresh="refresh"
      @addItem="addItem"
      @modItem="modItem"
      @deleteItem="deleteItem"
      @upload="upload"
      @download="download"
    >
    </QueryForm>

    <TableModal
      :tableData="tableData"
      :columns="columns"
      :operation="operation"
    >
    </TableModal>

    <UploadFile
      ref="uploadBox"
    >
    </UploadFile>
    <FormModal
     ref="addForm"
     :form="addForm"
     :form-config="formConfig1"
     ></FormModal>
    
  </div>
</template>

<script>
import QueryForm  from "./QueryForm.vue"
import UploadFile from "./UploadFile.vue"
import TableModal from "./TableModal.vue"
import FormModal from "./FormModal.vue"

export default {
  name: 'HelloWorld',
  components: {
    QueryForm, UploadFile, TableModal, FormModal
  },
  props: {
    // msg: String
  },
  data(){
    return{
      tableData: [
        {
          id: '123',
          status: '关闭',
          name: "电视"
        },
        {
          id: '234',
          status: '开启',
          name: "洗衣机"
        },
        {
          id: '345',
          status: '关闭',
          name: "投影仪",
        },
        
      ],
      columns: [
        { prop: 'id', label: 'ID' },
        { prop: 'name', label: 'name' },
        { prop: 'status', label: '状态' },
      ],
      // 操作按钮自定义
      operation:[
        {
          text: '查看', click: (row) => {return this.getInfo(row)}
          // text: '查看', click: (row, col, cellValue) => {return this.getInfo(row)}
        },
        {
          text: '编辑', click: (row) => {return this.editInfo(row)}
        },
        {
          text: '删除', click: (row) => {return this.delInfo(row)}
        }

      ],
      addForm: {
        id: '',
        status: "",
        name: '',
      },
      // 新增弹窗表单项
      formConfig1: [
        {model: 'id', label: 'ID', type: 'input'},
        {model: 'name', label: 'name', type: 'input'},
        {model: 'status', label: '状态', type: 'input'}
      ]
    }
  },
  methods: {
    // 表格操作
    getInfo(row){
      console.log("查看详情", row)
    },
    // 编辑
    editInfo(row) {
      console.log("编辑详情", row)
      this.$refs.addForm.handleOpen({
        title: '编辑',
        form: row
      })
    },
    // 删除
    delInfo(row) {
      console.log("删除改行", row)
    },

  }
}
</script>


GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐