vue实现指定区域自由拖拽、打印功能
先看下效果图,实现指定区域内内容自由拖拽,不超出。动态设置字体颜色及字号;设置完成实现打印指定区域内容,样式不丢失。1、运行命令npm i vue-draggable-resizable -S, 安装拖拽插件vue-draggable-resizable,并引入使用(下面引入是放入main.js文件中)import VueDraggableResizable from 'vue-draggable
·
先看下效果图,实现指定区域内内容自由拖拽,不超出。动态设置字体颜色及字号;设置完成实现打印指定区域内容,样式不丢失。
1、运行命令npm i vue-draggable-resizable -S
, 安装拖拽插件vue-draggable-resizable,并引入使用(下面引入是放入main.js文件中)
import VueDraggableResizable from 'vue-draggable-resizable'
// optionally import default styles
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'
Vue.component('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-resizable
parent=".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.innerHTML
const oldContent = document.body.innerHTML
document.body.innerHTML = newContent
window.print()
window.location.reload()
document.body.innerHTML = oldContent
return 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-resizable
parent=".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.innerHTML
const oldContent = document.body.innerHTML
document.body.innerHTML = newContent
window.print()
window.location.reload()
document.body.innerHTML = oldContent
return false
},
onResize: function(x, y, width, height) {
this.x = x
this.y = y
this.width = width
this.height = height
},
onDrag: function(x, y) {
this.x = x
this.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') { this.commonMethod('fontSize') }
if (this.form.name && this.form.fontSize && this.form.selectVal === 'lineHeight') { this.commonMethod('lineHeight') }
if (this.form.name && this.form.color) { this.commonMethod('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>
更多推荐
已为社区贡献13条内容
所有评论(0)