一、复制粘贴vue-clipboard2
1、安装vue-clipboard2
npm install vue-clipboard2
2、main.js引入插件
// 复制
import VueClipboard from 'vue-clipboard2'
Vue.use(VueClipboard)
3、页面使用
<el-button
size="mini"
type="text"
ref="copyButton"
v-clipboard:copy="scope.row.copy"//要复制的数据
v-clipboard:success="onCopy"//复制成功的回调
v-clipboard:error="onError"//复制失败的回调
>复制
</el-button>
onCopy() {
this.$notify({
type: "success",
position: "bottom-left",
message: "复制成功",
duration: 2000,
offset: 100,
});
},
onError() {
this.$notify({
type: "success",
position: "bottom-left",
message: "复制shibai",
duration: 2000,
offset: 100,
});
},
二、打印vue-print-nb
1、安装
npm install vue-print-nb
2、main.js引入插件
import Print from "vue-print-nb"; //引入
Vue.use(Print); //注册
3、页面使用
<template>
<div id="printMe"> //第一步,给盒子添加id
<div
style="page-break-after: always; margin: 0"//遇到特定的组件时,打印机会重新开始一个新的打印页
v-for="(item, index) in samplelist"
:key="index"
>
<div class="b" style="margin-bottom: 20px">
<div style="border: 1px solid #000; border-bottom: none">
<img src="../../assets/dlylogo.png" width="120px" />
<div class="b-1" style="padding: 10px 10px; text-align: center">
<div>样品编号/Sample No.</div>
<div>{{ item.sampleno }}</div>
</div>
</div>
<el-descriptions class="descriptions" :column="1" border>
<el-descriptions-item label="项目编号/Item No.">{{
item.no
}}</el-descriptions-item>
<el-descriptions-item label="样品名称/Name">{{
item.samplename
}}</el-descriptions-item>
<el-descriptions-item label="型号规格/Model">{{
item.type
}}</el-descriptions-item>
</el-descriptions>
</div>
</div>
</div>
<el-button type="primary" v-print="'#printMe'">打印</el-button> //第二步,给按钮添加v-print
</template>
<style lang="scss">
//页面样式
#Put {
.el-descriptions .is-bordered .el-descriptions-item__cell {
font-size: 12px;
border: 1px solid #747474 !important;
padding: 12px 10px !important;
}
.b-2 {
display: flex;
justify-content: space-around;
padding: 12px 5px;
border: 1px solid #747474;
border-top: none;
}
}
// 打印页的样式(一定要写在这里面)
@media print {
#printMe {
width: 90%;
height: 100%;
margin: auto;
}
.b {
margin: auto;
margin-bottom: 0px !important ;
font-size: 10px !important;
img {
width: 70px !important;
}
.b-1 {
padding: 0px 2px 2px !important;
font-size: 10px !important;
}
.b-2 {
font-size: 10px !important;
padding: 2px 5px;
border: 1px solid #000;
border-top: none;
color: #000;
}
}
.el-descriptions-item__label {
width: auto !important;
}
.el-descriptions--mini:not(.is-bordered) .el-descriptions-item__cell {
padding-bottom: 0px !important;
}
.el-descriptions .is-bordered .el-descriptions-item__cell {
color: #000;
font-size: 10px !important;
border: 1px solid #000 !important;
padding: 3px 2px !important;
}
.el-checkbox {
font-size: 6px !important;
// margin-right: 6px !important;
}
.el-checkbox__label {
display: inline-block;
padding-left: 3px !important;
line-height: 19px;
font-size: 10px !important;
color: #000;
}
.el-checkbox__inner {
border: 1px solid #000 !important;
}
}
</style>
>
最终呈现的样式
因为我的id是放在循环外面的,所以它会一次性展示所有,如果样式不太对的话,可以调整他的设置,然后我这里调整了他的边距和缩放,
因为我用的是热敏打印机是只有黑墨,所以除了黑色以外的颜色都打印不出来
使用热敏打印机前,先调整一下打印机的基本设置
页面设置:新建所要打印纸的尺寸(我这已经弄好了40mm x60mm),选择纵向
卷:方式选择热转印
如果有图的话,则在图形中混色选择无,就会清晰一点
三、下载多文件并压缩成包下载
1、下载jszip插件和file-saver插件
npm i file-saver
npm i jszip
2、页面使用
<template>
<div>
<el-button @click="allload()" type="text">下载全部文件</el-button>
</div>
</template>
<script>
import JSZip from "jszip";
import FileSaver from "file-saver";
export default {
methods:{
// 下载全部文件
allload(i) {
if (i.allfile.length > 0) {
this.$mess.info("正在下载中,请稍后");
var blogTitle = "过程数据文件"; // 下载后压缩包的名称
var zip = new JSZip();
var promi = [];
let cache = {};
for (let item of i.allfile) {
//item.path是文件地址
//item.filename是文件名称
if (item.path) {
item.path = decodeURIComponent(item.path);
const promise = this.getImgArrayBuffer(item.path).then((data) => {
// 下载文件, 并存成ArrayBuffer对象(blob)
zip.file(item.filename, data, { binary: true }); // 逐个添加文件
cache[item.filename] = data;
});
promi.push(promise);
} else {
// feilePath地址不存在时提示
this.$mess.error(`附件${item.fileName}地址错误,下载失败`);
}
}
Promise.all(promi)
.then(() => {
return zip.generateAsync({ type: "blob" }).then((content) => {
// 生成二进制流
FileSaver.saveAs(content, blogTitle); // 利用file-saver保存文件 blogTitle:自定义文件名
});
})
.catch((res) => {
this.$mess.error("文件压缩失败");
});
} else {
this.$mess.info("没有文件可下载");
}
},
//文件以流的形式获取(参数url为文件链接地址)
getImgArrayBuffer(url) {
return new Promise((resolve, reject) => {
//通过请求获取文件blob格式
let xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.responseType = "blob";
xmlhttp.onload = function () {
if (xmlhttp.status == 200) {
resolve(xmlhttp.response);
} else {
reject(xmlhttp.status);
}
};
xmlhttp.send();
});
},
}
}
</script>
但是这里有一个问题:我在使用的时候,偶尔会出现死循环,发现是他调用了我页面的接口,但是我并没有在这里调用接口,所以不知道是什么原因,如果有大佬知道,还望在评论区告知。
四、引导driver.js
1、安装
npm install driver.js
2、页面引入
import { driver } from "driver.js";
import "driver.js/dist/driver.css";
注意:有时候会是driver.min.css
3、使用
<div id='inp' ></div>
mounted() {
this.guide();
},
methods: {
// 页面引导
guide() {
// 判断首次登录
this.driver = driver();
this.driver.highlight({
element: "#inp",
popover: {
title: "点击'+',即刻开始对话",
description: "",
side: "right",
align: "start"
}
});
},
}
五、返回流失数据event-source-polyfill
1、安装
npm install event-source-polyfill
2、使用
1、接口参数采用的是字符串拼接的形式,如果参数为空,则不需要拼接再上面。
2、 需要注意的是,页面上必须得有一个盒子接受流失数据,所以在调用前我会添加一个盒子来接收(因为我是模仿对话的形式,所以是往数组push)。
3、loadSub的item是数组最后一个数据,也就是我push进去的数据;chatContent是滚动条的位置
<script>
let source = null;
var AIurl = "http://192.168.4.172:8081/userApp/ai/sse";
var resultUrl = "http://192.168.4.172:8081/userApp/ai/aiHelp";
import { EventSourcePolyfill } from "event-source-polyfill";
export default {
methods: {
loadSub(item, chatContent) {
this.disabled = true;
// 做判断,判断是否为空,为空则不拼接上去
const queryString = Object.keys(this.form)
.map(key => {
if (this.form[key] !== null) {
//是null就拼接
return `${encodeURIComponent(key)}=${encodeURIComponent(
this.form[key]
)}`;
}
})
.join("&");
const url = `${resultUrl}?${queryString}`;
source = new EventSourcePolyfill(url, {
headers: {
token: this.$cookies.get("userToken")
}
});
source.addEventListener("open", function(e) {
// console.log(e);
});
source.onmessage = e => {
// console.log(JSON.parse(e.data));
if (JSON.parse(e.data).end) {
// 结束了
item.aiId = JSON.parse(e.data).end;
this.disabled = false;
source.close();
return;
} else if (JSON.parse(e.data).error) {
this.$message.error(JSON.parse(e.data).error);
this.disabled = false;
return;
} else {
item.aiReply += JSON.parse(e.data).content.replace(/\\n/g, "\n");
chatContent.scrollTop = chatContent.scrollHeight;
}
};
source.onerror = event => {
// console.log(event);
// this.$message.error(event.target.readyState);
this.disabled = false;
// if (event.readyState == EventSource.CLOSED) {
// console.log("NOTICE连接关闭");
// } else if (this.source.readyState == EventSource.CONNECTING) {
// console.log("NOTICE正在重连");
// // //重新设置header
// // this.source.headers = {
// // [process.env.VUE_APP_OAUTH_AUTHORIZATION]: store.getters.getToken
// // };
// } else {
// console.log(event);
// }
event.target.close();
};
// source.addEventListener("message", function(e) {
// // console.log(e.data);
// // console.log(e);
// });
// source.addEventListener("error", function(err) {
// console.log(err);
// this.disabled = false;
// // console.log("服务异常请重试并联系开发者");
// source.close();
// });
},
// 生成结果
onSubmit() {
let that = this;
this.$refs["form"].validate(valid => {
if (valid) {
this.AiContent.push({
aiId: "", //编号
userId: "", //用户id
userAsk: "", //用户询问
aiReply: "", //ai回复
askTime: "", //询问时间
isPdf: false, //是否是pdf
fileName: null, //文件名称
fileSize: null, //文件大小
aiTopicId: this.form.topicId //话题编号
});
this.$message.success("请稍等,正在响应中");
this.loadSub(
this.AiContent[this.AiContent.length - 1],
that.chatContent
);
} else {
console.log("error submit!!");
return false;
}
});
},
}
}
六、vue2使用markdown
第一步:下载
npm i marked
npm i markdown-loader //代码样式高亮
第二步:页面引入并使用
<template>
<div class="dashbord">
<div v-highlight class="markdown-body" v-html="text"></div>
</div>
</template>
<script>
import { marked } from "marked";
export default {
data() {
return {
text:''
}
},
methods: {
// 获取当前对话历史
async chatMemory() {
//省略内容
this.text = marked(res.data)
}
}
}
</script>
其中class="markdown-body"是可以用过这个来改变marked的样式的
v-highlight就是高亮
注意点:
1、自定义渲染器————想要改变标题渲染的格式,变成下面的样子
// 创建自定义渲染器
class CustomRenderer extends marked.Renderer {
heading(text, level) {
// 将一级标题转换为h1标签
if (level === 1) {
return `<div class="hClass"># ${text}</div>`;
} else if (level === 2) {
return `<div class="hClass">## ${text}</div>`;
} else if (level === 3) {
return `<div class="hClass">### ${text}</div>`;
} else if (level === 4) {
return `<div class="hClass">#### ${text}</div>`;
} else if (level === 5) {
return `<div class="hClass">##### ${text}</div>`;
} else if (level === 6) {
return `<div class="hClass">###### ${text}</div>`;
}
}
}
// 使用自定义渲染器
const renderer = new CustomRenderer();
this.text = marked(res.data, {
breaks: true,
renderer: renderer,
});
这个是marked样式修改
.markdown-body {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
Microsoft YaHei, Arial, sans-serif !important;
line-height: 18px;
& ul {
list-style: none;
padding-left: 20px;
}
.hClass {
//出现#则不转换为h1等标签
font-size: 14px;
color: #8a2328;
font-weight: 600
}
}