创建一个通用的Table组件

<template>
  
  <div class="data-table">
    <el-table
      :data="myTableData"
      border
      size="small"
      @selection-change="selectionChange">
      
      <el-table-column v-if="type == 'selection'"
           type="selection"
           label="选择"
           width="55">
      </el-table-column>
      
      <!-- 序号 -->
      <el-table-column v-if="type == 'index'"
           type="index" label="序号"
           width="55">
      </el-table-column>
      
      <!-- 单元格 -->
      <el-table-column v-for="(item, index) in fieldData" :key="index"
         :label="item.label"
         :prop="item.field"
         :width="item.width"
         :sortable="item.sortable"
         :formatter="(row, column, cellValue, index) => formatter(row, column, cellValue, index, item)"
      />
      <!-- 插槽 额外 操作按钮自己控制 -->
      <slot name="opts"></slot>
    </el-table>

    <el-pagination v-if="page"
       @current-change="pageChange"
       @size-change="sizeChange"
       :page-size="pageSize"
       :page-sizes="pageSizeList"
       background
       :layout="pageLayout"
       :total="myTotal">
    </el-pagination>
  </div>
  
</template>

<script>
  export default{
    components: {},
    data(){
      return {
        checkboxArr: [],
        radio: '',
        formObj: null,
        tableClassName: '',
        id: '',
        successFieldObj: {},
        checkTrData: [],  // 多选数据
        myTableData: this.tableData,
        myTotal: this.total,  // 总条数
        myPageSize: this.pageSize,  // ,每页条数
      }
    },
    props: {
      // 数据总条数
      total: {
        default: 0,
        type: Number
      },
      // 表格类型:带索引  选择框
      type: {
        default: '',
        type: String
      },
      // 字段集合
      fieldData: {
        default: (() => []),
        type: Array
      },
      // 表格数据集合
      tableData: {
        default: (() => []),
        type: Array
      },
      // 是否需要分页
      page: {
        default: false,
        type: Boolean
      },
      // 每页显示条数
      pageSize: {
        default: 5,
        type: Number
      },
      // 可切换每页条数集合
      pageSizeList: {
        default: (() => [10, 20, 50, 100]),
        type: Array
      },
      pageLayout: {
        default: 'sizes, prev, pager, next',
        type: String
      }
    },
    mounted: function () {
    },
    watch: {
      // 监控表格数据修改 从新渲染表格
      tableData() {
        this.myTableData = this.tableData;
      },
      // 监听页面数据总数修改
      total() {
        this.myTotal = this.total;
      },
      // 修改每页条数
      pageSize() {
        this.myPageSize = this.pageSize;
      }
    },
    methods: {
      selectionChange(choosetr) {
        this.checkTrData = choosetr;
      },
      sizeChange(size) {
        this.$emit('sizeChange', size);
      },
      getChooseData() {
        return this.checkTrData;
      },
      //分页
      pageChange(pageIndex){
        this.$emit('pageChange',pageIndex);
      },
      
      // 格式化处理数据内容  后面日期格式化换成第三方插件
      // rowData: row, column, cellValue, index
      // fieldData 字段信息
      formatter(row, column, cellValue, index, fieldData) {
        //console.log(fieldData.fieldType);
        if (fieldData.fieldType === 'date') {
          const date = new Date(Number(cellValue));
          return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}`;
        }
        return cellValue;
      }
    }
  }

</script>

<style scoped="">
</style>

TableComponent

<template>
  <!-- 主机记录 -->
  <div>
    <Table
      :fieldData="fieldData"
      :tableData="tableData"
      :page="true"
      @pageChange="pageChange"
      @sizeChange="sizeChange"
      :total="total"
    >
        <el-table-column
          slot="opts"
          label="操作"
          width="100">
          <template slot-scope="scope">
            <el-button type="text" size="small">查看</el-button>
          </template>
        </el-table-column>
    </Table>
 
  </div>
</template>

<script>

  // 表格组件
  import Table from 'component/table'
  
  export default{
    components: {
      Table
    },
    data(){
      return {
        total: 0,        //总记录数
        currentPage:1,   //初始页
        pagesize:10,    // 每页的数据
        data:[],
        tableData: [],
        fieldData: [
          {
            field: 'title',
            label: '主机名',
            width: ''
          },
          {
            field: 'IP',
            label: 'IP地址'
          },
        ]
      }
    },
    props: {},
    mounted () {
      this.$store.commit('updateBreadcrumb', [
        {
          text: '首页',
          path: ''
        },
        {
          text: '主机列表',
          path: ''
        },
      ]);
    },
    created() 
    {
      this.gethosts();
    },
    methods: 
    {
      getChooseData()
       {
        //查看选中数据
        //console.log( this.$refs['testForm'].getChooseData() , '--getChooseDatar--');
      },
      pageChange(pageIndex) 
      {
        console.log("触发分页事件");
        console.log(pageIndex);
        this.currentPage=pageIndex;

        this.tableData=this.data.slice((this.currentPage-1)*this.pagesize,this.currentPage*this.pagesize);;
      },
      sizeChange(size)
      { 
        //触发每页显示的条数
        console.log("触发了改变每页显示条数");
        console.log(size);

        this.pagesize=size;
        this.tableData=this.data.slice((this.currentPage-1)*this.pagesize,this.currentPage*this.pagesize);
      },
      gethosts()
      {
        return this.$http.getAllHosts({},{notify: false})
          .then((data) => {
            //console.log(data);
            //console.log(this.pagesize);
            this.data=data;
            this.tableData=data.slice((this.currentPage-1)*this.pagesize,this.currentPage*this.pagesize);
            this.total=data.length;
        });
      }
    }
  }

</script>

<style scoped="">
</style>

业务子组件

 

实现把列中的数字变成字符串

<el-table
      :data="myTableData"
      border
      size="small"
      @selection-change="selectionChange">
      
      <el-table-column v-if="type == 'selection'"
           type="selection"
           label="选择"
           width="55">
      </el-table-column>
      
      <!-- 序号 -->
      <el-table-column v-if="type == 'index'"
           type="index" label="序号"
           width="55">
      </el-table-column>
      
      <!-- 单元格 -->
      <el-table-column v-html v-for="(item, index) in fieldData" :key="index"
         :label="item.label"
         :prop="item.field"
         :width="item.width"
         :sortable="item.sortable"
         :formatter="(row, column, cellValue, index) =>item.formatter(row, column, cellValue, index, item)"
      />
      <!-- 插槽 额外 操作按钮自己控制 -->
      <slot name="opts"></slot>
    </el-table>

通用表格组件

// 表格组件
  import Table from 'component/table'
  
  export default{
    components: {
      Table
    },
    data(){
      return {
        total: 0,        //总记录数
        currentPage:1,   //初始页
        pagesize:10,    // 每页的数据
        data:[],
        tableData: [],
        fieldData: [
          {
            field: 'title',
            label: '主机名',
            width: '',
            formatter:function(row, column, cellValue, index, item)
            {
              return cellValue;
            }
          },
          {
            field: 'IP',
            label: 'IP地址',
            formatter:function(row, column, cellValue, index, item)
            {
              return cellValue;
            }
          },
          {
            field: 'status',
            label: '状态',
            formatter:function(row, column, cellValue, index, item)
            {
              if(cellValue==0)
              {
                return "<el-button type='success'>正常</el-button>";
              }
              else if(cellValue==1)
              {
                return "<el-button type='info'>一般告警</el-button>";
              }
              else if(cellValue==2)
              {
                return "<el-button type='warning'>告警</el-button>";
              }
              else
              {
                return "<el-button type='danger'>异常</el-button>";
              }
            },

          },
        ]
      }
    }

业务表格

 

把列中的值转换成相应的html标签

  1.不要把需要变成模板的列传递到fieldData集合中

 

vue实现一个通用的分页列表_分页

2.在业务表的view中添加模板列即可

<template>
  <!-- 主机记录 -->
  <div>
    <Table
      :fieldData="fieldData"
      :tableData="tableData"
      :page="true"
      @pageChange="pageChange"
      @sizeChange="sizeChange"
      :total="total"
    >

    <el-table-column slot="opts" label="状态" prop="status">
       <template slot-scope="scope">                   
          <p v-if="scope.row.status=='1'">
               <el-button type="success">成功</el-button>
          </p>
           <p v-else-if="scope.row.status=='2'">
                <el-button type="success">成功</el-button>
           </p>
            <p v-else-if="scope.row.status=='3'">
                 作废
            </p>
            <p v-else-if="scope.row.status=='4'">
                 停用
            </p>                    
        </template>
     </el-table-column>

     <el-table-column
          slot="opts"
          label="操作"
          width="100">
          <template slot-scope="scope">
            <el-button type="text" size="small">查看</el-button>
          </template>
      </el-table-column>
    </Table>
 
  </div>
</template>

业务表vue

vue实现一个通用的分页列表_IP_02

 

实现通用分页排序删除过滤表格组件

<template>
  
  <div class="data-table">
    <el-table
      :data="myTableData"
      :default-sort="mysort"
      border
      size="small"
      @selection-change="selectionChange"
      >
      
      <el-table-column v-if="type == 'selection'"
           type="selection"
           label="选择"
           width="55">
      </el-table-column>
      
      <!-- 序号 -->
      <el-table-column v-if="type == 'index'"
           type="index" label="序号"
           width="55">
      </el-table-column>
      
      <!-- 单元格 -->
      <el-table-column  v-for="(item, index) in fieldData" :key="index"
         :label="item.label"
         :prop="item.field"
         :width="item.width"
         :sortable="item.sortable"
         :formatter="(row, column, cellValue, index) =>formatter(row, column, cellValue, index, item)"
      />
      <!-- 插槽 额外 操作按钮自己控制 -->
      <slot name="opts"></slot>
    </el-table>

    <el-pagination v-if="page"
       @current-change="pageChange"
       @size-change="sizeChange"
       :page-size="pageSize"
       :page-sizes="pageSizeList"
       background
       :layout="pageLayout"
       :total="myTotal">
    </el-pagination>
  </div>
  
</template>

<script>
  export default{
    components: {},
    data(){
      return {
        checkboxArr: [],
        radio: '',
        formObj: null,
        tableClassName: '',
        id: '',
        successFieldObj: {},
        checkTrData: [],  // 多选数据multipleSelection
        myTableData: this.tableData,
        myTotal: this.total,  // 总条数
        myPageSize: this.pageSize,  // ,每页条数
        mysort:this.tableSort //传递的默认排序规则
      }
    },
    props: {
      // 数据总条数
      total: {
        default: 0,
        type: Number
      },
      // 表格类型:带索引  选择框
      type: {
        default: '',
        type: String
      },
      // 字段集合
      fieldData: {
        default: (() => []),
        type: Array
      },
      // 表格数据集合
      tableData: {
        default: (() => []),
        type: Array
      },
      tableSort: {
        default:(() => {}),
        type: Object
      },
      // 是否需要分页
      page: {
        default: false,
        type: Boolean
      },
      // 每页显示条数
      pageSize: {
        default: 5,
        type: Number
      },
      // 可切换每页条数集合
      pageSizeList: {
        default: (() => [10, 20, 50, 100]),
        type: Array
      },
      pageLayout: {
        default: 'sizes, prev, pager, next',
        type: String
      }
    },
    mounted: function () {
    },
    watch: {
      // 监控表格数据修改 从新渲染表格
      tableData() {
        this.myTableData = this.tableData;
      },
      // 监听页面数据总数修改
      total() {
        this.myTotal = this.total;
      },
      // 修改每页条数
      pageSize() {
        this.myPageSize = this.pageSize;
      }
    },
    methods: {
      selectionChange(choosetr) {
        console.log(choosetr);//选中行的row对象
        this.checkTrData=choosetr;
      },
      sizeChange(size) {
        this.$emit('sizeChange', size);
      },
      getChooseData() {
         return this.checkTrData;
      },
      //分页
      pageChange(pageIndex){
        this.$emit('pageChange',pageIndex);
      },
      
      // 格式化处理数据内容  后面日期格式化换成第三方插件
      // rowData: row, column, cellValue, index
      // fieldData 字段信息
      formatter(row, column, cellValue, index, fieldData) {
        //console.log("formatter");
        if (fieldData.fieldType === 'date') {
          const date = new Date(Number(cellValue));
          return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}`;
        }
        return cellValue;
      }
    }
  }

</script>

<style scoped="">
</style>

通用子组件

<template>
  <!-- 主机记录 -->
  <div>
    <el-button type="danger" @click="batchdelete">批量删除</el-button>
    <el-button type="info" @click="addhost">添加</el-button>
    <Table
       ref="hoststable"
      :fieldData="fieldData"
      :tableData="tableData"
      :page="true"
      @pageChange="pageChange"
      @sizeChange="sizeChange"
      :total="total"
      type="selection"
      :tableSort="tablSort"
    >

    <el-table-column slot="opts" label="状态" prop="status"
    :filters="[{ text: '成功', value: '1' }, { text: '告警', value: '2' }]"
     :filter-method="filterTag">
       <template slot-scope="scope">                   
          <p v-if="scope.row.status=='1'">
               <el-button type="success">成功</el-button>
          </p>
           <p v-else-if="scope.row.status=='2'">
                <el-button type="info">告警</el-button>
           </p>
            <p v-else-if="scope.row.status=='3'">
                <el-button type="warning">严重告警</el-button>
            </p>
            <p v-else-if="scope.row.status=='4'">
                <el-button type="danger">异常</el-button>
            </p>                    
        </template>
     </el-table-column>
     <el-table-column slot="opts" label="状态2" prop="status">
       <template slot-scope="scope">
        <el-tag
          :type="scope.row.status === 2 ? 'primary' : 'success'"
          disable-transitions>{{scope.row.status}}</el-tag>
      </template>
     </el-table-column>

     <el-table-column
          slot="opts"
          label="功能操作"
          width="150">
          <template slot-scope="scope">
            <el-button type="text" size="small"  @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
            <el-button type="text" size="small">操作日志</el-button>
            <el-button type="text" size="small">删除</el-button>
          </template>
      </el-table-column>
    </Table>
 
  </div>
</template>

<script>

  // 表格组件
  import Table from 'component/table'
  
  export default{
    components: {
      Table
    },
    data(){
      return {
        total: 0,        //总记录数
        currentPage:1,   //初始页
        pagesize:10,    // 每页的数据
        data:[],
        tablSort:{prop:'id', order:'descending'},//默认排序规则
        tableData: [],
        fieldData: [
         {
            field: 'id',
            label: '编号'
          },
          {
            field: 'title',
            label: '主机名',
            sortable:true     //设置可以按这个字段排序
          },
          {
            field: 'IP',
            label: 'IP地址',
            sortable:true
          }
        ]
      }
    },
    props: {},
    mounted () {
      this.$store.commit('updateBreadcrumb', [
        {
          text: '首页',
          path: ''
        },
        {
          text: '资产管理',
          path: ''
        },
        {
          text: '主机列表',
          path: ''
        }
      ]);
    },
    created() 
    {
      this.gethosts();
    },
    methods: 
    {
      getChooseData()
      {
         //查看选中数据
         console.log(this.$refs['hoststable']);
         console.log(this.$refs['hoststable'].getChooseData());
         const rows=this.$refs['hoststable'].getChooseData();
         return rows;
         // if (rows.length>0) 
         // {
         //   rows.forEach(row => {
         //       console.log(row.IP);
         //   });
         // } 
         // else 
         // {
         //   console.log("没有选中任何行");
         // }
      },
      batchdelete()
      {
         const rows=this.getChooseData();
         if (rows.length>0) 
         {
           rows.forEach(row => {
               console.log(row.IP);
           });
           this.$message({
            type: 'sucess',
            message: "批量删除成功"
          });
         } 
         else 
         {
           this.$message({
            type: 'error',
            message: "没有选中任何行"
          });
         }
      },
      pageChange(pageIndex) 
      {
        console.log("触发分页事件");
        console.log(pageIndex);
        this.currentPage=pageIndex;

        this.tableData=this.data.slice((this.currentPage-1)*this.pagesize,this.currentPage*this.pagesize);;
      },
      sizeChange(size)
      { 
        //触发每页显示的条数
        console.log("触发了改变每页显示条数");
        console.log(size);

        this.pagesize=size;
        this.tableData=this.data.slice((this.currentPage-1)*this.pagesize,this.currentPage*this.pagesize);
      },
      gethosts()
      {
        return this.$http.getAllHosts({},{notify: false})
          .then((data) => {
            //console.log(data);
            //console.log(this.pagesize);
            this.data=data;
            this.tableData=data.slice((this.currentPage-1)*this.pagesize,this.currentPage*this.pagesize);
            this.total=data.length;
        });
      },
      handleEdit(index, row) {
        console.log(index, row);
        this.$message({
            type: 'success',
            message: row.id
          });
      },
      handleDelete(index, row) {
        console.log(index, row);
      },
      filterTag(value,row,column) {
        const property = column['property'];
        console.log("....过滤开始.....");
        console.log(value);
        console.log(row);
        console.log(column);
        console.log(".....过滤结束....");
        return row.status === value;
      },
      addhost()
      {
        this.$router.push('/exec'); //http://127.0.0.1:9000/#/exec
        //this.$router.push('exec');//http://127.0.0.1:9000/#/host/exec
      }
    }
  }

</script>

<style scoped="">
</style>

业务表格组件

 

添加一个路由跳转

addhost()
      {
        this.$router.push('add'); //http://127.0.0.1:9000/#/host/add
        
       //this.$router.push('/add');//http://127.0.0.1:9000/#/add
      }

跳转点击按钮

import Vue from 'vue';
import Router from 'vue-router';
import Hosts from './index'
import HostAdd from './hostAdd'
Vue.use(Router);

export default [
  {
    path: '/host/list',
    name: 'hosts',
    component: Hosts
  },
  {
      path: '/host/add',
      name: 'hostAdd',
      component: HostAdd
  }
];

路由配置router.js

<template>
  <!-- 添加主机记录 -->
  <div>
    <el-button type="danger">进入添加主机页面</el-button>
  </div>
</template>

<script>

  
  export default{
    components: {
    },
    data(){
      return {}
    },
    props: {},
    mounted () {
      this.$store.commit('updateBreadcrumb', [
        {
          text: '首页',
          path: ''
        },
        {
          text: '资产管理',
          path: '/host/list'
        },
        {
          text: '添加主机',
          path: ''
        }
      ]);
    },
    created() 
    {
    },
    methods: 
    {
      
    }
  }
</script>

<style scoped="">
</style>

视图代码add.vue

 

vue传递属性的两种方式

  1.<el-dialog   :custom-class="mydailog">

vue实现一个通用的分页列表_IP_03

必须在data里面设置相关值

data() {
   return {     formLabelWidth:"120px",
      mydailog:"mydailog"  }
}
  2.<el-dialog   custom-class="mydailog"> 不需要在data对象中设置任何键值对
  <style>   不能写成  <style scoped> 否则不会生效
     .mydailog
      {
       color:red;
      }
  </style>  <style> 
     .mydailog
      {
       color:red;
      }
   </style>

vue组件实现自定义css样式 

引入custom-class属性
 
<el-dialog
  title="添加分组"
  :visible.sync="centerDialogVisible"
  width="30%"
  center
  custom-class="mydailog">
    <el-form>
    <el-form-item label="分组名称" :label-width="formLabelWidth">
      <el-input v-model="input" autocomplete="off"></el-input>
    </el-form-item>
  </el-form>
  <span slot="footer" class="dialog-footer">
    <el-button @click="centerDialogVisible =false">取 消</el-button>
    <el-button type="primary" @click="centerDialogVisible = false">确 定</el-button>
  </span>
</el-dialog>

模板代码

style标签一定不能加scope属性 否则不会生效

<style>
   .mydailog
   {
     text-align:center;
     background:red;
   }
</style>

style

 

vue实现table等待远程数据加载

<bee-table :data="logList"
               :column-config="LOG_TABLE_COLUMN"
               :pageIndex="currentPage1"
               :pageSize="pageSize"
               @size-change="handleSizeChange"
               @current-change="handleCurrentChange"
               @sort-change="handleSortChange"
               v-loading="tbflag"
               :total="total">
               <template slot="operation" slot-scope="{scope}">
                  <el-tooltip class="item" effect="dark" :content="scope.row.jylsh" placement="top-start">
                   <a @click="showDetail(scope.row.jylsh)">
                    {{scope.row.jylsh}}
                   </a>
                  </el-tooltip>
               </template>
              </bee-table>



 data(){
      return {
         // 当前页
        currentPage1: 1,
        // 每页条数
        pageSize: 10,
        // 总条数
        total: 0,
         // 主机列表数据
        tableData: [],
   
        tbflag:false
      };

table

getHostMonitorView()
      {
        Promise.all([
            this.getHostCpuView()
       ]).then(() => {
           this.loading = false;
       });
      },
 getHostlogs(){
         this.tbflag=true;
         return this.$http.getHostLogs({
          "appname":this.appname,
          "startTime":this.startTtime,
          "endTime":this.endTime,
          "hostname":this.selectRowHostName,
          "pageIndex":this.currentPage1,
          "pageSize":this.pageSize,
          "sortColumn":this.sortColumn,
          "sortType":this.sortType
         },{notify:true})
        .then((data) => {
             this.logList=data.list;
             this.total=data.total; 
        }).finally(()=>{
           this.tbflag=false;
        });
 }

js