vue-markdown/src/mixins/common.js

242 lines
7.7 KiB
JavaScript
Raw Normal View History

2019-12-13 18:21:59 +08:00
import {saveFile} from '../utils';
import defaultTools from '../config/tools';
export default {
name: 'markdown',
props: {
value: {
type: [String, Number],
default: ''
},
theme: {// 默认主题
type: String,
default: 'light'
},
width: {// 初始化宽度
type: [Number, String],
default: 'auto'
},
height: {// 初始化高度
type: Number,
default: 600
},
toolbars: {// 工具栏
type: Object,
default() {
return {};
}
},
bordered: {//是否有边框
type: Boolean,
default: true
},
autoSave: {// 是否自动保存
type: Boolean,
default: false
},
interval: {// 自动保存间隔 mm
type: Number,
default: 10000
},
exportFileName: {// 默认导出文件名称
type: String,
default: 'unnamed'
},
markedOptions: {//marked.js配置项
type: Object,
default() {
return {};
}
},
2019-12-13 18:21:59 +08:00
copyCode: {// 复制代码
type: Boolean,
default: true
},
copyBtnText: {// 复制代码按钮文字
type: String,
default: '复制代码'
},
isPreview: {//是否是预览模式
type: Boolean,
default: false
}
},
data() {
return {
currentValue: '', // 输入框内容
timeoutId: null,
indexLenth: 1,
html: '',// 预览的html
preview: false, // 是否是预览状态
split: true, //分屏显示
fullscreen: false, // 是否是全屏
scrollSide: '', // 哪个半栏在滑动
lastInsert: '', //最后一次插入的内容
timerId: null, // 定时器id
themeName: '',
themeSlideDown: false,
2019-12-13 18:21:59 +08:00
imgSlideDown: false,
imgs: [],
scrolling: true, // 同步滚动
editorScrollHeight: 0,
previewImgModal: false,
previewImgSrc: '',
previewImgMode: ''
};
},
computed: {
tools() {
2019-12-13 18:21:59 +08:00
const {toolbars = {}} = this;
return {
...defaultTools,
...toolbars
};
}
},
methods: {
insertLink() {// 插入链接
this.insertContent('\n[link](href)');
},
insertImage() {// 插入图片
this.insertContent('\n![image](imgUrl)');
},
insertTable() {// 插入表格
this.insertContent(
'\nheader 1 | header 2\n---|---\nrow 1 col 1 | row 1 col 2\nrow 2 col 1 | row 2 col 2\n\n'
);
},
handleSave() {// 保存操作
2019-12-13 18:21:59 +08:00
const {currentValue, themeName, html} = this;
this.$emit('on-save', {
theme: themeName,
2019-12-13 17:32:17 +08:00
value: currentValue,
html
});
},
toggleSlideDown() {// 显示主题选项
this.slideDown = !this.slideDown;
},
setThemes(name) {// 设置主题
this.themeName = name;
this.themeSlideDown = false;
this.$emit('on-theme-change', name);
},
exportFile() {// 导出为.md格式
saveFile(this.currentValue, this.exportFileName + '.md');
},
importFile(e) {// 导入本地文件
const file = e.target.files[0];
if (!file) {
return;
}
2019-12-13 18:21:59 +08:00
const {type} = file;
if (!['text/markdown', 'text/src'].includes(type)) {
return;
}
const reader = new FileReader();
reader.readAsText(file, {
encoding: 'utf-8'
});
reader.onload = () => {
this.currentValue = reader.result;
e.target.value = '';
2019-12-13 18:21:59 +08:00
if (this.pro) {// 专业版手动set value
this.editor.setOption('value', this.currentValue);
}
};
2019-12-13 18:21:59 +08:00
reader.onerror = err => {
console.error(err);
}
},
handlePaste(_, e) {// 粘贴图片
2019-12-13 18:21:59 +08:00
const {clipboardData = {}} = e;
const {types = [], items} = clipboardData;
let item = null;
for (let i = 0; i < types.length; i++) {
if (types[i] === 'Files') {
item = items[i];
break;
}
}
if (item) {
const file = item.getAsFile();
if (/image/gi.test(file.type)) {
2019-12-13 18:21:59 +08:00
this.$emit('on-upload-image', file);
e.preventDefault();
}
}
},
mousescrollSide(side) {// 设置究竟是哪个半边在主动滑动
this.scrollSide = side;
},
addImageClickListener() {// 监听查看大图
2019-12-13 18:21:59 +08:00
const {imgs = []} = this;
if (imgs.length > 0) {
for (let i = 0, len = imgs.length; i < len; i++) {
imgs[i].onclick = null;
}
}
setTimeout(() => {
this.imgs = this.$refs.preview.querySelectorAll('img');
for (let i = 0, len = this.imgs.length; i < len; i++) {
this.imgs[i].onclick = () => {
const src = this.imgs[i].getAttribute('src');
this.previewImage(src);
};
}
}, 600);
},
previewImage(src) {// 预览图片
const img = new Image();
img.src = src;
img.onload = () => {
const width = img.naturalWidth;
const height = img.naturalHeight;
if (height / width > 1.4) {
this.previewImgMode = 'horizontal';
} else {
this.previewImgMode = 'vertical';
}
this.previewImgSrc = src;
this.previewImgModal = true;
};
},
2019-12-13 18:21:59 +08:00
chooseImage() {// 选择图片
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.onchange = ()=>{
const files = input.files;
if(files[0]){
this.$emit('on-upload-image', files[0]);
input.value = '';
}
}
input.click();
},
addCopyListener() {// 监听复制操作
setTimeout(() => {
const btns = document.querySelectorAll(
'.code-block .copy-code'
);
this.btns = btns;
for (let i = 0, len = btns.length; i < len; i++) {
btns[i].onclick = () => {
const code = btns[i].parentNode.querySelectorAll('pre')[0].innerText;
const aux = document.createElement('input');
aux.setAttribute('value', code);
document.body.appendChild(aux);
aux.select();
document.execCommand('copy');
document.body.removeChild(aux);
this.$emit('on-copy', code);
};
}
}, 600);
}
},
destroyed() {// 销毁时清除定时器
clearInterval(this.timerId);
}
};