先看下效果图,实现指定区域内内容自由拖拽,不超出。动态设置字体颜色及字号;设置完成实现打印指定区域内容,样式不丢失。
1、运行命令npm i vue-draggable-resizable -S
, 安装拖拽插件vue-draggable-resizable,并引入使用(下面引入是放入main.js文件中)
import VueDraggableResizable from 'vue-draggable-resizable'// optionally import default stylesimport 'vue-draggable-resizable/dist/VueDraggableResizable.css'ponent('vue-draggable-resizable', VueDraggableResizable)
2、 实现指定区域内自由拖拽代码:
<div class="p-event" id="print" style="border: 1px solid red; box-sizing: border-box; height: 500px; width: 900px;"><template v-for="(item, index) in list"><vue-draggable-resizableparent=".p-event":grid="[10,10]":x="item.x":y="item.y":left="form.paddingLeft":key="item+index":parent="true"w="auto"h="auto"@dragging="onDrag"@resizing="onResize"><p :style="{ fontSize: item.fontSize, color: item.color, lineHeight: item.lineHeight }">{{ item.name }}</p></vue-draggable-resizable></template></div>
class=“p-event”, parent=".p-event", :parent=“true” 是为了设置父元素,且拖拽区域不能超过父元素。
x与y采用随机数,是为了初次进入,不会多个数据不会挤在左上角。
2、打印指定区域内内容
/** 打印方法 */doPrint() {const subOutputRankPrint = document.getElementById('print')const newContent = subOutputRankPrint.innerHTMLconst oldContent = document.body.innerHTMLdocument.body.innerHTML = newContentwindow.print()window.location.reload()document.body.innerHTML = oldContentreturn false},
去掉页头页尾
<style media="print" scoped>/** 去掉页头和页尾 */@page {size: auto; /* auto is the initial value */margin: 0mm; /* this affects the margin in the printer settings */}</style>
整体代码如下:
<template><div style="padding:30px;"><h1>拖拽</h1><el-button @click="doPrint">打印</el-button><el-form ref="form" :model="form" label-width="80px"><el-form-item label="字号设置"><el-row :gutter="20"><el-col :span="4"><el-select v-model="form.name" @change="changeName();changeVal()"><el-option v-for="(item,index) in list" :label="item.label" :key="index+item.label" :value="item.name"></el-option></el-select></el-col><el-col :span="4"><el-select v-model="form.selectVal" @change="changeHeight"><el-option label="字体大小" value="fontSize"></el-option><el-option label="行高设置" key="index+item.value" value="lineHeight"></el-option></el-select></el-col><el-col :span="4"><el-select v-model="form.fontSize" @change="changeVal"><el-option v-for="(item,index) in sizeList" :key="index+item.value" :label="item.label" :value="item.value"></el-option></el-select></el-col><el-col :span="4"><el-color-picker v-model="form.color" @change="changeVal"></el-color-picker></el-col></el-row></el-form-item></el-form><div class="p-event" id="print" style="border: 1px solid red; box-sizing: border-box; height: 500px; width: 900px;"><template v-for="(item, index) in list"><vue-draggable-resizableparent=".p-event":grid="[10,10]":x="item.x":y="item.y":left="form.paddingLeft":key="item+index":parent="true"w="auto"h="auto"@dragging="onDrag"@resizing="onResize"><p :style="{ fontSize: item.fontSize, color: item.color, lineHeight: item.lineHeight }">{{ item.name }}</p></vue-draggable-resizable></template></div></div></template><script>export default {data: function() {return {width: 0,height: 0,x: 0,y: 0,form: {name: '',fontSize: '',selectVal: '',color: '',paddingTop: 20,paddingBottom: 0,paddingLeft: 0,paddingRight: 0},sizeList: [], // 字体号数组apiArr: [ // 后期从接口中获取name集合{name: '公司名称' },{name: '抬头' },{name: '公司简介' }],list: [] // apiArr带上所有属性的集合}},mounted() {// 字号数组获取for (let i = 12; i <= 48; i++) {this.sizeList.push({label: `${i}px`, value: `${i}px` })}// 网格上的数据获取for (const it of this.apiArr) {this.list.push({name: it.name, // 表名对应的值label: it.name, // 表名fontSize: '16px', // 默认字体lineHeight: 'normal', // 默认行高color: '#000000', // 默认颜色x: Math.floor(Math.random() * (800 - 10)) + 10, // x默认值y: Math.floor(Math.random() * (450 - 10)) + 10 // y 默认值})}},methods: {/** 打印方法 */doPrint() {const subOutputRankPrint = document.getElementById('print')const newContent = subOutputRankPrint.innerHTMLconst oldContent = document.body.innerHTMLdocument.body.innerHTML = newContentwindow.print()window.location.reload()document.body.innerHTML = oldContentreturn false},onResize: function(x, y, width, height) {this.x = xthis.y = ythis.width = widththis.height = height},onDrag: function(x, y) {this.x = xthis.y = y},/** 选择列下拉框 */changeName() {this.form.fontSize = ''this.form.color = ''},changeHeight() {this.form.fontSize = ''},/** 下拉框改变的时候进行动态设置样式 */changeVal() {if (this.form.name && this.form.fontSize && this.form.selectVal === 'fontSize') {monMethod('fontSize') }if (this.form.name && this.form.fontSize && this.form.selectVal === 'lineHeight') {monMethod('lineHeight') }if (this.form.name && this.form.color) {monMethod('color') }},/** 公共的设置样式方法 */commonMethod(val) {for (const it of this.list) {if (it.label === this.form.name) {if (val === 'lineHeight') {it[val] = this.form.fontSize} else {it[val] = this.form[val]}}}}}}</script><style scoped>/** 这里vdr的样式设置是为了当没有选中目标文字时,去掉默认的虚线框,只有选中的时候才有虚线框 */.vdr {border: none;}.handle, .active.vdr {border: 1px dashed #000;}#print {position: relative;/** 网格样式 */background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px) 0% 0% / 10px 10px, linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px) 0% 0% / 10px 10px;}</style><style media="print" scoped>/** 去掉页头和页尾 */@page {size: auto; /* auto is the initial value */margin: 0mm; /* this affects the margin in the printer settings */}</style>