<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## 概述 Yjs 是一個用于構建實時協作應用的高效、基于 JSON 的共享編輯框架。它允許多個用戶在多個設備上同時編輯同一個文檔,具有強大的同步功能。Yjs 的核心功能包括**分布式同步**、**沖突處理**、**離線編輯**、以及**性能優化**,使其成為現代協作應用程序開發的熱門選擇。 ### 主要特點: 1. **沖突自由復制數據類型 (CRDT)**:Yjs 使用 CRDT 數據結構,確保在多個用戶編輯同一數據時,無需中央服務器管理,系統可以自動解決沖突。 2. **離線支持**:用戶可以在離線狀態下編輯數據,Yjs 會在用戶重新連接時自動同步修改。 3. **高效同步**:Yjs 的架構設計使其可以在傳輸非常少的數據的情況下,確保文檔的完整同步,適合低帶寬和高延遲的環境。 4. **可擴展性**:Yjs 可以與各種不同的傳輸層(如 WebSocket、WebRTC)和數據庫(如 IndexedDB、Redis)結合,適用于不同的使用場景。 5. **集成與插件支持**:Yjs 通過插件支持與多種流行的編輯器(如 ProseMirror、CodeMirror 和 Quill)集成,用于處理富文本編輯、代碼協作等需求。 ### 適用場景: * **實時文檔編輯**:類似于 Google Docs 的多人實時編輯應用。 * **協作設計工具**:允許多個用戶同時編輯圖形或 UI 的工具。 * **多人在線筆記**:像 Notion、Evernote 這樣的工具,可以實現跨設備的內容同步。 ## 語法 ### Y.doc 代表一個文檔對象,存儲共享數據并支持實時協作。它是基于 CRDT(沖突自由的復制數據類型)實現的,允許多個客戶端在沒有中央服務器的情況下進行并發操作,并且自動解決數據沖突 **主要功能:** 1. **管理文檔的狀態**:`Y.Doc` 包含所有實時共享的數據結構,如數組、映射、文本等。開發者可以通過它創建和操作共享的數據。 2. **同步功能**:`Y.Doc` 支持離線和在線的協作,當用戶重新連接網絡時,`Y.Doc` 會自動將本地更改與其他用戶同步。 3. **模塊化與擴展**:它可以通過多種通信協議(WebSocket、WebRTC 等)進行同步,并與數據庫如 IndexedDB、Redis 結合存儲和同步狀態。 示例 <details> <summary> Y.doc 示例 </summary> ``` import * as Y from 'yjs' const doc1 = new Y.Doc(); const doc2 = new Y.Doc(); doc1.on('update', (update) => { console.log('doc1 update', ) Y.applyUpdate(doc2, update); }); doc2.on('update', (update) => { console.log('doc2 update', ) Y.applyUpdate(doc1, update); }); doc1.getArray('myarray').insert(0, ['Hello doc2, you got this?']); const res = doc2.getArray('myarray').get(0); console.log(res.toString()) // output // doc1 update // doc2 update // Hello doc2, you got this? ``` </details> ### Shared Types 核心數據類型 * [Y.Map](https://docs.yjs.dev/api/shared-types/y.map) * [Y.Array](https://docs.yjs.dev/api/shared-types/y.array) * [Y.Text](https://docs.yjs.dev/api/shared-types/y.text) * [Y.XmlFragment](https://docs.yjs.dev/api/shared-types/y.xmlfragment) * [Y.XmlElement](https://docs.yjs.dev/api/shared-types/y.xmlelement) * [Y.XmlText](https://docs.yjs.dev/api/shared-types/y.xmltext) #### Y.Text <details> <summary>Y.Text 示例</summary> ``` import * as Y from 'yjs' // 創建一個新的 Yjs 文檔 const ydoc = new Y.Doc() // 從文檔中獲取一個 Y.Text 實例 const ytext = ydoc.getText('my-shared-text') // 監聽文本變化 ytext.observe(event => { console.log('文本變化:', event.changes.delta) }) // 向文本中插入內容 ytext.insert(0, 'Hello, ') // 在特定位置插入內容 ytext.insert(7, 'Yjs ') // 刪除內容 ytext.delete(0, 5) // 替換內容 ytext.delete(0, 2) ytext.insert(0, 'Greetings') // 獲取當前文本內容 console.log('當前文本:', ytext.toString()) // 獲取文本長度 console.log('文本長度:', ytext.length) // 在文本的末尾追加內容 ytext.insert(ytext.length, '!') // 使用 insert 方法一次插入多個字符 ytext.insert(ytext.length, ' How are you?') console.log('當前文本:', ytext.toString()) // output // 文本變化: [ { insert: 'Hello, ' } ] // 文本變化: [ { retain: 7 }, { insert: 'Yjs ' } ] // 文本變化: [ { delete: 5 } ] // 文本變化: [ { delete: 2 } ] // 文本變化: [ { insert: 'Greetings' } ] // 當前文本: GreetingsYjs // 文本長度: 13 // 文本變化: [ { retain: 13 }, { insert: '!' } ] // 文本變化: [ { retain: 14 }, { insert: ' How are you?' } ] // 當前文本: GreetingsYjs ! How are you? ``` </details> ### Y.XmlElement 使用用在 html 中 <details> <summary> Y.XmlElement 示例</summary> ``` import * as Y from 'yjs' const ydoc = new Y.Doc() const xml = ydoc.get("prop-name", Y.XmlElement) const paragraph = new Y.XmlElement('p') paragraph.setAttribute('class', 'important') paragraph.insert(0, [new Y.XmlText('Hello, world!')]) xml.insert(0, [paragraph]) console.log(paragraph.toString()) console.log(xml.toString()) // output // <p class="important">Hello, world!</p> // <undefined><p class="important">Hello, world!</p></undefined> ``` </details> ### Y.UndoManager 撤回 <details> <summary>撤回示例</summary> ``` import * as Y from 'yjs' const ydoc = new Y.Doc() const ytext = ydoc.getText('text') const undoManager = new Y.UndoManager(ytext) ytext.insert(0, 'abc') undoManager.undo() console.log(ytext.toString()) // => '' undoManager.redo() console.log(ytext.toString()) // => 'abc' ``` </details> ### Delta Format 可通過 Delta 把數據通過到另一個 doc 中 <details> <summary>ytext.applyDelta 同步到另一個 Y.doc</summary> ``` import * as Y from 'yjs' const ydoc = new Y.Doc() const ytext = ydoc.getText('demo') ytext.insert(0, 'abc') ytext.insert(1, '123', { bold: true ,class:'desc'}) const delta = ytext.toDelta() // 通過 delta 轉到 doc2 中 const doc2 = new Y.Doc() const ytext2 = doc2.getText('demo') ytext2.applyDelta(delta) console.log(ytext2.toDelta()) // 輸出 // [ // { insert: 'a' }, // { insert: '123', attributes: { bold: true, class: 'desc' } }, // { insert: 'bc' } // ] ``` </details> ### Subdocuments 可進行 doc 的嵌套 ``` import * as Y from 'yjs' // Client One const rootDoc = new Y.Doc() const folder = rootDoc.getMap() const subDoc = new Y.Doc() subDoc.getText().insert(0, 'some initial content') folder.set('my-document.txt', subDoc) // Client Two const subDoc2 = rootDoc.getMap().get('my-document.txt') const subDocText2 = subDoc2.getText() console.log(subDocText2.toString()) // => "" - content is empty // Data needs to be loaded first.. subDoc2.load() // Then the providers will fetch data from the database / network // and eventually fill the content subDoc2.on('synced', () => { console.log(subDocText2.toString()) // => "some initial content" }) // It is hard to determine when data was actually synced. // The synced event is still helpful to show the user that this user synced // with other users. // It is safer to observe the data types and don't listen // to an explicit sync event. subDocText2.observe((data) => { console.log('data changed..', data) }) ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看