vue.js 渲染函数_Vue.js的不可渲染且可扩展的RTF编辑器[通俗易懂]

vue.js 渲染函数_Vue.js的不可渲染且可扩展的RTF编辑器[通俗易懂]vue.js渲染函数轻按(tiptap)Arich-texteditorforVue.js.Vue.js的富文本编辑器。Viewdemo查看演示DownloadSource下载源什么是无renderless?(Whatmeansrenderless?)Withrenderlesscomponentsyou’llhave(almost)…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

vue.js 渲染函数

轻按 (tiptap)

A rich-text editor for Vue.js.

Vue.js的富文本编辑器。

tiptapv

什么是无renderless(What means renderless?)

With renderless components you’ll have (almost) full control over markup and styling. I don’t want to tell you what a menu should look like or where it should be rendered in the DOM. That’s all up to you. There is also a good article about renderless components by Adam Wathan.

使用无渲染组件,您将(几乎)完全控制标记和样式。 我不想告诉您菜单的外观或在DOM中的显示位置。 这完全取决于您。 Adam Wathan也有一篇关于无渲染组件的好文章

数据如何存储在后台? (How is the data stored under the hood?)

You can save your data as a raw HTML string or can get a JSON-serializable representation of your document. And of course, you can pass these two types back to the editor.

您可以将数据另存为原始HTML字符串,也可以获取文档的JSON序列化表示。 当然,您可以将这两种类型传递回编辑器。

例子 (Examples)

To check out some live examples, visit tiptap.scrumpy.io.

要查看一些实时示例,请访问tiptap.scrumpy.io

安装 (Installation)

npm install tiptap

or

要么

yarn add tiptap

基本设定 (Basic Setup)

<template>
  <editor>
    <!-- Add HTML to the scoped slot called `content` -->
    <div slot="content" slot-scope="props">
      <p>Hi, I'm just a boring paragraph</p>
    </div>
  </editor>
</template>

<script>
// Import the editor
import { Editor } from 'tiptap'

export default {
  components: {
    Editor,
  },
}
</script>

编辑器属性 (Editor Properties)

Property Type Default Description
editable Boolean true When set to false the editor is read-only.
doc Object null The editor state object used by Prosemirror. You can also pass HTML to the content slot. When used both, the content slot will be ignored.
watchDoc Boolean true If set to true the content gets updated whenever doc changes.
extensions Array [] A list of extensions used, by the editor. This can be Nodes, Marks or Plugins.
@init Object undefined This will return an Object with the current state and view of Prosemirror on init.
@update Object undefined This will return an Object with the current state of Prosemirror, a getJSON() and getHTML() function on every change.
属性 类型 默认 描述
editable Boolean true 设置为false ,编辑器为只读。
doc Object null Prosemirror使用的编辑器状态对象。 您还可以将HTML传递到content插槽。 同时使用两者时, content位置将被忽略。
watchDoc Boolean true 如果设置为true则每当doc更改时内容就会更新。
extensions Array [] 编辑器使用的扩展名列表。 这可以是NodesMarksPlugins
@init Object undefined 这将返回一个具有当前state的对象,并在初始化时view Prosemirror view
@update Object undefined 这将返回具有Prosemirror当前state的Object,每次更改都将返回getJSON()getHTML()函数。

范围插槽 (Scoped Slots)

Name Description
editor Here the content will be rendered.
menubar Here a menu bar will be rendered.
menububble Here a menu bubble will be rendered.
名称 描述
editor 这里将呈现内容。
menubar 这里将显示一个菜单栏。
menububble 此处将呈现菜单气泡。

插槽属性 (Slot Properties)

The menubar and menububble slot will receive some properties.

menubarmenubar menububble槽将接收一些属性。

Property Type Description
nodes Object A list of available nodes with active state and command.
marks Object A list of available marks with active state and command.
focused Boolean Whether the editor is focused.
focus Function A function to focus the editor.
属性 类型 描述
nodes Object 具有活动状态和命令的可用节点的列表。
marks Object 具有活动状态和命令的可用标记的列表。
focused Boolean 编辑器是否专注。
focus Function 聚焦编辑器的功能。

扩展名 (Extensions)

By default, the editor will only support paragraphs. Other nodes and marks are available as extensions. There is a package called tiptap-extensions with the most basic nodes, marks, and plugins.

默认情况下,编辑器仅支持段落。 其他节点和标记可用作扩展 。 有一个名为tiptap-extensions的程序包,其中包含最基本的节点,标记和插件。

可用扩展 (Available Extensions)

<template>
  <editor :extensions="extensions">
    <div slot="content" slot-scope="props">
      <h1>Yay Headlines!</h1>
      <p>All these <strong>cool tags</strong> are working now.</p>
    </div>
  </editor>
</template>

<script>
import { Editor } from 'tiptap'
import {
  // Nodes
  BlockquoteNode,
  BulletListNode,
  CodeBlockNode,
  CodeBlockHighlightNode,
  HardBreakNode,
  HeadingNode,
  ImageNode,
  ListItemNode,
  OrderedListNode,
  TodoItemNode,
  TodoListNode,

  // Marks
  BoldMark,
  CodeMark,
  ItalicMark,
  LinkMark,
  StrikeMark,
  UnderlineMark,

  // General Extensions
  HistoryExtension,
  PlaceholderExtension,
} from 'tiptap-extensions'

export default {
  components: {
    Editor,
  },
  data() {
    return {
      extensions: [
        new BlockquoteNode(),
        new BulletListNode(),
        new CodeBlockNode(),
        new HardBreakNode(),
        new HeadingNode({ maxLevel: 3 }),
        new ImageNode(),
        new ListItemNode(),
        new OrderedListNode(),
        new TodoItemNode(),
        new TodoListNode(),
        new BoldMark(),
        new CodeMark(),
        new ItalicMark(),
        new LinkMark(),
        new StrikeMark(),
        new UnderlineMark(),
        new HistoryExtension(),
        new PlaceholderExtension(),
      ],
    }
  },
}
</script>

创建自定义扩展 (Create Custom Extensions)

The most powerful feature of tiptap is that you can create your own extensions. There are 3 types of extensions.

Tiptap最强大的功能是您可以创建自己的扩展程序。 有3种扩展名。

Type Description
Extension The most basic type. It’s useful to register some Prosemirror plugins or some input rules.
Node Add a custom node. Nodes are block elements like a headline or a paragraph.
Mark Add a custom mark. Marks are used to add extra styling or other information to inline content like a strong tag or links.
类型 描述
Extension 最基本的类型。 注册一些Prosemirror插件或一些输入规则很有用。
Node 添加一个自定义节点。 节点是块元素,例如标题或段落。
Mark 添加自定义标记。 标记用于向内嵌内容(如强标签或链接)添加额外的样式或其他信息。

扩展类 (Extension Class)

Method Type Default Description
get name() String null Define a name for your extension.
get defaultOptions() Object {} Define some default options. The options are available as this.$options.
get plugins() Array [] Define a list of Prosemirror plugins.
keys({ schema }) Object null Define some keybindings.
inputRules({ schema }) Array [] Define a list of input rules.
方法 类型 默认 描述
get name() String null 为您的扩展名定义一个名称。
get defaultOptions() Object {} 定义一些默认选项。 这些选项可作为this.$options
get plugins() Array [] 定义Prosemirror插件列表。
keys({ schema }) Object null 定义一些键绑定。
inputRules({ schema }) Array [] 定义输入规则列表。

节点|标记类 (Node|Mark Class)

Method Type Default Description
get name() String null Define a name for your node or mark.
get defaultOptions() Object {} Define some default options. The options are available as this.$options.
get schema() Object null Define a schema.
get view() Object null Define a node view as a vue component.
keys({ type, schema }) Object null Define some keybindings.
command({ type, schema, attrs }) Object null Define a command. This is used for menus to convert to this node or mark.
inputRules({ type, schema }) Array [] Define a list of input rules.
get plugins() Array [] Define a list of Prosemirror plugins.
方法 类型 默认 描述
get name() String null 为节点或标记定义名称。
get defaultOptions() Object {} 定义一些默认选项。 这些选项可作为this.$options
get schema() Object null 定义一个模式
get view() Object null 将节点视图定义为vue组件。
keys({ type, schema }) Object null 定义一些键绑定。
command({ type, schema, attrs }) Object null 定义一个命令。 这用于菜单转换为该节点或标记。
inputRules({ type, schema }) Array [] 定义输入规则列表。
get plugins() Array [] 定义Prosemirror插件列表。

创建一个节点 (Create a Node)

Let’s take a look at a real example. This is basically how the default blockquote node from tiptap-extensions looks like.

让我们看一个真实的例子。 这基本上是来自tiptap-extensions的默认blockquote节点的外观。

import { Node } from 'tiptap'
import { wrappingInputRule, setBlockType, wrapIn } from 'tiptap-commands'

export default class BlockquoteNode extends Node {

  // choose a unique name
  get name() {
    return 'blockquote'
  }

  // the prosemirror schema object
  // take a look at https://prosemirror.net/docs/guide/#schema for a detailed explanation
  get schema() {
    return {
      content: 'block+',
      group: 'block',
      defining: true,
      draggable: false,
      // define how the editor will detect your node from pasted HTML
      // every blockquote tag will be converted to this blockquote node
      parseDOM: [
        { tag: 'blockquote' },
      ],
      // this is how this node will be rendered
      // in this case a blockquote tag with a class called `awesome-blockquote` will be rendered
      // the '0' stands for its text content inside
      toDOM: () => ['blockquote', { class: 'awesome-blockquote' }, 0],
    }
  }

  // this command will be called from menus to add a blockquote
  // `type` is the prosemirror schema object for this blockquote
  // `schema` is a collection of all registered nodes and marks
  command({ type, schema }) {
    return wrapIn(type)
  }

  // here you can register some shortcuts
  // in this case you can create a blockquote with `ctrl` + `>`
  keys({ type }) {
    return {
      'Ctrl->': wrapIn(type),
    }
  }

  // a blockquote will be created when you are on a new line and type `>` followed by a space
  inputRules({ type }) {
    return [
      wrappingInputRule(/^\s*>\s$/, type),
    ]
  }

}

创建节点作为Vue组件 (Create a Node as a Vue Component)

The real power of the nodes comes in combination with Vue components. Let us build an iframe node, where you can change its URL (this can also be found in our examples).

节点的真正功能与Vue组件结合在一起。 让我们构建一个iframe节点,您可以在其中更改其URL(这也可以在我们的示例中找到)。

import { Node } from 'tiptap'

export default class IframeNode extends Node {

  get name() {
    return 'iframe'
  }

  get schema() {
    return {
      // here you have to specify all values that can be stored in this node
      attrs: {
        src: {
          default: null,
        },
      },
      group: 'block',
      selectable: false,
      // parseDOM and toDOM is still required to make copy and paste work
      parseDOM: [{
        tag: 'iframe',
        getAttrs: dom => ({
          src: dom.getAttribute('src'),
        }),
      }],
      toDOM: node => ['iframe', {
        src: node.attrs.src,
        frameborder: 0,
        allowfullscreen: 'true',
      }],
    }
  }

  // return a vue component
  // this can be an object or an imported component
  get view() {
    return {
      // there are some props available
      // `node` is a Prosemirror Node Object
      // `updateAttrs` is a function to update attributes defined in `schema`
      // `editable` is the global editor prop whether the content can be edited
      props: ['node', 'updateAttrs', 'editable'],
      data() {
        return {
          // save the iframe src in a new variable because `this.node.attrs` is immutable
          url: this.node.attrs.src,
        }
      },
      methods: {
        onChange(event) {
          this.url = event.target.value

          // update the iframe url
          this.updateAttrs({
            src: this.url,
          })
        },
      },
      template: `
        <div class="iframe">
          <iframe class="iframe__embed" :src="url"></iframe>
          <input class="iframe__input" type="text" :value="url" @input="onChange" v-if="editable" />
        </div>
      `,
    }
  }

}

建立菜单 (Building a Menu)

This is a basic example of building a custom menu. A more advanced menu can be found at the examples page.

这是构建自定义菜单的基本示例。 在示例页面上可以找到更高级的菜单。

<template>
  <editor :extensions="extensions">
    <div slot="menubar" slot-scope="{ nodes, marks }">
      <div v-if="nodes && marks">
        <button :class="{ 'is-active': nodes.heading.active({ level: 1 }) }" @click="nodes.heading.command({ level: 1 })">
          H1
        </button>
        <button :class="{ 'is-active': marks.bold.active() }" @click="marks.bold.command()">
          Bold
        </button>
      </div>
    </div>
    <div slot="content" slot-scope="props">
      <p>This text can be made bold.</p>
    </div>
  </editor>
</template>

<script>
import { Editor } from 'tiptap'
import { HeadingNode, BoldMark } from 'tiptap-extensions'

export default {
  components: {
    Editor,
  },
  data() {
    return {
      extensions: [
        new HeadingNode({ maxLevel: 3 }),
        new BoldMark(),
      ],
    }
  },
}
</script>

开发设置 (Development Setup)

Currently, only Yarn is supported for development because of a feature called workspaces we are using here.

目前,由于我们在此使用的称为工作区的功能,仅支持Yarn进行开发。

# install dependencies
yarn install

# serve examples at localhost:3000
yarn start

# build dist files for packages
yarn build:packages

# build dist files for examples
yarn build:examples

翻译自: https://vuejsexamples.com/a-renderless-and-extendable-rich-text-editor-for-vue-js/

vue.js 渲染函数

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/194998.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Linux如何切换到root用户(linux禁止用户切换root)

    Linux如何切换到root用户(linux禁止用户切换root)1.首先,我们输入pwd命令,查看当前用户目录:当前用户是xg其中我解释一下[xg@localhost~]$ 这个的含义,其中xg指的是当前的用户,localhost指的是本机服务,~指的是当前目录,后面的$符号指的是普通用户,如果是root用户的话,就会变成下图这样,其中的#符号指的就是root用户:2.这时我们分别输入su xg和su-,如下图所示:输入suxg命

  • mysql自定义函数命名_MySQL自定义函数[通俗易懂]

    mysql自定义函数命名_MySQL自定义函数[通俗易懂]在使用MySQL的过程中,MySQL自带的函数可能完成不了我们的业务需求,这时候就需要自定义函数。自定义函数是一种与存储过程十分相似的过程式数据库对象。它与存储过程一样,都是由SQL语句和过程式语句组成的代码片段,并且可以被应用程序和其他SQL语句调用。自定义函数与存储过程之间存在几点区别:1.自定义函数不能拥有输出参数,这是因为自定义函数自身就是输出参数;而存储过程可以拥有输出参数…

  • Java 面试之 IO 流及Socket

    Java 面试之 IO 流及SocketJava 面试之 IO 流及Socket

  • 离线数仓和实时数仓架构与设计

    离线数仓和实时数仓架构与设计前言:离线数仓和实时数仓架构与设计讲解离线数仓和实时数仓架构与设计一、数仓架构演变(场景驱动)二、离线大数据架构三、离线数仓分层四、离线大数据架构典型案例1、Lambda架构1.Lambda架构2.Lambda架构进一步了解3.Lambda架构典型案例4.Lambda架构典型案例(有赞广告团,基于Druid)5.Lambda架构存在的问题2、Kappa架构1.Kappa架构典型案例2.Kappa架构典型案例(一Kylin为例)3.Kappa架构的重新处理过程3、Lambda架构vsKappa架构的对比

  • lamp配置多个虚拟站点

    lamp配置多个虚拟站点在同一ip下添加多个域名站点!1.查看ip命令:ifconfig2.添加域名命令:vi/etc/hosts输入域名:如192.168.160.127www.test.com192.168.160.127www.test2.com3.创建要配置站点的文件夹及文件.var/www/test/index.php/var/www/test2/inde…

  • LMDB使用说明_ldd教程

    LMDB使用说明_ldd教程http://rayz0620.github.io/2015/05/25/lmdb_in_caffe/官方的extract_feature.bin很好用,但是输出的特征是放在LMDB里的。以前嫌LMDB麻烦,一直都图方便直接用ImageDataLayer来读原始图像。这次绕不过去了,就顺便研究了一下Caffe对LMDB的使用,一些心得写下来和大家分享一下。提取特征的内容下一篇再写。

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号