vue의tiptap에서iframe로 생성된 외부 내용을 삽입합니다

11362 단어 iframetiptapVue.js

개요


vue에서 WYSIWYG 편집기의 tiptap에 다른 사이트를 표시하는 방법을 소개합니다.

단계


  • Iframely
  • tiptap의 사용자 정의 노드를 정의하고 iframe로 Iframely의 URL을 표시합니다
  • 세부 정보


    API 키를 가져오려면 Iframely에 서명


    https://iframely.com/에서 업그레이드하면 사용자가 등록하면 API 키가 발행되므로 이 키를 사용합니다.월 최대 1만 회까지 무료로 이용할 수 있다.
    API 키 예제58xx1axxbxxxcca68fxxxdb새로 고치면 홈 페이지에 자신의 API 키가 표시됩니다.

    tiptap의 사용자 정의 노드 정의


    다음 js 파일을 만들고 vue 구성 요소와 같은 폴더에 준비합니다.toDom는 점으로 수조 정의 서브노드를 대량으로 사용하여 다음과 같은 html를 생성한다.
    공식 가이드의 Iframely embeds for CKEditor oEmbed plugin 이 페이지CKEditor에 있는 WYSIWYG 편집기의 설치 예가 있기 때문에 참고하십시오.

    생성할 HTML

    <div class="iframely-embed">
      <div class="iframely-responsive">
        <iframe src="//cdn.iframe.ly/api/iframe?app=1&api_key=APIキー&url=エンコードされたURL" 'frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
      </div>
    </div>
    

    CDN에서 iframely로의 embed.js 가져오기(2021/1/1 추적)


    index.html의 경우
      <script src="//cdn.iframe.ly/embed.js" async></script>
    
    nuxt.config.js시
    export default {
      // Global page headers (https://go.nuxtjs.dev/config-head)
      head: {
        title: 'xxxxx',
        meta: [
          { charset: 'utf-8' },
          { name: 'viewport', content: 'width=device-width, initial-scale=1' },
          { hid: 'description', name: 'description', content: '' }
        ],
        link: [
          { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
        ],
        script: [
          { src: '//cdn.iframe.ly/embed.js'}
        ]
      },
    ...
    

    tiptap 생성 사용자 정의 노드 js


    tiptap는 웹에 풍부한 텍스트 편집기 ProseMirror 를 구축하기 위해 도구 패키지를 사용합니다. 그 규격은 이 도구 패키지를 따라야 합니다.그 방법이 방대하고 이해하는 데 시간이 걸릴 것 같아서 실험을 거듭하면서 진행했어요.
    Embed.js
    import { Node } from 'tiptap'
    
    export default class Embed extends Node {
    
      get name() {
        return 'embed'
      }
    
      get schema() {
        return {
          attrs: {
            src: {
              default: null,
            }
          },
          group: 'block',
          selectable: false,
          parseDOM: [{
            tag: 'iframe',
            getAttrs: dom => ({
              src: dom.getAttribute('src'),
            }),
          }],
          toDOM: node => ['div', { class: 'iframely-embed' },
            ['div', { class: 'iframely-responsive', style: 'padding-bottom: 66.6667%; padding-top: 120px;' },
              ['iframe', {
                src: '//cdn.iframe.ly/api/iframe?app=1&api_key=58xx1axxbxxxcca68fxxxdb&url=' + encodeURIComponent(node.attrs.src), // ここは自分のAPI Keyを設定する
                frameborder: "0",
                allow: "autoplay; encrypted-media",
              }]
            ]
          ],
        }
      }
    
      commands({ type }) {
        return attrs => (state, dispatch) => {
          const { selection } = state;
          const position = selection.$cursor
            ? selection.$cursor.pos
            : selection.$to.pos;
          const node = type.create(attrs);
          const transaction = state.tr.insert(position, node);
          dispatch(transaction);
        };
      }
    
    }
    
    2021/1/1 업데이트
    위의 toDOM에 있는 iframe의 지정으로 뒤에 0을 추가했지만 이게 있으면 getHTML이 잘못될 수 있어서 뺐습니다.
    수정 전)
              ['iframe', {
                src: '//cdn.iframe.ly/api/iframe?app=1&api_key=58xx1axxbxxxcca68fxxxdb&url=' + encodeURIComponent(node.attrs.src), // ここは自分のAPI Keyを設定する
                frameborder: "0",
                allow: "autoplay; encrypted-media",
              }, 0]
    
    수정 후)
              ['iframe', {
                src: '//cdn.iframe.ly/api/iframe?app=1&api_key=58xx1axxbxxxcca68fxxxdb&url=' + encodeURIComponent(node.attrs.src), // ここは自分のAPI Keyを設定する
                frameborder: "0",
                allow: "autoplay; encrypted-media",
              }]
    

    편집기 구성 요소에서command를 통해 URL을 전달하여 노드를 표시합니다


    url의 입력 폼 등 생략,editor.command에서 embed를 호출하면 node를 삽입할 수 있습니다.
    <template>
      <div class="editor">
        <editor-content class="editor__content" :editor="editor" />
      </div>
    </template>
    
    <script>
    import { Editor, EditorContent } from 'tiptap'
    import {
      HardBreak,
      Heading,
      Bold,
      Italic,
      History,
      TrailingNode,
    } from 'tiptap-extensions'
    import Embed from './Embed.js'
    
    export default {
      components: {
        EditorContent,
      },
      data() {
        return {
          editor: new Editor({
            extensions: [
              new HardBreak(),
              new Heading({ levels: [1, 2, 3] }),
              new Bold(),
              new Italic(),
              new History(),
              new TrailingNode(),
              // ここで指定する
              new Embed(),
            ],
            content: "",
          }),
        }
      },
      beforeDestroy() {
        this.editor.destroy()
      },
      methods: {
        embed() {
          this.editor.commands.embed({ src: 'https://news.yahoo.co.jp/pickup/6348622' });
        },
      }
    }
    </script>
    
    <style lang="scss">
    ...省略
    </style>
    
    내장형 이미지

    좋은 웹페이지 즐겨찾기