# 自定义表格内外边框颜色

# 问题描述

在我们使用饿了么 UI 框架做项目的时候,el-table 的自带的表格边框颜色有时候需要修改一下。本文简述一下修改 el-table 边框样式的注意事项。

# 初始代码

<template>
  <div id="app">
    <el-table 
      :data="tableData" 
      style="width: 40%" 
      border
    >
      <el-table-column prop="name" label="姓名" width="180"></el-table-column>
      <el-table-column prop="nation" label="国别" width="180"></el-table-column>
      <el-table-column prop="bornPlace" label="出生地方"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: "app",
  data() {
    return {
      tableData: [
        {
          name: "刘备",
          nation: "蜀国",
          bornPlace: "涿郡涿县(河北省涿州市)",
        },
        {
          name: "曹操",
          nation: "魏国",
          bornPlace: "沛国谯县(安徽省亳州市)",
        },
        {
          name: "孙权",
          nation: "吴国",
          bornPlace: "吴郡富春县(浙江省杭州市富阳区)",
        },
        {
          name: "关羽",
          nation: "蜀国",
          bornPlace: "河东郡解县(山西省运城市盐湖区解州镇)",
        },
      ],
    };
  },
};
</script>

# 初始效果

image

# 第一步,加入单元格的回调

# 代码如下

image

# 效果如下

image

# 第二步,加入表头的回调

# 代码如下

image

# 效果如下

image

# 第三步,单独给表格加样式

# 代码如下

image
image

# 效果如下

image

# 表格自适应宽

<template>
<!-- 表格的自适应宽 -->
<div class="container">
   <h2>All Columns auto-fit</h2>
   <el-button @click="handleAddColumn" type="primary">Add Column</el-button>
  <el-button @click="handleAddRows" type="success">Add Row</el-button>
  <el-table
    :data="data"
    border
    auto-fit-column
  >
    <el-table-column
      label="姓名2222"
      prop="name"
      fixed
    ></el-table-column>
    <el-table-column
      label="年龄3333"
      prop="age"
    ></el-table-column>
    <el-table-column
      v-for="(option, index) in options"
      :label="option.label"
      :prop="option.prop"
      :key="index"
      sortable
      auto-fit
    ></el-table-column>
    <el-table-column
      label="年龄"
      width="100"
    >
      <template slot="header">
        <el-input
          v-model="search"
          size="mini"
          placeholder="Type to search"/>
      </template>
    </el-table-column>
  </el-table>
  <h2>Max-width</h2>
  <el-table
    :data="data"
    border
    auto-fit-column
  >
    <el-table-column
      label="姓名2222"
      prop="name"
      fixed
    ></el-table-column>
    <el-table-column
      label="年龄3333"
      prop="age"
      :max-width="130"
    ></el-table-column>
    <el-table-column
      v-for="(option, index) in options"
      :label="option.label"
      :prop="option.prop"
      :key="index"
      :max-width="100"
      sortable
      auto-fit
    ></el-table-column>
    <el-table-column
      label="年龄"
      width="100"
    >
      <template slot="header">
        <el-input
          v-model="search"
          size="mini"
          placeholder="Type to search"/>
      </template>
    </el-table-column>
  </el-table>
  <h2>Some Columns auto-fit (name & age)</h2>
  <el-button @click="handleAddColumn" type="primary">Add Column</el-button>
  <el-button @click="handleAddRows" type="success">Add Row</el-button>
  <el-table
    :data="data"
    border
    auto-fit-column
    :fit-styles="styles"
    :fit-columns="['name', 'age', 'salary']"
  >
    <el-table-column
      label="Name"
      prop="name"
      fixed
    ></el-table-column>
    <el-table-column
      label="Age"
      prop="age"
    ></el-table-column>
    <el-table-column
      label="Salary"
      prop="salary"
      :formatter="formatter"
    ></el-table-column>
    <el-table-column
      v-for="(option, index) in options"
      :label="option.label"
      :prop="option.prop"
      :key="index"
      sortable
      auto-fit
    ></el-table-column>
    <el-table-column
      label="年龄"
      width="100"
    >
      <template slot="header">
        <el-input
          v-model="search"
          size="mini"
          placeholder="Type to search"/>
      </template>
    </el-table-column>
  </el-table>
   <h2>Show Summary</h2>
  <el-button @click="handleAddColumn" type="primary">Add Column</el-button>
  <el-button @click="handleAddRows" type="success">Add Row</el-button>
  <el-button @click="handleReverseColumn" type="success">Reverse Column</el-button>
  <el-button @click="handleDynamicAutoColumn" type="success">Dynamic auth-width Column</el-button>
  <el-table
    :data="data"
    border
    auto-fit-column
    show-summary
    :summary-method="summaryMethod"
    :fit-styles="styles"
    :fit-columns="fitColumns"
  >
    <el-table-column
      v-for="(column, cIndex) in autoWidthColumns"
      :label="column.label"
      :prop="column.name"
      :key="cIndex"
      :formatter="formatter"
      fixed
    ></el-table-column>
    <el-table-column
      v-for="(option, index) in options"
      :label="option.label"
      :prop="option.prop"
      :key="10 + index"
      sortable
      auto-fit
    ></el-table-column>
    <el-table-column
      label="年龄"
      width="100"
    >
      <template slot="header">
        <el-input
          v-model="search"
          size="mini"
          placeholder="Type to search"/>
      </template>
    </el-table-column>
  </el-table>
  <div class="copyright">&copy; www.kuaizi.ai</div>
</div>
</template>
<script>
const currency = (num, decimal = 2) => {
  let n = Number(num)
  let parts
  let hasDecimal = false
  if (num !== null && !isNaN(n)) {
    // 检测是否有小数点
    hasDecimal = /\.\d{1,}/g.test(num)
    // 精度
    n = hasDecimal ? n.toFixed(decimal) : String(n)
    parts = n.split('.')
    return `${parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',') + (hasDecimal ? '.' : '') + (parts[1] || '')}`.replace(/\.$/, '')
  }
  return '-'
}
export default {
  data () {
    return {
      search: '',
      data: [
        {
          name: '张三',
          age: 30,
          salary: 320000,
          remark: 'sdfsdfsdfsdfsdfsdff'
        },
        {
          name: '李四',
          age: 24,
          salary: 525000,
          remark: 'sdfsdfsdfsdfsdfsdff'
        }
      ],
      options: [],
      autoWidthColumns: [
        {
          name: 'name',
          label: 'Name'
        },
        {
          name: 'age',
          label: 'Age'
        },
        {
          name: 'salary',
          label: 'Salary'
        },
        {
          name: 'remark',
          label: 'Remark'
        }
      ],
      styles: {
        header: 'font-size: 14px; font-weight: bold; padding: 0 10px;',
        body: 'font-size: 14px; padding: 0 10px;'
      }
    }
  },
  computed: {
    fitColumns () {
      return this.autoWidthColumns.map(a => a.name)
    }
  },
  methods: {
    // formatter (row, column, cellValue, index) {
    formatter (row, column, cellValue) {
      if (column.property !== 'salary') return cellValue
      // 获取字段名
      // console.log(column.property)
      return currency(cellValue)
    },
    handleAddColumn () {
      this.options.push({ prop: 'remark', label: '备注', maxWidth: 130 })
    },
    handleAddRows () {
      this.data.push({
        name: 'tommyshao',
        age: 30,
        salary: 15000,
        remark: 'sdfsdfsdf什么备注,不准换行啊啊啊啊啊啊啊啊啊啊啊'
      })
    },
    summaryMethod ({ columns, data }) {
      const showSummaryCol = ['salary']
      const sums = []
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计'
          return
        }
        const values = data.map(item => Number(item[column.property]))
        if (!values.every(value => isNaN(value)) && showSummaryCol.includes(column.property)) {
          sums[index] = values.reduce((prev, curr) => {
            const value = Number(curr)
            if (!isNaN(value)) {
              return prev + curr
            } else {
              return prev
            }
          }, 0)
          sums[index] = currency(sums[index])
        } else {
          sums[index] = ''
        }
      })
      return sums
    },
    handleReverseColumn () {
      // this.autoWidthColumns =
      this.autoWidthColumns.reverse()
    },
    handleDynamicAutoColumn () {
      this.autoWidthColumns = [
        {
          name: 'remark',
          label: 'Remark'
        },
        ...this.autoWidthColumns.slice(0, 2)
      ]
    }
  }
}
</script>
<style>
.container {
  overflow-x: auto;
}
.el-table .cell {
  white-space: nowrap;
}
.copyright {
  text-align: center;
  margin: 100px 20px 20px;
  padding: 20px 0 0;
  border-top: 1px solid #e7e7e7;
}
</style>

# 分页效果

<el-col :span="24">
    <el-pagination
    layout="prev, pager, next"
    :page-size="device.ps"
    :total="device.trw"
    @current-change="pageChange"
    />
 </el-col>
pageChange(pn) {
   loadDevices(this, pn);
},

分页效果使用在 element ui 的表格中,表格数据过多时,使它可以点击下一页。实现翻页,让页面美化。上面代码中, layou t 是组件的布局,其中 prev 是表示上一页,默认是一个箭头。可以换为 prev-test + 文字,自定义文字。反之 next 。中间的 pager 是组件的主体部分,显示一共几页。要给分页按钮添加颜色使用 background 属性即可。page-size 每页显示条目个数,即每页多少行。total 总的条目数,一共有多少行。pn 代表当前行。点击方法,点击以换分页显示数据。ps 代表每页可以显示多少行。

# Element Ui,实现表格左右拖动滑动

直接在 main.js 中全局添加
使用:在 el-table 组件里面加上组件: v-tableMove 即可。
代码:

// 全局添加 table 左右拖动效果的指令
	Vue.directive('tableMove', {
	  bind: function(el, binding, vnode) {
		var odiv = el // 获取当前表格元素
		// 修改样式小手标志
		// el.style.cursor = 'pointer'
		el.querySelector('.el-table .el-table__body-wrapper').style.cursor = 'pointer'
		var mouseDownAndUpTimer = null
		var mouseOffset = 0
		var mouseFlag = false
		odiv.onmousedown = (e) => {
		  const ePath = composedPath(e)
		  // 拖拽表头不滑动
		  if (ePath.some(res => { return res && res.className && res.className.indexOf('el-table__header') > -1 })) return
		  if (e.which !== 1) return
		  mouseOffset = e.clientX
		  mouseDownAndUpTimer = setTimeout(function() {
			mouseFlag = true
		  }, 80)
		}
		odiv.onmouseup = (e) => {
		  setTimeout(() => {
			// 解决拖动列宽行不对齐问题 -- 渲染表格
			vnode.context.$refs['yourRefName'].doLayout()
		  }, 200)
		  if (mouseFlag) {
			mouseFlag = false
		  } else {
			clearTimeout(mouseDownAndUpTimer) // 清除延迟时间
		  }
		}
		odiv.onmouseleave = (e) => {
		  setTimeout(() => {
			// 解决拖动列宽行不对齐问题 -- 渲染表格
			vnode.context.$refs['yourRefName'].doLayout()
		  }, 200)
		  mouseFlag = false
		}
		odiv.onmousemove = (e) => {
		  if (e.which !== 1) return
		  const divData = odiv.querySelector('.el-table .el-table__body-wrapper')
		  if (mouseFlag && divData) {
			// 设置水平方向的元素的位置
			divData.scrollLeft -= (-mouseOffset + (mouseOffset = e.clientX))
		  }
		}
		// 解决有些时候,在鼠标松开的时候,元素仍然可以拖动;
		odiv.ondragstart = (e) => {
		  e.preventDefault()
		}
		odiv.ondragend = (e) => {
		  e.preventDefault()
		}
		// 是否拖拽可选中文字
		odiv.onselectstart = () => {
		  return false
		}
		// 浏览器 Event.path 属性不存在
		function composedPath(e) {
		  // 存在则直接 return
		  if (e.path) { return e.path }
		  // 不存在则遍历 target 节点
		  let target = e.target
		  e.path = []
		  while (target.parentNode !== null) {
			e.path.push(target)
			target = target.parentNode
		  }
		  // 最后补上 document 和 window
		  e.path.push(document, window)
		  return e.path
		}
	  }
	)