vue+tiptap ,基于vue的无渲染的富文本编辑器_鸣拙的博客-程序员宅基地

技术标签: VUE  vue  markdown  

安装tiptap

官网:
github:https://github.com/ueberdosis/tiptap
演示:https://www.vue365.cn/code_demo.php?id=975

npm install tiptap
npm install tiptap-extensions

该编辑器基于prosemiror,完全可扩展且无渲染。您可以轻松地将自定义节点添加为Vue组件。

基础案例

// 如果点击按钮,页面文本的样式没有改变,查看元素的标签是否已经改变,标签已改变,只是页面的样式没有改变,可以查看示例的css样式,
<template>
  <div class="editor">
    <editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
          <div class="menubar">
            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.bold() }"
              @click="commands.bold"
              title="加粗"
            >
              <!-- <icon name="bold" /> -->
              <i class="iconfont r-bold"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.italic() }"
              @click="commands.italic"
              title="斜体"
            >
              <!-- <icon name="italic" /> -->
              <i class="iconfont r-italic"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.strike() }"
              @click="commands.strike"
            >
              <!-- <icon name="strike" /> -->
              <i class="iconfont r-strike"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.underline() }"
              @click="commands.underline"
              title="下划线"
            >
              <!-- <icon name="underline" /> -->
              <i class="iconfont r-underline"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.code() }"
              @click="commands.code"
              title="代码"
            >
              <!-- <icon name="code" /> -->
              <i class="iconfont r-code"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.paragraph() }"
              @click="commands.paragraph"
            >
              <!-- <icon name="paragraph" /> -->
              <i class="iconfont r-paragraph"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.heading({ level: 1 }) }"
              @click="commands.heading({ level: 1 })"
              title="标题1"
            >
              H1
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.heading({ level: 2 }) }"
              @click="commands.heading({ level: 2 })"
              title="标题2"
            >
              H2
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.heading({ level: 3 }) }"
              @click="commands.heading({ level: 3 })"
              title="标题3"
            >
              H3
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.bullet_list() }"
              @click="commands.bullet_list"
              title="有序列表"
            >
              <!-- <icon name="ul" /> -->
              <i class="iconfont r-ul"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.ordered_list() }"
              @click="commands.ordered_list"
              title="无序列表"
            >
              <!-- <icon name="ol" /> -->
              <i class="iconfont r-ol"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.blockquote() }"
              @click="commands.blockquote"
              title="引用"
            >
              <!-- <icon name="quote" /> -->
              <i class="iconfont r-TextQuote-1"></i>
            </el-button>

            <el-button
              class="menubar__button"
              :class="{ 'is-active': isActive.code_block() }"
              @click="commands.code_block"
              title="代码块"
            >
              <!-- <icon name="code" /> -->
              <i class="iconfont r-code"></i>
            </el-button>

            <el-button
              class="menubar__button"
              @click="commands.horizontal_rule"
              title="基准线"
            >
              <!-- <icon name="hr" /> -->
              <i class="iconfont r-hr"></i>
            </el-button>

            <el-button
              class="menubar__button"
              @click="commands.undo"
              title="恢复"
            >
              <!-- <icon name="undo" /> -->
              <i class="iconfont r-undo"></i>
            </el-button>

            <el-button
              class="menubar__button"
              @click="commands.redo"
              title="重做"
            >
              <!-- <icon name="redo" /> -->
              <i class="iconfont r-redo"></i>
            </el-button>
          </div>
        </editor-menu-bar>

    <editor-content class="editor__content" :editor="editor" />
  </div>
</template>

<script>
import {
     Editor, EditorContent, EditorMenuBar } from 'tiptap'
import {
    
  Blockquote,
  CodeBlock,
  HardBreak,
  Heading,
  HorizontalRule,
  OrderedList,
  BulletList,
  ListItem,
  TodoItem,
  TodoList,
  Bold,
  Code,
  Italic,
  Link,
  Strike,
  Underline,
  History
} from 'tiptap-extensions'
export default {
    
  components: {
    
    EditorContent,
    EditorMenuBar
  },
  data () {
    
    return {
    
      editor: new Editor({
    
        extensions: [
          new Blockquote(),
          new BulletList(),
          new CodeBlock(),
          new HardBreak(),
          new Heading({
     levels: [1, 2, 3] }),
          new HorizontalRule(),
          new ListItem(),
          new OrderedList(),
          new TodoItem(),
          new TodoList(),
          new Link(),
          new Bold(),
          new Code(),
          new Italic(),
          new Strike(),
          new Underline(),
          new History()
        ],
        content: `
          <h2>
            Hi there,
          </h2>
          <p>
            this is a very <em>basic</em> example of tiptap.
          </p>
          <pre><code>body { display: none; }</code></pre>
          <ul>
            <li>
              A regular list
            </li>
            <li>
              With regular items
            </li>
          </ul>
          <blockquote>
            It's amazing 
            <br />
            – mom
          </blockquote>
        `
      })
    }
  },
  beforeDestroy () {
    
    this.editor.destroy()
  }
}
</script>
<style>
.editor__content .ProseMirror pre {
    
    padding: .7rem 1rem;
    border-radius: 5px;
    background: #000;
    color: #fff;
    font-size: .8rem;
    overflow-x: auto;
}
.editor__content .ProseMirror blockquote {
    
    border-left: 3px solid rgba(0,0,0,.1);
    color: rgba(0,0,0,.8);
    padding-left: .8rem;
    font-style: italic;
}
.editor__content .ProseMirror p code {
    
    padding: .2rem .4rem;
    border-radius: 5px;
    font-size: .8rem;
    font-weight: 700;
    background: rgba(0,0,0,.1);
    color: rgba(0,0,0,.8);
}
</style>

图示:
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45939191/article/details/115393693

智能推荐

vite element-plus自定义主题按需导入不生效-程序员宅基地

1. 使用官方CLI 主题工具编译sass为css文件 (node版本v10.24.1)2.复制编译后的theme文件夹到主项目3.主项目导入所有css文件import { createApp } from 'vue';import App from './App.vue';import '@/mock';import './theme/index.css'createApp(App) .mount('#app');4.修改vite配置- node 版本切换...

im2col函数解析-程序员宅基地

im2col函数是进行卷积运算所常用的一个函数,它的作用是将进行卷积运算的一组图片二维化,而后再与卷积核进行矩阵相乘,代替了卷积运算原来相乘再相加的运算形式,可以大大减少运算所需时间。接下来介绍im2col函数的实现原理以及其不同形式。先上代码def im2col(input_img, FH, FW, stride=1, pad=0): """ :param input_img...

Autocad二次开发vba教程第二课-程序员宅基地

下面是源码:Sub c100()Dim cc(0 To 2) As Double 声明坐标变量cc(0) = 1000 定义圆心座标cc(1) = 1000cc(2) = 0For i = 1 To 1000 Step 10 开始循环Call ThisDrawing.ModelSpace.AddCircle(cc, i * 10) 画圆Next iEnd Sub先看第一行和最后一

MFC 关于OnPaint绘图的一些经验_mfc onpaint-程序员宅基地

MFC 关于OnPaint绘图的一些经验_mfc onpaint

不平衡数据集的处理-程序员宅基地

一、不平衡数据集的定义所谓的不平衡数据集指的是数据集各个类别的样本量极不均衡。以二分类问题为例,假设正类的样本数量远大于负类的样本数量,通常情况下通常情况下把多数类样本的比例接近100:1这种情况下的数据称为不平衡数据。不平衡数据的学习即需要在分布不均匀的数据集中学习到有用的信息。不平衡数据集的处理方法主要分为两个方面:1、从数据的角度出发,主要方法为采样,分为欠采样和过采...

cisco 华为交换机端口镜像配置-程序员宅基地

<snip>!interface FastEthernet0/1port monitor FastEthernet0/2port monitor FastEthernet0/5port monitor VLAN1!interface FastEthernet0/2!Cisco − Configuring the Catalyst S...

随便推点

创建 ROS 工作空间遇到的问题-程序员宅基地

在 Ubuntu 16.04 下创建 catkin 的 工作空间遇到了关于 python 路径依赖的问题。1.source /opt/ros/kinetic/setup.bash 2.mkdir -p ~/catkin_ws/src 3.cd ~/catkin_ws/src4.catkin_init_workspace5. 进入上级目录 catkin_make成功的话执行后面...

Golang testing包 测试使用示例教程-程序员宅基地

示例代码:root/E.gopackage mainimport "fmt"// F1 get stringfunc F1() string { return "www.ydook.com : testing for golang"}func main() { a := F1() fmt.Println(a)}root/E_test.gopackage main...

对嵌入式linux驱动开发的理解_linux嵌入式要求_zhvngchvng的博客-程序员宅基地

做嵌入式linux驱动开发,首先要搞明白大致框架。linux的驱动通常分为字符设备驱动、块设备驱动和网络设备驱动三大块。字符设备是最普遍的应用,用于简单控制、读写、传输数据等等,块设备主要与硬盘、EMMC等存储设备有关,网络设备驱动则是与以太网、wifi相关的驱动。块设备驱动和网络设备驱动一般由原厂提供,可以直接使用,我们开发人员只需要根据具体应用需求编写相应的字符设备驱动即可。linux一切皆文件,我们开发字符设备驱动就是要实现对该设备的read write open release等函数。一般以设备_linux嵌入式要求

三款开源 Kubernetes 负载均衡器大比拼 (MetalLB vs PureLB vs OpenELB)-程序员宅基地

公众号关注「奇妙的 Linux 世界」设为「星标」,每天带你玩转 Linux !原文链接:https://ewhisper.cn/posts/29610/????译者声明:请注意文章发布时间,时间比较久远,部分观点可能已经过时。原文作者为 PureLB 的利益相关者,所以本文可能不尽客观。词汇表英文中文备注LoadBalancer负载均衡器本文指 Kubernetes Lo..._开源负载均衡软件

基于 STM32+FPGA 的通用工业控制器设计(一)系统方案设计-程序员宅基地

设计用户程序的编程语言,作为人类自然语言与底层芯片编程语言之间的桥梁,能够提供任务调度与管理、内存管理、任务间同步与通信、时间管理和中断服务等功能,振,但是精度没有外部配置的高速晶振精度高。就是内核可配置,采用模块化的设计方式带来的灵活的配置,核心部分由小同的组件构。任务管理、时间管理、信号量、消息队列、内存管理、记录等功能,可以满足一个最小。器人、电梯控制等场合,用于驱动步进电机、伺服电机或交流电动机,此时需要控制器。控制经常用于冶金、化工、锅炉控制等场合,用于对温度、压力、流量等模拟量的闭环。

vue-cli打包给静态资源添加版本号。-程序员宅基地

在build文件夹下的webpack.prod.conf里的搜索HtmlWebpackPlugin处,添加hash值就可以了。