tiptap Link 扩展支持在文档中创建超链接,tiptap 没有提供 UI界面,添加删除编辑 URL 链接你需要通过tiptap命令来执行,粘贴的url将自动转换为链接。
npm install @tiptap/extension-link
protocols 自定义可以识别为链接的协议。
Link.configure({
protocols: ['ftp', 'mailto']
})
autolink 当用户在编辑器内输入网址时自动加上超链接。
Link.configure({
autolink: false
})
openOnClick 点击时打开链接。
Link.configure({
openOnClick: false
})
linkOnPaste 粘贴内容时是否将内容里面的url转换为链接。
Link.configure({
linkOnPaste: false
})
HTMLAttributes 自定义标签属性。
Link.configure({
HTMLAttributes: {
class: 'my-custom-class',
rel: 'noopener noreferrer',
// Remove target entirely so links open in current tab
target: null,
},
})
validate 自动识别创建链接时对URL进行校验,比如你可以用来只能创建https://www.itxst.com 的链接 。
// only autolink urls with a protocol
Link.configure({
validate: href => /^https?:\/\//.test(href),
})
setLink 创建超链接。
editor.commands.setLink({ href: 'https://www.itxst.com' })
editor.commands.setLink({ href: 'https://www.itxst.com', target: '_blank' })
ttoggleLink 切换为超链接。
editor.commands.toggleLink()
unsetLink 移除链接。
editor.commands.unsetLink()
获取当前链接
this.editor.getAttributes('link').href
Vue 例子
React 例子
React CSS
<template>
<div v-if="editor">
<button @click="setLink" :class="{ 'is-active': editor.isActive('link') }">
setLink
</button>
<button @click="editor.chain().focus().unsetLink().run()" :disabled="!editor.isActive('link')">
unsetLink
</button>
<editor-content :editor="editor" />
</div>
</template>
<script>
import Code from '@tiptap/extension-code'
import Document from '@tiptap/extension-document'
import Link from '@tiptap/extension-link'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { Editor, EditorContent } from '@tiptap/vue-3'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Code,
Link.configure({
openOnClick: false,
}),
],
content: `
<p>
Wow, this editor has support for links to the whole <a href="https://en.wikipedia.org/wiki/World_Wide_Web">world wide web</a>. We tested a lot of URLs and I think you can add *every URL* you want. Isn’t that cool? Let’s try <a href="https://statamic.com/">another one!</a> Yep, seems to work.
</p>
<p>
By default every link will get a <code>rel="noopener noreferrer nofollow"</code> attribute. It’s configurable though.
</p>
`,
})
},
methods: {
setLink() {
const previousUrl = this.editor.getAttributes('link').href
const url = window.prompt('URL', previousUrl)
// cancelled
if (url === null) {
return
}
// empty
if (url === '') {
this.editor
.chain()
.focus()
.extendMarkRange('link')
.unsetLink()
.run()
return
}
// update link
this.editor
.chain()
.focus()
.extendMarkRange('link')
.setLink({ href: url })
.run()
},
},
beforeUnmount() {
this.editor.destroy()
},
}
</script>
<style>
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
a {
color: #68CEF8;
}
code {
font-size: 0.9rem;
padding: 0.25em;
border-radius: 0.25em;
background-color: rgba(#616161, 0.1);
color: #616161;
box-decoration-break: clone;
}
}
</style>
import './styles.scss'
import Code from '@tiptap/extension-code'
import Document from '@tiptap/extension-document'
import Link from '@tiptap/extension-link'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React, { useCallback } from 'react'
export default () => {
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Code,
Link.configure({
openOnClick: false,
}),
],
content: `
<p>
Wow, this editor has support for links to the whole <a href="https://en.wikipedia.org/wiki/World_Wide_Web">world wide web</a>. We tested a lot of URLs and I think you can add *every URL* you want. Isn’t that cool? Let’s try <a href="https://statamic.com/">another one!</a> Yep, seems to work.
</p>
<p>
By default every link will get a <code>rel="noopener noreferrer nofollow"</code> attribute. It’s configurable though.
</p>
`,
})
const setLink = useCallback(() => {
const previousUrl = editor.getAttributes('link').href
const url = window.prompt('URL', previousUrl)
// cancelled
if (url === null) {
return
}
// empty
if (url === '') {
editor.chain().focus().extendMarkRange('link').unsetLink()
.run()
return
}
// update link
editor.chain().focus().extendMarkRange('link').setLink({ href: url })
.run()
}, [editor])
if (!editor) {
return null
}
return (
<>
<button onClick={setLink} className={editor.isActive('link') ? 'is-active' : ''}>
setLink
</button>
<button
onClick={() => editor.chain().focus().unsetLink().run()}
disabled={!editor.isActive('link')}
>
unsetLink
</button>
<EditorContent editor={editor} />
</>
)
}
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
a {
color: #68cef8;
}
code {
background-color: rgba(#616161, 0.1);
border-radius: 0.25em;
box-decoration-break: clone;
color: #616161;
font-size: 0.9rem;
padding: 0.25em;
}
}
本教程Demo的源码点击这里下载,Tiptap Demo,下载完成后运行npm i初始化依赖包。