diff --git a/README.md b/README.md
index f1bd3b3..3f85f23 100644
--- a/README.md
+++ b/README.md
@@ -17,16 +17,23 @@
Markdown 文档自动即时渲染为微信图文,让你不再为微信文章排版而发愁!只要你会基本的 Markdown 语法,就能做出一篇样式简洁而又美观大方的微信图文。
## 在线编辑器地址
-- GitHub Page:https://doocs.github.io/md
-- Gitee Page:https://doocs.gitee.io/md
+- Netlify: https://mdmd.netlify.app
+- Gitee Pages:https://doocs.gitee.io/md
+- GitHub Pages:https://doocs.github.io/md
-注:推荐使用 Chrome 浏览器,效果最佳。另外,对于国内(中国)的朋友,访问 [Gitee Page](https://doocs.gitee.io/md) 速度会相对快一些。
+注:推荐使用 Chrome 浏览器,效果最佳。另外,对于国内(中国)的朋友,访问 [Gitee Pages](https://doocs.gitee.io/md) 速度会相对快一些。
## 为何二次开发
现有的开源微信 Markdown 编辑器,样式繁杂,也不符合我个人的审美需求。在我使用它们进行文章排版的时候,经常还要自己做一些改动,费时费力,因此动手做了二次开发。
欢迎各位朋友随时提交 PR,让这款微信 Markdown 编辑器变得更好!如果你有新的想法,也欢迎在 Issues 区反馈。
+注:目前在非 master 分支上对项目进行重构,更多新特性,敬请期待!
+
+- [Vue 分支](https://github.com/doocs/md/tree/m_create_vue)
+- [React 分支](https://github.com/doocs/md/tree/chore-webpack)
+
+
## 功能特性
- [x] 支持 Markdown 所有基础语法
- [x] 支持单独进行字体、字号设置
@@ -57,8 +64,55 @@ Markdown 文档自动即时渲染为微信图文,让你不再为微信文章
![doocs-md-upload-image](https://imgkr.cn-bj.ufileos.com/97db3cd6-bddc-4eff-8635-472631b0a642.gif)
+## 谁在使用
+
+
+注:如果你使用了本 Markdown 编辑器进行文章排版,并且希望在本项目 README 中展示你的公众号,请到 [#5](https://github.com/doocs/md/issues/5) 留言。
+
## 示例文章
-- [ES6 特性快速扫盲](https://mp.weixin.qq.com/s/I3EzOO0skf8xDCGtyYM5Lg)
+- [全网首发!GPU 驱动自升级原理详解](https://mp.weixin.qq.com/s/7UG24ZugfI5ZnhUpo8vfvQ)
+- [Quick Start - 天下武功,唯快不破!效率工具,老少皆宜](https://mp.weixin.qq.com/s/SFde8OsZ8FzNGMHwpmDtrg)
+- [死磕JavaScript系列之原来你是对象(一)](https://mp.weixin.qq.com/s/oc5Z2t9ykbu_Dezjnw5mfQ)
+- [一文多发神器--ArtiPub&OpenWrite](https://mp.weixin.qq.com/s/FpGIX9viQR6Z9iSCEPH86g)
- [免费且好用的图床,就你了,「图壳」!](https://mp.weixin.qq.com/s/0HhgHLo_tTRFZcC-CVjDbw)
- [GitHub 项目持续本地化,交给它来做,准没错!](https://mp.weixin.qq.com/s/KO4xHr4EI0YfjF0hiT3pbw)
- [阿里又一个 20k+ stars 开源项目诞生,恭喜 fastjson!](https://mp.weixin.qq.com/s/RNKDCK2KoyeuMeEs6GUrow)
@@ -66,8 +120,6 @@ Markdown 文档自动即时渲染为微信图文,让你不再为微信文章
- [刷掉 90 % 候选人的海量数据面试题(附题解+方法总结)](https://mp.weixin.qq.com/s/rjGqxUvrEqJNlo09GrT1Dw)
- [GitHub 标星 11.5k 的一款开源工具,助你轻松查看 Git 历史](https://mp.weixin.qq.com/s/PK-ikENqF13Lmqy2pcMhYQ)
-注:如果你使用了本 Markdown 编辑器进行文章排版,并且希望将你的文章加入示例列表,欢迎随时提交 PR。
-
## 项目维护者
diff --git a/src/api/fetch.js b/src/api/fetch.js
new file mode 100644
index 0000000..206de7f
--- /dev/null
+++ b/src/api/fetch.js
@@ -0,0 +1,32 @@
+import axios from 'axios';
+
+// 创建axios实例
+const service = axios.create({
+ baseURL: '',
+ timeout: 10 * 1000 // 请求超时时间
+});
+
+service.interceptors.request.use(
+ config => {
+ if (/^(post)|(put)|(delete)$/i.test(config.method)) {
+ if (config.data && config.data.upload) {
+ config.headers['Content-Type'] = 'multipart/form-data';
+ config.headers['Access-Control-Allow-Origin'] = 'http://192.168.0.106:8080';
+ }
+ }
+ return config;
+ }, error => {
+ Promise.reject(error);
+ }
+);
+
+service.interceptors.response.use(res => {
+ if (res.data.success) {
+ return res.data;
+ } else {
+ console.log(res);
+ }
+ return Promise.reject(res.data);
+}, error => Promise.reject(error));
+
+export default service;
\ No newline at end of file
diff --git a/src/api/file.js b/src/api/file.js
new file mode 100644
index 0000000..f20fad7
--- /dev/null
+++ b/src/api/file.js
@@ -0,0 +1,15 @@
+import fetch from './fetch';
+
+
+function fileUpload(data) {
+ return fetch({
+ url: 'https://imgkr.com/api/files/upload',
+ method: 'post',
+ data: data
+ })
+}
+
+
+export default {
+ fileUpload
+};
\ No newline at end of file
diff --git a/src/components/CodemirrorEditor.vue b/src/components/CodemirrorEditor.vue
index 85d24f2..bde61bf 100644
--- a/src/components/CodemirrorEditor.vue
+++ b/src/components/CodemirrorEditor.vue
@@ -4,61 +4,61 @@
-
+ :show-file-list="false" :multiple="true" accept=".jpg,.jpeg,.png,.gif" name="file"
+ :before-upload="beforeUpload" :on-success="uploaded">
+
-
+
-
+
-
+
-
+
-
+
-
{{ font.label }}
Abc
-
+
-
-
+
+
-
+
{{ size.label }}
{{ size.desc }}
-
+
-
-
+
+
-
+
{{ color.label }}
{{ color.hex }}
-
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
复制
关于
@@ -71,7 +71,7 @@
-
+
@@ -105,12 +105,12 @@
-
+
-
+
-
+
diff --git a/src/components/codeMirror/header.vue b/src/components/codeMirror/header.vue
new file mode 100644
index 0000000..6f83a02
--- /dev/null
+++ b/src/components/codeMirror/header.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ font.label }}
+ Abc
+
+
+
+
+
+
+ {{ size.label }}
+ {{ size.desc }}
+
+
+
+
+
+
+ {{ color.label }}
+ {{ color.hex }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 复制
+ 关于
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/scripts/config.js b/src/scripts/config.js
new file mode 100644
index 0000000..2a623c5
--- /dev/null
+++ b/src/scripts/config.js
@@ -0,0 +1,60 @@
+export default {
+ builtinFonts: [
+ {
+ label: '无衬线',
+ value: '-apple-system-font,BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB , Microsoft YaHei UI , Microsoft YaHei ,Arial,sans-serif'
+ },
+ {
+ label: '衬线',
+ value: "Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif"
+ }
+ ],
+ sizeOption: [
+ {
+ label: '12px',
+ value: '12px',
+ desc: '更小'
+ },
+ {
+ label: '13px',
+ value: '13px',
+ desc: '稍小'
+ },
+ {
+ label: '14px',
+ value: '14px',
+ desc: '推荐'
+ },
+ {
+ label: '15px',
+ value: '15px',
+ desc: '稍大'
+ },
+ {
+ label: '16px',
+ value: '16px',
+ desc: '更大'
+ }
+ ],
+ colorOption: [
+ {
+ label: '经典蓝',
+ value: 'rgba(15, 76, 129, 1)',
+ hex: '最新流行'
+ },
+ {
+ label: '翡翠绿',
+ value: 'rgba(0, 152, 116, 1)',
+ hex: '优雅清新'
+ },
+ {
+ label: '活力橘',
+ value: 'rgba(250, 81, 81, 1)',
+ hex: '热情活泼'
+ }
+ ],
+ form: {
+ rows: 1,
+ cols: 1
+ }
+};
\ No newline at end of file
diff --git a/src/scripts/util.js b/src/scripts/util.js
index fe6ce62..d7f8893 100644
--- a/src/scripts/util.js
+++ b/src/scripts/util.js
@@ -167,3 +167,29 @@ export function css2json (css) {
// 返回JSON形式的结果串
return json
}
+
+
+/**
+ * 将编辑器内容保存到 LocalStorage
+ * @param {*} editor
+ * @param {*} name
+ */
+export function saveEditorContent(editor, name) {
+ const content = editor.getValue(0)
+
+ if (content) {
+ localStorage.setItem(name, content)
+ } else {
+ localStorage.removeItem(name)
+ }
+}
+
+export function checkImage(file) {
+ if (!/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/.test(file.name)) {
+ return '请上传 JPG/PNG/GIF 格式的图片';
+ }
+ if (file.size > 5 * 1024 * 1024) {
+ return '由于公众号限制,图片大小不能超过 5.0M';
+ }
+ return false;
+}
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
index 332b916..8689f0a 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1,15 +1,136 @@
import Vue from 'vue'
import Vuex from 'vuex'
+import config from '../scripts/config';
+import WxRenderer from '../scripts/renderers/wx-renderer'
+import marked from 'marked'
+import CodeMirror from 'codemirror/lib/codemirror'
+import DEFAULT_CONTENT from '../scripts/default-content'
+import DEFAULT_CSS_CONTENT from '../scripts/themes/default-theme-css'
+import {
+ setColor
+} from '../scripts/util'
Vue.use(Vuex)
+const state = {
+ wxRenderer: null,
+ output: '',
+ editor: null,
+ cssEditor: null,
+ html: '',
+ currentFont: {},
+ currentSize: {},
+ currentColor: {}
+};
+const mutations = {
+ setEditorValue(state, data) {
+ state.editor.setValue(data)
+ },
+ setCssEditorValue(state, data) {
+ state.cssEditor.setValue(data)
+ },
+ setWxRendererOptions(state, data) {
+ state.wxRenderer.setOptions(data);
+ },
+ setCurrentFont(state, data) {
+ state.currentFont = data;
+ localStorage.setItem('fonts', data)
+ },
+ setCurrentSize(state, data) {
+ state.currentSize = data;
+ localStorage.setItem('size', data)
+ },
+ setCurrentColor(state, data) {
+ state.currentColor = data;
+ localStorage.setItem('color', data)
+ },
+ initEditorState(state) {
+ state.currentFont = localStorage.getItem('fonts') || config.builtinFonts[0].value
+ state.currentColor = localStorage.getItem('color') || config.colorOption[1].value
+ state.currentSize = localStorage.getItem('size') || config.sizeOption[2].value
+ state.status = localStorage.getItem('status') === 'true'
+ state.wxRenderer = new WxRenderer({
+ theme: setColor(state.currentColor),
+ fonts: state.currentFont,
+ size: state.currentSize,
+ status: state.status
+ })
+ },
+ initEditorEntity(state) {
+ state.editor = CodeMirror.fromTextArea(
+ document.getElementById('editor'),
+ {
+ value: '',
+ mode: 'text/x-markdown',
+ theme: 'xq-light',
+ lineNumbers: false,
+ lineWrapping: true,
+ styleActiveLine: true,
+ autoCloseBrackets: true
+ }
+ )
+ // 如果有编辑器内容被保存则读取,否则加载默认内容
+ if (localStorage.getItem('__editor_content')) {
+ state.editor.setValue(localStorage.getItem('__editor_content'))
+ } else {
+ state.editor.setValue(DEFAULT_CONTENT)
+ }
+ },
+ initCssEditorEntity(state) {
+ state.cssEditor = CodeMirror.fromTextArea(
+ document.getElementById('cssEditor'), {
+ value: '',
+ mode: 'css',
+ theme: 'style-mirror',
+ lineNumbers: false,
+ lineWrapping: true,
+ matchBrackets: true,
+ autofocus: true,
+ extraKeys: {
+ 'Ctrl-F': function autoFormat(editor) {
+ const totalLines = editor.lineCount()
+ editor.autoFormatRange({
+ line: 0,
+ ch: 0
+ }, {
+ line: totalLines
+ })
+ }
+ }
+ }
+ )
+
+ // 如果有编辑器内容被保存则读取,否则加载默认内容
+ if (localStorage.getItem('__css_content')) {
+ state.cssEditor.setValue(localStorage.getItem('__css_content'))
+ } else {
+ state.cssEditor.setValue(DEFAULT_CSS_CONTENT)
+ }
+ },
+ editorRefresh(state) {
+ let output = marked(state.editor.getValue(0), {
+ renderer: state.wxRenderer.getRenderer(state.status)
+ })
+ // 去除第一行的 margin-top
+ output = output.replace(/(style=".*?)"/, '$1;margin-top: 0"')
+ if (state.status) {
+ // 引用脚注
+ output += state.wxRenderer.buildFootnotes()
+ // 附加的一些 style
+ output += state.wxRenderer.buildAddition()
+ }
+
+ state.output = output
+ },
+ clearEditorToDefault(state) {
+ state.editor.setValue(DEFAULT_CONTENT)
+ state.cssEditor.setValue(DEFAULT_CSS_CONTENT)
+ }
+}
+
export default new Vuex.Store({
- state: {
- },
- mutations: {
- },
- actions: {
- },
- modules: {
- }
+ state,
+ mutations,
+ actions: {},
+ modules: {}
})
diff --git a/src/views/Home.vue b/src/views/Home.vue
index 02d9ab5..7d00042 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -1,17 +1,14 @@
-