vue2使用markdown编辑器
安装
npm install mavon-editor --save
全局引入(main)
import mavonEditor from 'mavon-editor' //引入mavon-editor组件
import 'mavon-editor/dist/css/index.css' //引入组件的样式
Vue.use(mavonEditor)
vue2 使用打印功能
安装
npm install vue-print-nb --save
全局引入(main)
//引入打印机插件
import Print from 'vue-print-nb'
//注册
Vue.use(Print); //注册
组件应用
<template>
<div class="bg-white p-5">
<!-- 给要打印的区块添加一个id,这时候给点击打印的按钮添加一个指令v-print,指定为要打印的区域id即可 -->
<div class="flex justify-end">
<el-button v-print="printObj" size="mini" type="primary">打印</el-button>
</div>
<div id="printTest" >
<h3 style="text-align: center;">虚惊轻微事故调查表</h3>
<div class="mt-5" >
<table style="width: 100%;">
<tr>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故等级</td>
<td class="border p" style="text-align: center;">虚惊/轻微</td>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故类别</td>
<td class="border p" style="text-align: center;">物体打击</td>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故时间</td>
<td class="border p" style="text-align: center;">2023-04-14</td>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故地点</td>
<td class="border p" style="text-align: center;">上海</td>
</tr>
<tr>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故所属Bu</td>
<td class="border p" style="text-align: center;">BU1</td>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故部门</td>
<td class="border p" style="text-align: center;"></td>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">事故区域负责人</td>
<td class="border p" style="text-align: center;"></td>
<td class="border p printcolor" style="text-align: center;background-color: #E7F3FC;">电话</td>
<td class="border p" style="text-align: center;">19822773234</td>
</tr>
<tr>
<td class="border p printcolor" colspan="8" style="background-color: #E7F3FC;">1.事故状况描述:(时间、地点、人物、受伤经过)</td>
</tr>
<tr>
<td class="border p" style="height: 100px;" colspan="8">
<mavon-editor ref="md" v-model="content" :ishljs="true" @imgAdd="imgAdd"/>
</td>
</tr>
<tr>
<td class="border p printcolor" colspan="8" style="background-color: #E7F3FC;">2.事故图片:</td>
</tr>
<tr>
<td class="border p" style="height: 100px;" colspan="8">
<!-- 预览 -->
<mavon-editor class="md" :value="content" :subfield="false" :defaultOpen="'preview'" :toolbarsFlag="false" :editable="false" :scrollStyle="true" :ishljs="true" />
</td>
</tr>
<tr>
<td class="border p printcolor" colspan="8" style="background-color: #E7F3FC;">3.事故处理情况(事故现场处理措施与状况、伤员处理情况等)</td>
</tr>
<tr>
<td class="border p" style="height: 100px;" colspan="8">
</td>
</tr>
<tr>
<td class="border p printcolor" colspan="8" style="background-color: #E7F3FC;">4、事故直接损失统计</td>
</tr>
<tr>
<td class="border p" colspan="8">□无损失 □轻微损失(说明):</td>
</tr>
<tr>
<td class="border p printcolor" colspan="8" style="background-color: #E7F3FC;">5、原因分析与改善方案</td>
</tr>
<tr>
<td class="border p" colspan="8" style="height: 100px;" >
</td>
</tr>
<tr>
<td class="border p printcolor" colspan="8" style="background-color: #E7F3FC;">6、预防改善对策:</td>
</tr>
<tr style="background-color: #E7F3FC;text-align: center;">
<td class="border p printcolor" colspan="3" >改善对策</td>
<td class="border p printcolor" >完成时间</td>
<td class="border p printcolor" >佐证资料<el-button @click="drawer3 = true" type="text" style="margin-left: 16px">描述</el-button></td>
<td class="border p printcolor" >责任人</td>
<td class="border p printcolor" >核实结果</td>
<td class="border p printcolor" >核实人员</td>
</tr>
<tr style="text-align: center;height: 30px;">
<td class="border p" colspan="3" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
</tr>
<tr style="text-align: center;height: 30px;">
<td class="border p" colspan="3" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
<td class="border p" ></td>
</tr>
</table>
</div>
<el-drawer title="佐证资料" :visible.sync="drawer3" direction="rtl" :close-on-press-escape='false'
:wrapperClosable='false' destroy-on-close size='50%'>
<div style="font-size: 10px; padding: 10px;overflow-y: auto;" :style="{ height: (h + 'px') }" v-html>
可根据具体对策提供相关佐证资料:<br/>
改善现场照片、管理培训记录、书面培训教材、培训会议签到表、培训会议照片、制定相关管理要求文件等
</div>
</el-drawer>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
const windowHeight = window.innerHeight || document.body.clientHeight
export default {
data() {
return {
drawer3: false,
printObj:{
id:'printTest',//打印的id
popTitle:'智能综合管理',//打印的标题
},
content:'',
}
},
computed: {
...mapState({
h: state => {
let a = windowHeight - 64 - 44
return state.screenHeight ? state.screenHeight : a
}
}),
},
mounted() {
document.addEventListener('visibilitychange', this.handleVisiable)
document.body.onblur=()=>{
this.outNumber++;
console.log(this.outNumber)
//alert(`请回到考试页面,你已离开${this.outNumber}次`)
}
},
destroyed() {
document.removeEventListener('visibilitychange', this.handleVisiable)
},
methods:{
// 绑定@imgAdd event
imgAdd(pos, $file) {
console.log(pos, $file)
let $vm = this.$refs.md
// 第一步.将图片上传到服务器.
const formData = new FormData();
formData.append("withc",'还发快手看');
formData.append("hegidnh",'和立铠四大皆空福建省');
formData.append('file', $file);
axios({
url: 'http://localhost:9090/file/upload',
method: 'post',
data: formData,
headers: {'Content-Type': 'multipart/form-data'},
}).then((res) => {
// 第二步.将返回的url替换到文本原位置![...](./0) -> ![...](url)
$vm.$img2Url(pos, res.data);
})
},
handleVisiable(e) {
switch(e.target.visibilityState) {
case 'prerender':
console.log('网页预渲染,内容不可见')
break;
case 'hidden':
console.log('内容不可见,处理后台、最小化、锁屏状态')
//alert('警告!你已经离开当前答题页面');
break;
case 'visible':
console.log('处于正常打开')
break;
}
},
}
}
</script>
<style>
/* 给要打印的背景的元素添加样式 */
.printcolor{
-webkit-print-color-adjust: exact;
}
</style>
eggjs开启流模式
配置 config/config.default.js
eggjs文档
config.multipart = {
fileSize: '50mb',
mode: 'stream', //'file' 可以配置文件模式 https://www.eggjs.org/zh-CN/basics/controller 官方文档 'stream' 配置流模式 配置的模式不一样 接收的方法方式就不一样
fileExtensions: ['.xlsx', '.txt', '.jpg', '.JPG', '.png', '.PNG', '.gif', '.GIF', '.jpeg', '.JPEG','.apk'], // 扩展几种上传的文件格式
};
controller/shigu.js
'use strict';
const Controller = require('egg').Controller;
// 引入
const fs = require('fs');
const path = require('path');
//故名思意 异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write;
//管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
const dayjs = require('dayjs');
class ShiguController extends Controller {
async shuguuploade() {
let { ctx, app } = this;
const stream = await ctx.getFileStream();
console.log(stream.fields)
console.log(stream.filename)
ctx.apiSuccess('ok');
}
}
module.exports = ShiguController;
egg后台打印结果 vue前端 劫持图片上传,自定义图片上传
注意:
只支持上传一个文件。
上传文件必须在所有其他的 fields 后面,否则在拿到文件流时可能还获取不到 fields。
vue3使用富文本
引入tinymce富文本编辑器
npm i tinymce
npm i @tinymce/tinymce-vue
node_modules/tinymce引入 语音包下载
中文语言包zh-Hans.js下载地址
新建组件src/components/Editor.vue
<template>
<editor v-model="content" tag-name="div" :init="init" />
<ChooseImage :preview="false" ref="ChooseImageRef" :limit="9" />
</template>
<script setup>
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import ChooseImage from '~/components/ChooseImage.vue'
import { ref, watch } from "vue"
import "tinymce/themes/silver/theme"; // 引用主题文件
import "tinymce/icons/default"; // 引用图标文件
import 'tinymce/models/dom'
// tinymce插件可按自己的需要进行导入
// 更多插件参考:https://www.tiny.cloud/docs/plugins/
import "tinymce/plugins/advlist"
import "tinymce/plugins/anchor"
import "tinymce/plugins/autolink"
import "tinymce/plugins/autoresize"
import "tinymce/plugins/autosave"
import "tinymce/plugins/charmap" // 特殊字符
import "tinymce/plugins/code" // 查看源码
import "tinymce/plugins/codesample" // 插入代码
import "tinymce/plugins/directionality"
import "tinymce/plugins/emoticons"
import "tinymce/plugins/fullscreen" //全屏
import "tinymce/plugins/help"
import "tinymce/plugins/image" // 插入上传图片插件
import "tinymce/plugins/importcss" //图片工具
import "tinymce/plugins/insertdatetime" //时间插入
import "tinymce/plugins/link"
import "tinymce/plugins/lists" // 列表插件
import "tinymce/plugins/media" // 插入视频插件
import "tinymce/plugins/nonbreaking"
import "tinymce/plugins/pagebreak" //分页
import "tinymce/plugins/preview" // 预览
import "tinymce/plugins/quickbars"
import "tinymce/plugins/save" // 保存
import "tinymce/plugins/searchreplace" //查询替换
import "tinymce/plugins/table" // 插入表格插件
import "tinymce/plugins/template" //插入模板
import "tinymce/plugins/visualblocks"
import "tinymce/plugins/visualchars"
import "tinymce/plugins/wordcount" // 字数统计插件
// v-model
const props = defineProps({
modelValue: String,
})
const emit = defineEmits(["update:modelValue"])
const ChooseImageRef=ref(null)
// 配置
const init = {
language_url: '/tinymce/langs/zh-Hans.js', // 中文语言包路径
language: "zh-Hans",
skin_url: '/tinymce/skins/ui/oxide', // 编辑器皮肤样式
content_css: "/tinymce/skins/content/default/content.min.css",
menubar: false, // 隐藏菜单栏
autoresize_bottom_margin: 50,
max_height: 500,
min_height: 400,
// height: 320,
toolbar_mode: "none",
plugins:
'wordcount visualchars visualblocks template searchreplace save quickbars preview pagebreak nonbreaking media insertdatetime importcss image help fullscreen directionality codesample code charmap link code table lists advlist anchor autolink autoresize autosave',
//新增自定义按钮 这里需要注册如:imageUpload
toolbar:
"formats undo redo fontsizeselect fontselect ltr rtl searchreplace media imageUpload | outdent indent aligncenter alignleft alignright alignjustify lineheight underline quicklink h2 h3 blockquote numlist bullist table removeformat forecolor backcolor bold italic strikethrough hr link preview fullscreen help ",
content_style: "p {margin: 5px 0; font-size: 14px}",
fontsize_formats: "12px 14px 16px 18px 24px 36px 48px 56px 72px",
font_formats: "微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方= PingFang SC, Microsoft YaHei, sans- serif; 宋体 = simsun, serif; 仿宋体 = FangSong, serif; 黑体 = SimHei, sans - serif; Arial = arial, helvetica, sans - serif;Arial Black = arial black, avant garde;Book Antiqua = book antiqua, palatino; ",
branding: false,
elementpath: false,
resize: false, // 禁止改变大小
statusbar: false, // 隐藏底部状态栏
setup:(editor)=>{ //插入图片功能 自定义按钮imageUpload
editor.ui.registry.addButton('imageUpload',{
tooltip:'插入图片',//文字提示
icon:'image',//内置图标
onAction(){
ChooseImageRef.value.open((data)=>{
data.forEach(url=>{
//插入内容 图片
editor.insertContent(`<img src='${url}' style='width:100%'/>`)
})
})
}
})
}
}
tinymce.init; // 初始化
const content = ref(props.modelValue)
watch(props, (newVal) => content.value = newVal.modelValue)
watch(content, (newVal) => emit("update:modelValue", newVal))
</script>
<style>
.tox-tinymce-aux {
z-index: 9999 !important;
}
</style>
调用content.vue
<template>
<FormDrawer ref="formDrawerRef" title="设置商品详情" @submit="submit" destroy-on-close>
<el-form :model="form">
<el-form-item >
<Editor v-model="form.content"/>
</el-form-item>
</el-form>
</FormDrawer>
</template>
<script setup>
import { reactive, ref } from 'vue';
import FormDrawer from '~/components/FormDrawer.vue';
import {readGoods,updateGoods} from '~/api/goods.js'
import Editor from '~/components/Editor.vue';
import { toast } from '~/composables/util';
const formDrawerRef=ref(null)
const form=reactive({
content:''
})
const goodsId=ref(0)
const open=(row)=>{
goodsId.value=row.id
row.contentLoading=true
readGoods(goodsId.value).then(res=>{
form.content=res.content
formDrawerRef.value.open()
}).finally(()=>{
row.contentLoading=false
})
}
const emit=defineEmits(['reloadData'])
const submit=()=>{
formDrawerRef.value.showLoading()
updateGoods(goodsId.value,form)
.then(res=>{
toast('设置商品详情成功')
formDrawerRef.value.close()
emit('reloadData')
})
.finally(()=>{
formDrawerRef.value.hideLoading()
})
}
defineExpose({
open
})
</script>
vue3使用打印功能
npm install vue3-print-nb --save
全局引入(main)
// 1. 全局挂载
import { createApp } from 'vue'
import App from './App.vue'
import print from 'vue3-print-nb'
const app = createApp(App)
app.use(print)
app.mount('#app')