瀏覽代碼

富文本编辑器

zhuliu 1 年之前
父節點
當前提交
aead475e89
共有 2 個文件被更改,包括 80 次插入17 次删除
  1. 5 17
      src/utils/model/prosemirror/index.vue
  2. 75 0
      src/utils/model/prosemirror/menu.js

+ 5 - 17
src/utils/model/prosemirror/index.vue

@@ -1,15 +1,15 @@
 <template>
-  <Editor  ref="editor"></Editor>
+  <Editor @didCreate="didCreate"  ref="editor"></Editor>
 </template>
 
 <script>
 import Editor from 'vue-prosemirror-editor'
-import { menu  } from 'prosemirror-menu';  
-import 'prosemirror-menu/style/menu.css'; // 导入菜单样式  
+import { common } from './menu.js'
 export default {
   components: {
     Editor
   },
+  mixins:[common],
   props: {},
   data() {
     return {
@@ -20,7 +20,7 @@ export default {
   computed: {},
   created() {},
   mounted() {
-   this.init()
+  //  this.init()
   },
   methods: {
     init(){
@@ -43,19 +43,7 @@ export default {
       tr.addMark(selection, markType.create()).setMeta('addToHistory', true);  
       return dispatch(tr);  
     },
-    didCreate(val){
-      this.editor = val
-      var state = this.editor.state
-      var view = this.editor.view
-      console.log(MenuItem)
-      const menu = new MenuItem({  
-        state,  
-        view,  
-        // ... 其他配置选项  
-      });  
-      console.log(view) 
-      this.editor.view.someProp =  menu
-    },
+   
     bold(){
       const { view, state, tr } = this.editor;  
       tr.toggleMark(state.schema.marks.bold);  

+ 75 - 0
src/utils/model/prosemirror/menu.js

@@ -0,0 +1,75 @@
+import Vue from 'vue'
+import {Plugin} from "prosemirror-state"
+import {toggleMark, setBlockType, wrapIn} from "prosemirror-commands"
+import {schema} from "prosemirror-schema-basic"
+
+export class MenuView {
+    constructor(items, editorView) {
+      this.items = items
+      this.editorView = editorView
+  
+      this.dom = document.createElement("div")
+      this.dom.className = "menubar"
+      items.forEach(({dom}) => this.dom.appendChild(dom))
+      this.update()
+  
+      this.dom.addEventListener("mousedown", e => {
+        e.preventDefault()
+        editorView.focus()
+        items.forEach(({command, dom}) => {
+          if (dom.contains(e.target))
+            command(editorView.state, editorView.dispatch, editorView)
+        })
+      })
+    }
+  
+    update() {
+      this.items.forEach(({command, dom}) => {
+        let active = command(this.editorView.state, null, this.editorView)
+        dom.style.display = active ? "" : "none"
+      })
+    }
+  
+    destroy() { this.dom.remove() }
+}
+
+export function menuPlugin(items) {
+    return new Plugin({
+      view(editorView) {
+        let menuView = new MenuView(items, editorView)
+        editorView.dom.parentNode.insertBefore(menuView.dom, editorView.dom)
+        return menuView
+      }
+    })
+}
+
+export function icon(text, name) {
+    let span = document.createElement("span")
+    span.className = "menuicon " + name
+    span.title = name
+    span.textContent = text
+    return span
+  }
+  
+  // 创建一个给定级别的标题图标
+  export  function heading(level) {
+    return {
+      command: setBlockType(schema.nodes.heading, {level}),
+      dom: icon("H" + level, "heading")
+    }
+  }
+  export const common = {
+    methods:{
+        didCreate(val){
+            this.editor = val
+            let menu = menuPlugin([
+            {command: toggleMark(schema.marks.strong), dom: icon("B", "strong")},
+            {command: toggleMark(schema.marks.em), dom: icon("i", "em")},
+            {command: setBlockType(schema.nodes.paragraph), dom: icon("p", "paragraph")},
+            heading(1), heading(2), heading(3),
+            {command: wrapIn(schema.nodes.blockquote), dom: icon(">", "blockquote")}
+            ])
+        },
+    }
+    
+}