拖拽打印等功能javascript
拖拽大概有兩種(onmousemove,ondrag),簡單的具體思路都是,記錄下開始點,再獲取到結束點,交換完事css
在表頭右邊加個自定義下拉按鈕html
打印瀏覽器不是有麼,調用print()就能夠,打印表格估計就是把表格這塊摳出來,弄到個新文檔,打印vue
是後臺排序,那我就只要監聽個事件回調,調後臺就能夠了java
因爲老衲過於菜雞,保守起見,仍是先來查查別人是怎麼弄的吧git
參考(fuzhi)地址github
拖拽chrome
打印瀏覽器
<template>
<div>
<div ref="template">
<slot>
</slot>
</div>
<button v-if="buttonShow" @click="print" type="button" :class="buttonClass">
<span>開始打印</span>
</button>
</div>
</template>
複製代碼
export default {
props: {
// 是否顯示默認的打印按鈕
buttonShow: {
type: Boolean,
default: false
},
buttonClass: {
type: String,
default: 'el-button el-button--default'
}
},
mounted () {
this.init()
},
methods: {
init () {
let printI = document.getElementById('easyPrintIframe')
if (!printI) {
printI = document.createElement('iframe')
printI.id = 'easyPrintIframe'
printI.style.position = 'fixed'
printI.style.width = '0'
printI.style.height = '0'
printI.style.top = '-100px'
// 兼容ie
if (
window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)
) {
printI.src = 'javascript:document.write("<head><script>document.domain="' + document.domain + '";</s' + 'cript></head><body></body>")'
}
printI.onload = () => {
this.getStyle()
}
document.body.appendChild(printI)
} else {
this.getStyle()
}
},
print () {
if (typeof this.beforeCopy === 'function') {
// 檢測到有複製前須要執行的功能
this.beforeCopy()
}
let $iframe = document.getElementById('easyPrintIframe')
// 複製body,打印內容
$iframe.contentDocument.body.innerHTML = this.$refs.template.innerHTML
if (typeof this.beforePrint === 'function') {
// 檢測到有打印前須要執行的功能
// 好比有些二維碼組件沒法直接複製dom完成。
this.beforePrint()
}
setTimeout(() => {
$iframe.contentWindow.print()
}, 100)
},
getStyle () {
let mystyle = ``
let printI = document.getElementById('easyPrintIframe')
var str = ''
var styles1 = document.querySelectorAll('style')
for (var i = 0; i < styles1.length; i++) {
str += styles1[i].outerHTML
}
// console.log(str)
printI.contentDocument.head.innerHTML = str + mystyle
// 添加link引入
let styles = document.querySelectorAll('link')
for (let i = 0; i < styles.length; i++) {
// chrome 正常,firefox不正常,能執行到,可是添加沒結果
let link = document.createElement('link')
link.setAttribute('rel', 'stylesheet')
if (styles[i].type) link.setAttribute('type', styles[i].type)
else link.setAttribute('type', 'text/css')
link.setAttribute('href', styles[i].href)
link.setAttribute('media', 'all')
printI.contentDocument.head.appendChild(link)
}
}
}
}
複製代碼
<template>
<div>
<div class="w-table" :class="{'w-table_moving': dragState.dragging}">
<div class="edit">
<el-dropdown type="primary" size="small" trigger="click">
<span class="el-dropdown-link">
<i class="el-icon-edit"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="(item, index) in tableHeaderBackup" :key="index">
<div>
<el-checkbox v-model="item.show" @change="init">{{item.label}}</el-checkbox>
</div>
</el-dropdown-item>
<el-dropdown-item style="padding:10px 15px 8px;">
<el-button @click="print" type="primary" style="width:100%;" icon="el-icon-download" size="small">打印</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<easy-print ref="print">
<el-table ref="table" row-key="id" :data="tableData" :header-cell-class-name="headerCellClassName" :cell-class-name="cellClassName" :style="`width: 100%`" >
<template v-for="(col, index) in tableHeaderYes ">
<el-table-column v-if="col.show" :key="index" :prop="col.prop" :label="col.label" :width="col.width" :min-width="col.minWidth" :type="col.type" :header-align="col.headerAlign" :column-key="index.toString()" :render-header="renderHeader" >
<template slot-scope="scope" >
<div v-if="col.format" v-html="col.format(scope.row[col.prop])"></div>
<div v-else>{{scope.row[col.prop]}}</div>
</template>
</el-table-column>
</template>
</el-table>
</easy-print>
</div>
</div>
</template>
複製代碼
export default {
data () {
return {
dragState: {
start: -9, // 起始元素的 index
end: -9, // 移動鼠標時所覆蓋的元素 index
dragging: false, // 是否正在拖動
},
tableHeaderBackup: [], //備份完整的tableHeader
tableHeaderYes: [],// 須要在表頭顯示的
tableHeaderNo: [], // 暫時不顯示的
tableHeader: [
{
prop: 'name',
label: '油站名稱',
show: true,
minWidth: '120'
},
{
prop: 'address',
label: '油站地址',
sort: 1,
show: true,
minWidth: '120'
},
{
prop: 'header',
label: '油站負責人',
sort: 1,
show: true,
minWidth: '120'
},
{
prop: 'headerPhone',
label: '負責人電話',
sort: 1,
show: true,
minWidth: '120'
},
{
prop: 'updateTime',
label: '更新時間',
sort: 1,
show: true,
minWidth: '120'
}
],
tableData: []
}
},
mounted () {
this.tableHeaderBackup = this.$tool._deepCopy(this.tableHeader)
this.init()
},
methods: {
init () {
this.tableHeaderYes = this.tableHeaderBackup.filter(i => i.show)
this.tableHeaderNo = this.tableHeaderBackup.filter(i => !i.show)
},
renderHeader (createElement, { column, $index }) {
return createElement(
'div',
{
class: ['thead-cell-box'],
on: {
mousedown: $event => {},
mousemove: $event => {}
}
},
[
createElement(
'span',
{
class: ['thead-cell1']
},
column.label
),
createElement('span', {
class: ['thead-cell'],
on: {
mousedown: $event => {
this.handleMouseDown($event, column)
},
mousemove: $event => {
this.handleMouseMove($event, column)
}
}
}),
createElement(
'span',
{
class: {
'thead-cell2': true,
'caret-wrapper': true,
hidden: !this.tableHeaderYes[$index].sort,
ascending: this.tableHeaderYes[$index].sort === 2,
descending: this.tableHeaderYes[$index].sort === 3
},
on: {
click: $evnet => {
this.clickHandler($evnet, column, $index)
}
}
},
[
createElement(
'i',
{
class: ['sort-caret', 'ascending']
}
),
createElement(
'i',
{
class: ['sort-caret', 'descending']
}
)
]
)
]
)
},
handleMouseDown (e, column) {
this.dragState.dragging = true
this.dragState.start = parseInt(column.columnKey)
document.addEventListener('mouseup', this.handleMouseUp)
},
handleMouseUp () {
// 初始化拖動狀態
this.dragState.start = -9
this.dragState.end = -9
this.dragState.dragging = false
document.removeEventListener('mouseup', this.handleMouseUp)
},
handleMouseMove (e, column) {
if (this.dragState.dragging) {
let index = parseInt(column.columnKey) // 記錄起始列
if (index - this.dragState.start !== 0) {
this.dragState.end = parseInt(column.columnKey)
this.dragColumn(this.dragState) // 換位置
}
} else {
return false
}
},
dragColumn ({ start, end, direction }) {
const tableHeaderYes = this.$tool._deepCopy(this.tableHeaderYes)
//交換位置
const startObj = tableHeaderYes[start]
this.tableHeaderYes.splice(start, 1)
this.tableHeaderYes.splice(end, 0, startObj)
this.tableHeaderBackup = this.tableHeaderYes.concat(this.tableHeaderNo)//合併從新設置表頭
this.dragState.dragging = false
this.$nextTick(() => {
this.dragState.dragging = true
this.dragState.start = end
this.dragState.end = start
})
},
// 拖拽樣式的設置
headerCellClassName ({ column, columnIndex }) {
if (this.showSelection) columnIndex--
if (this.showExpand) columnIndex--
let active =
columnIndex === this.dragState.end
? `darg_active_${this.dragState.direction}`
: ''
let start = columnIndex === this.dragState.start ? `darg_start` : ''
return `${active} ${start}`
},
cellClassName ({ column, columnIndex }) {
if (this.showSelection) columnIndex--
if (this.showExpand) columnIndex--
return columnIndex === this.dragState.start ? `darg_start` : ''
},
//打印包住區域
print () {
this.$refs.print.print()
},
// 點擊表頭排序回調事件 1是默認,2升序,3降序
clickHandler (e, c, i) {
this.tableHeaderYes.map((item, index) => {
if (i === index) {
item.sort++
if (item.sort >= 4) {
item.sort = 1
}
} else if (item.sort) {
item.sort = 1
}
})
console.log(c.property, this.tableHeaderYes[i].sort)// 字段名,排序狀態
}
}
}
複製代碼
.w-table {
position: relative;
.edit {
position: absolute;
right: 0;
top: 0;
z-index: 10;
.el-dropdown-link {
cursor: pointer;
background: #fff;
color: #1890ff;
font-size: 20px;
border: 1px solid #dfe6ec;
box-sizing: border-box;
height: 40px;
width: 40px;
display: flex;
justify-items: center;
align-content: center;
}
i {
margin: 0;
width: 40px;
text-align: center;
line-height: 40px;
}
}
.cell {
transition: all ease 0.2s;
}
.el-table {
thead {
th{
transition: all ease 0.2s;
&:hover{
background: #ddd;
}
}
.cell{
line-height: 40px;
}
.darg_start {
background: #999 !important;
cursor: move;
.cell{
color: #fff;
}
}
}
}
.el-table th {
padding: 0;
.thead-cell-box {
display: block;
position: relative;
white-space: normal;
}
.thead-cell {
cursor:copy;
position: absolute;
top: 0;
left: -10px;
bottom: 0;
right: 0;
}
.thead-cell2 {
width: 35px;
}
.thead-cell1 {
display: inline-block;
position: relative;
white-space: normal;
font-weight: 800;
line-height: 22px;
}
&.w-table_moving {
.el-table th .thead-cell {
cursor: move !important;
}
.el-table__fixed {
cursor: not-allowed;
}
}
}
複製代碼
搞完收工,200到手,下班下班,明天再來封裝成組件app
轉載記錄地址連接