提交 77c78aa2 编写于 作者: 璃白.'s avatar 璃白. 🌻

feat:第一版

上级 95dde5e4
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script src="./bundle.js"></script> <script src="./markdown-editor.js"></script>
<script> <script>
new MdEditor({ new MdEditor({
el: "#app", // required el: "#app", // required
...@@ -20,18 +20,21 @@ ...@@ -20,18 +20,21 @@
textColorActive: "#000" textColorActive: "#000"
}, },
canAttachFile: true, canAttachFile: true,
placeholder: "请输入内容",
onChange: function(res) { onChange: function(res) {
console.log(res); console.log(res);
}, },
onUpload: function(fileList, callback) { onUpload: function(file, callback) {
new Promise((res, rej) => { new Promise((res, rej) => {
setTimeout(() => { setTimeout(() => {
res(fileList); res(file);
}, 2000); }, 2000);
}).then(res => { }).then(res => {
callback( var reader = new FileReader();
"https://img2.baidu.com/it/u=3681880960,455182084&fm=26&fmt=auto&gp=0.jpg" reader.readAsDataURL(res);
); reader.onload = () => {
callback(reader.result);
};
}); });
} }
}); });
......
import store from '@/store' import store from "@/store";
// 获取选中文本信息 // 获取选中文本信息
...@@ -8,21 +8,36 @@ export function getSelectionInfo(selectorId) { ...@@ -8,21 +8,36 @@ export function getSelectionInfo(selectorId) {
const { selectionStart = 0, selectionEnd = 0 } = selector; const { selectionStart = 0, selectionEnd = 0 } = selector;
if (selectionStart === selectionEnd) return ""; if (selectionStart === selectionEnd) return "";
return { return {
selectorId,
selectionStart, selectionStart,
selectionEnd selectionEnd
}; };
} }
export const getPosition = function(selectorId) {
const element = document.getElementById(selectorId);
let cursorPos = 0;
if (document.selection) {
//IE
var selectRange = document.selection.createRange();
selectRange.moveStart("character", -element.value.length);
cursorPos = selectRange.text.length;
} else if (element.selectionStart || element.selectionStart == "0") {
cursorPos = element.selectionStart;
}
return cursorPos;
};
// 工具栏格式化文本 // 工具栏格式化文本
export function formatText(text, selectionInfo, startStr = "", endStr = "") { export function formatText(text, selectionInfo, startStr = "", endStr = "") {
if (!selectionInfo) return text + startStr + endStr; if (!selectionInfo) return;
return ( const newText =
text.slice(0, selectionInfo.selectionStart) + text.slice(0, selectionInfo.selectionStart) +
startStr + startStr +
text.slice(selectionInfo.selectionStart, selectionInfo.selectionEnd) + text.slice(selectionInfo.selectionStart, selectionInfo.selectionEnd) +
endStr + endStr +
text.slice(selectionInfo.selectionEnd) text.slice(selectionInfo.selectionEnd);
); return newText;
} }
// //
...@@ -67,7 +82,7 @@ export function initStyle({ ...@@ -67,7 +82,7 @@ export function initStyle({
} }
} }
// //
export function isNotEmpty(val) { export function isNotEmpty(val) {
return val !== null && val !== undefined; return val !== null && val !== undefined;
} }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
@blur="setFocus(false)" @blur="setFocus(false)"
@paste="pasteFile" @paste="pasteFile"
v-model="textContent" v-model="textContent"
:placeholder="placeholder"
rows="10" rows="10"
> >
</textarea> </textarea>
...@@ -19,7 +20,7 @@ ...@@ -19,7 +20,7 @@
</template> </template>
<script> <script>
import { mapState, mapMutations } from "vuex"; import { mapState, mapMutations } from "vuex";
import { getSelectionInfo } from "@/assets/js/utils"; import { getSelectionInfo, getPosition } from "@/assets/js/utils";
export default { export default {
data() { data() {
return { return {
...@@ -43,32 +44,40 @@ export default { ...@@ -43,32 +44,40 @@ export default {
document.removeEventListener("mouseup", this.checkSelection); document.removeEventListener("mouseup", this.checkSelection);
}, },
computed: { computed: {
...mapState(["text", "fullScreen"]) ...mapState(["text", "fullScreen", "placeholder"])
}, },
methods: { methods: {
...mapMutations([ ...mapMutations([
"setText", "setText",
"setFullScreen", "setFullScreen",
"setSelectionInfo", "setSelectionInfo",
"setFileList",
"setFocus" "setFocus"
]), ]),
checkSelection() { checkSelection() {
const info = getSelectionInfo(this.id); const info = getSelectionInfo(this.id);
if (!info) return; if (!info) {
const cursorPoint = getPosition(this.id);
this.setSelectionInfo({
selectorId: this.id,
selectionStart: cursorPoint,
selectionEnd: cursorPoint
});
return;
}
this.setSelectionInfo(info); this.setSelectionInfo(info);
}, },
pasteFile(event) { pasteFile(event) {
let fileList = []; let fileList = [];
const items = (event.clipboardData || window.clipboardData).items; const items = (event.clipboardData || window.clipboardData).items;
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
console.log(items[i]);
if (items[i].type.indexOf("image") !== -1) { if (items[i].type.indexOf("image") !== -1) {
fileList.push(items[i].getAsFile()); fileList.push(items[i].getAsFile());
break; break;
} }
} }
if (!fileList.length) return; if (!fileList.length) return;
console.log(fileList); this.setFileList(fileList[0]);
} }
} }
}; };
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
name="md-upload-file" name="md-upload-file"
id="md-upload-file" id="md-upload-file"
@change="upload" @change="upload"
multiple
/> />
<span>添加附件</span> <span>添加附件</span>
</div> </div>
...@@ -27,7 +26,7 @@ export default { ...@@ -27,7 +26,7 @@ export default {
...mapMutations(["setText", "setFileList"]), ...mapMutations(["setText", "setFileList"]),
upload(e) { upload(e) {
const fileList = Array.from(e.target.files); const fileList = Array.from(e.target.files);
this.setFileList(fileList); this.setFileList(fileList[0]);
} }
} }
}; };
......
...@@ -9,15 +9,23 @@ import "@/assets/style/global.less"; ...@@ -9,15 +9,23 @@ import "@/assets/style/global.less";
Vue.use(Vtip.directive); Vue.use(Vtip.directive);
function initMdEditor(obj) { function initMdEditor(obj) {
const { el, onChange, onUpload, canAttachFile, themeOptions } = obj; const {
el,
onChange,
onUpload,
placeholder,
canAttachFile,
themeOptions
} = obj;
if (!el || !document.querySelector(el)) throw new Error("请指定容器"); if (!el || !document.querySelector(el)) throw new Error("请指定容器");
if (isNotEmpty(themeOptions)) initStyle(themeOptions); if (isNotEmpty(themeOptions)) initStyle(themeOptions);
if (isNotEmpty(canAttachFile)) if (isNotEmpty(canAttachFile))
store.commit("setCanAttachFile", canAttachFile); store.commit("setCanAttachFile", canAttachFile);
if (isNotEmpty(placeholder)) store.commit("setPlaceholder", placeholder);
new Vue({ new Vue({
store, store,
render: (h) => render: h =>
h(App, { h(App, {
on: { on: {
change(val) { change(val) {
......
...@@ -9,6 +9,7 @@ export default new Vuex.Store({ ...@@ -9,6 +9,7 @@ export default new Vuex.Store({
fullScreen: false, fullScreen: false,
isFocus: false, isFocus: false,
showPreview: false, showPreview: false,
placeholder: "请输入内容",
toolButtonList: [ toolButtonList: [
{ {
name: "bold", name: "bold",
...@@ -82,48 +83,47 @@ export default new Vuex.Store({ ...@@ -82,48 +83,47 @@ export default new Vuex.Store({
], ],
fileList: "", fileList: "",
ulNum: 1, ulNum: 1,
text: ` // text: `
# 标题一标题一标题一 // # 标题一标题一标题一
## 标题二标题二 // ## 标题二标题二
666\`行内代码\`666 // 666\`行内代码\`666
\`\`\`js // \`\`\`js
// 是注释呀 // // 是注释呀
/** // /**
* @params x // * @params x
*/ // */
function fn() { // function fn() {
return null; // return null;
} // }
\`\`\` // \`\`\`
**粗体文字** // **粗体文字**
_斜体文字_ // _斜体文字_
> 这段是引用的内容\n // > 这段是引用的内容\n
> 这段是引用的内容 // > 这段是引用的内容
> 这段是引用的内容 // > 这段是引用的内容
[链接](url) // [链接](url)
// - 无序列表
// - 无序列表
// - 无序列表
- 无序列表 // 1. 有序列表
- 无序列表 // 2. 有序列表
- 无序列表 // 3. 有序列表
// - [ ] 任务列表
// - [x] 任务列表
// - [ ] 任务列表
1. 有序列表 // | header | header |
2. 有序列表 // | ------ | ------ |
3. 有序列表 // | cell | cell |
// | cell | cell |`,
- [ ] 任务列表
- [x] 任务列表
- [ ] 任务列表
| header | header |
| ------ | ------ |
| cell | cell |
| cell | cell |`,
selectionInfo: "", selectionInfo: "",
text: "",
html: "", html: "",
canAttachFile: true canAttachFile: true
}, },
...@@ -155,6 +155,9 @@ _斜体文字_ ...@@ -155,6 +155,9 @@ _斜体文字_
}, },
setFileList(state, val) { setFileList(state, val) {
state.fileList = val; state.fileList = val;
},
setPlaceholder(state, val) {
state.placeholder = val;
} }
} }
}); });
...@@ -3,7 +3,7 @@ const VueLoaderPlugin = require("vue-loader/lib/plugin"); ...@@ -3,7 +3,7 @@ const VueLoaderPlugin = require("vue-loader/lib/plugin");
module.exports = { module.exports = {
entry: path.resolve(__dirname, "./src/main.js"), entry: path.resolve(__dirname, "./src/main.js"),
output: { output: {
filename: "bundle.js", filename: "markdown-editor.js",
path: path.resolve(__dirname, "dist") path: path.resolve(__dirname, "dist")
}, },
devServer: { devServer: {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册