प्रत्यक्ष एकीकरण
grapesjs आयात करें, grapesjs.init() को onMounted() में कॉल करें, editor.destroy() को onUnmounted() में कॉल करें। कोई अतिरिक्त निर्भरता नहीं, आपके और संपादक के बीच कुछ भी नहीं API।
विज़ुअल पेज बिल्डरों, CMS संपादकों, लैंडिंग पेज बिल्डरों, ईमेल संपादकों और व्हाइट-लेबल संपादन अनुभवों का निर्माण करने के लिए ओपन-सोर्स GrapesJS विज़ुअल एडिटर को Vue 3 और Nuxt एप्लिकेशन में एकीकृत करें।
विभाजन किसी भी कोड से पहले नामकरण के लायक है। आपका Vue एप्लिकेशन रूटिंग, उपयोगकर्ताओं, अनुमतियों और डेटा का मालिक है। GrapesJS कैनवास और उसके अंदर हेरफेर करने वाली हर चीज का मालिक है। दोनों एक DOM नोड और एक सेव कॉल पर मिलते हैं।
उस श्रृंखला में कुछ भी करने के लिए यह जानने के लिए Vue की आवश्यकता नहीं है कि संपादक कैसे काम करता है, और यह जानने के लिए GrapesJS की आवश्यकता नहीं है कि यह Vue ऐप के अंदर है। इसलिए एकीकरण छोटा है।
हाँ। GrapesJS फ्रेमवर्क-अज्ञेयवादी है और इसे सीधे Vue 3 अनुप्रयोगों में एकीकृत किया जा सकता है। आप संपादक को Vue जीवनचक्र हुक के साथ प्रारंभ कर सकते हैं, संपादक इंस्टेंस को कंपोजेबल या घटक में रख सकते हैं, GrapesJS ईवेंट को अपने Vue एप्लिकेशन से कनेक्ट कर सकते हैं, और अपने स्वयं के बैकएंड के माध्यम से प्रोजेक्ट डेटा को बनाए रख सकते हैं।
grapesjs आयात करें, grapesjs.init() को onMounted() में कॉल करें, editor.destroy() को onUnmounted() में कॉल करें। कोई अतिरिक्त निर्भरता नहीं, आपके और संपादक के बीच कुछ भी नहीं API।
उस जीवनचक्र को अपने स्वयं के कंपोजेबल - या एक सामुदायिक पैकेज में लपेटें - ताकि घटकों को अनिवार्य के बजाय Vue-आकार API मिले। एक से अधिक स्क्रीन एक संपादक को माउंट करने के बाद उपयोगी।
GrapesJS React के लिए एक आधिकारिक फ्रेमवर्क रैपर, @grapesjs/react प्रकाशित करता है। Vue परियोजना से कोई समतुल्य GrapesJS पैकेज नहीं है, इसलिए कोई भी Vue रैपर जो आपको npm पर मिलता है, वह एक सामुदायिक परियोजना है। इसे अपनाने से पहले इसकी Vue और GrapesJS सहकर्मी श्रेणियों की जाँच करें।
Vue 3 एक एप्लिकेशन फ्रेमवर्क है। GrapesJS एक विज़ुअल एडिटिंग इंजन है। वे विभिन्न समस्याओं को हल करते हैं, और एकीकरण ठीक से साफ है क्योंकि वे ओवरलैप नहीं होते हैं।
इनमें से पांच आपके हैं। बाकी पहले से मौजूद हैं, और शेष दो निर्माण के बजाय कॉन्फ़िगरेशन हैं।
एक निर्भरता। GrapesJS अपनी TypeScript परिभाषाएँ भेजता है, इसलिए जोड़ने के लिए कोई अलग @types पैकेज नहीं है।
npm install grapesjsइसके बिना संपादक अनस्टाइल है। Vite या Nuxt प्रोजेक्ट में आप इसे संपादक बनाने वाले घटक या कंपोज़ेबल से आयात कर सकते हैं; वैश्विक स्टाइलशीट वाले ऐप में, इसके बजाय इसे एक बार वहां आयात करें।
इसे एक घटक में कॉपी करें और यह चलता है। इस खंड के बाद सब कुछ इसके अतिरिक्त है, न कि इसका पुनर्लेखन।
<template>
<div ref="editorContainer" class="editor-shell"></div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, shallowRef, ref } from 'vue';
import grapesjs, { type Editor } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
// A template ref: the name matches the ref="" attribute above.
const editorContainer = ref<HTMLDivElement | null>(null);
// shallowRef, not ref — see "Performance" further down the page.
const editor = shallowRef<Editor | null>(null);
onMounted(() => {
if (!editorContainer.value) return;
editor.value = grapesjs.init({
container: editorContainer.value,
height: '100%',
fromElement: false,
storageManager: false,
});
});
onUnmounted(() => {
editor.value?.destroy();
editor.value = null;
});
</script>
<style scoped>
.editor-shell {
height: 100vh;
}
</style>टेम्पलेट रेफरी नाम ref="" विशेषता से मेल खाता है - इस तरह Vue उन्हें <script setup> में बांधता है।
संपादक shallowRef में रहता है, रेफरी नहीं Vue अन्यथा पूरे संपादक ऑब्जेक्ट ग्राफ़ को प्रतिक्रियाशील बनाता है।
fromElement गलत है, इसलिए GrapesJS कंटेनर के अंदर जो भी मार्कअप था, उसके बजाय आपके द्वारा पास किए गए घटकों से शुरू होता है।
संपूर्ण एकीकरण एक जीवनचक्र मानचित्रण है। Vue आपको बताता है कि DOM नोड कब मौजूद है और यह कब गायब होने वाला है; GrapesJS को बिल्कुल उन्हीं दो क्षणों की आवश्यकता है।
ऊपर से नीचे पढ़ें, यह दो पुस्तकालयों के बीच का पूरा अनुबंध है।
सर्वर पर न तो onMounted और न ही onUnmounted चलता है, यही वजह है कि एक सादे Vue एसपीए को अतिरिक्त कुछ भी नहीं चाहिए। एक सर्वर-रेंडर किए गए ऐप को एक और गार्ड की आवश्यकता होती है - Nuxt अनुभाग इसे कवर करता है।
एक बार जब दूसरी स्क्रीन को एक संपादक की आवश्यकता होती है, तो जीवनचक्र को एक कंपोज़ेबल में ले जाएं। घटक तब कहता है कि वह क्या चाहता है, न कि संपादक को कैसे वायर्ड किया जाता है।
// composables/useGrapesJS.ts
import { onMounted, onUnmounted, shallowRef, type Ref } from 'vue';
import grapesjs, { type Editor, type EditorConfig } from 'grapesjs';
import 'grapesjs/dist/css/grapes.min.css';
type EditorOptions = Omit<EditorConfig, 'container'>;
export function useGrapesJS(
container: Ref<HTMLElement | null>,
options: EditorOptions = {},
) {
const editor = shallowRef<Editor | null>(null);
const init = (): Editor | undefined => {
if (editor.value || !container.value) return;
editor.value = grapesjs.init({
container: container.value,
height: '100%',
fromElement: false,
storageManager: false,
...options,
});
return editor.value;
};
const destroy = (): void => {
editor.value?.destroy();
editor.value = null;
};
onMounted(init);
onUnmounted(destroy);
return { editor, init, destroy };
}<template>
<div ref="editorContainer" class="editor-shell"></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useGrapesJS } from '~/composables/useGrapesJS';
const editorContainer = ref<HTMLElement | null>(null);
const { editor } = useGrapesJS(editorContainer, {
blockManager: {
blocks: [
{
id: 'hero',
label: 'Hero',
category: 'Sections',
content: '<section>…</section>',
},
],
},
});
</script>इसे आवश्यकता से अधिक बढ़ाने का विरोध करें। एक कंपोजेबल जो प्रत्येक GrapesJS मॉड्यूल को एक प्रतिक्रियाशील मुखौटे में लपेटता है, सीखने के लिए दूसरा API है और सिंक में रखने के लिए दूसरी चीज़ है।
GrapesJS संपादक स्थिति का प्रबंधन करता है। Vue आवेदन स्थिति का प्रबंधन करता है। घटनाएँ सीम हैं: उन कुछ की सदस्यता लें जो आपका UI वास्तव में प्रतिबिंबित करता है, और उन्हें सामान्य रेफ में लिखें।
import { onMounted, ref, shallowRef } from 'vue';
import type { Editor, Component } from 'grapesjs';
const isReady = ref(false);
const isDirty = ref(false);
const saveState = ref<'idle' | 'saving' | 'saved' | 'error'>('idle');
const selectedName = ref<string | null>(null);
function bindEditorEvents(editor: Editor): void {
editor.on('load', () => {
isReady.value = true;
});
editor.on('component:selected', (component: Component) => {
selectedName.value = component?.getName?.() ?? null;
});
editor.on('component:update', () => {
isDirty.value = true;
});
editor.on('storage:start:store', () => {
saveState.value = 'saving';
});
editor.on('storage:end:store', () => {
saveState.value = 'saved';
isDirty.value = false;
});
editor.on('storage:error', () => {
saveState.value = 'error';
});
}| आयोजन | आपका UI इसके साथ क्या करता है |
|---|---|
| load | प्रोजेक्ट कैनवास पर होने के बाद लोडिंग स्थिति छुपाएं |
| component:selected | दिखाएँ कि आपके स्वयं के उपकरण पट्टी में कौन सा तत्व चयनित है |
| component:update | दस्तावेज़ को गंदा चिह्नित करें, सहेजें बटन सक्षम करें |
| storage:start:store | एक बचत संकेतक दिखाएं |
| storage:end:store | सहेजा गया दिखाएं, गंदा झंडा साफ़ करें |
| storage:error | किसी विफलता को उस पर उपयोगकर्ता द्वारा कार्य किया जा सकता है |
आप जो प्रदर्शित करते हैं उसे मिरर करें, न कि संपादक के पास क्या है। घटक ट्री को Vue स्टोर में कॉपी करने से आपको सत्य के दो स्रोत और एक सिंक्रनाइज़ेशन बग मिलता है।
GrapesJS ब्राउज़र DOM APIs पर निर्भर करता है, इसलिए संपादक आरंभीकरण केवल ब्राउज़र संदर्भ में होना चाहिए। Nuxt में इसका मतलब है कि संपादक को सर्वर रेंडर से बाहर रखना - बाकी सब कुछ वही एकीकरण है जो आपके पास पहले से है।
<!-- pages/editor.vue -->
<template>
<ClientOnly>
<VisualEditor />
<template #fallback>
<p class="editor-placeholder">Loading the editor…</p>
</template>
</ClientOnly>
</template><!-- components/VisualEditor.client.vue -->
<template>
<div ref="editorContainer" class="editor-shell"></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useGrapesJS } from '~/composables/useGrapesJS';
// Reached only in the browser: the .client suffix keeps this
// component out of the server render, and onMounted never runs
// on the server anyway.
const editorContainer = ref<HTMLElement | null>(null);
const { editor } = useGrapesJS(editorContainer);
</script>संपादक को लपेटें जहां इसका उपयोग किया जाता है। फ़ॉलबैक slot सर्वर को प्रस्तुत करने के लिए कुछ देता है, इसलिए जलयोजन से पहले कोई खाली फ्रेम नहीं है।
Nuxt का अपना नामकरण सम्मेलन: एक घटक जिसका फ़ाइल नाम .client में समाप्त होता है, केवल ब्राउज़र में प्रस्तुत किया जाता है। उपयोगी जब संपादक का उपयोग कई स्थानों पर किया जाता है।
दोनों मान्य हैं, और वे गठबंधन करते हैं। GrapesJS द्वारा न तो आवश्यक है - GrapesJS की आवश्यकता केवल यह है कि init() वहां चलता है जहां दस्तावेज़ मौजूद है।
SSR एप्लिकेशन शेल को प्रस्तुत करता है। GrapesJS ब्राउज़र में चलता है। उस सीमा का नामकरण ही जलयोजन बग के स्रोत के बजाय Nuxt एकीकरण को पूर्वानुमानित बनाता है।
संपादक स्क्रीन एक ऐसा पृष्ठ नहीं है जिसे आप SEO के लिए सर्वर-रेंडर करते हैं - यह एक प्रमाणित उपकरण है। इसके द्वारा उत्पादित पृष्ठ वही हैं जिन्हें आप प्रस्तुत और अनुक्रमित करते हैं, और वे सादे HTML और CSS हैं।
एक पूर्ण Vue पेज बिल्डर बनाएं →नहीं। प्रत्यक्ष एकीकरण GrapesJS का उपयोग करने का एक पूर्ण, समर्थित तरीका है, और इस पृष्ठ पर दिए गए उदाहरण यही करते हैं। रैपर एक सुविधा है, आवश्यकता नहीं।
| दृष्टिकोण | के लिए सबसे अच्छा | समंजन |
|---|---|---|
| प्रत्यक्ष GrapesJS | अधिकतम नियंत्रण | आप जीवनचक्र स्वयं लिखते हैं - लगभग पंद्रह पंक्तियाँ। |
| Vue रैपर/एकीकरण | एक अधिक Vue-उन्मुख API | आपके और संपादक के बीच निर्भरता API, किसी और के रिलीज़ शेड्यूल पर। |
| कस्टम कंपोजेबल | पुनः प्रयोज्य अनुप्रयोग एकीकरण | आपका बनाए रखना है - लेकिन यह ऊपर दिखाई गई फ़ाइल है, और यह बासी नहीं होती है। |
कुछ भी अपनाने से पहले जांच करने लायक है, क्योंकि इस प्रश्न के खोज परिणाम उनके द्वारा वर्णित पैकेजों से पुराने हैं।
npm रजिस्ट्री के विरुद्ध जाँच की गई 2026-09-02. यदि आपको एक नया Vue पैकेज मिलता है, तो पहले इसका peerDependencies पढ़ें: वह एकल फ़ील्ड आपको बताता है कि क्या यह Vue 3 और वर्तमान GrapesJS को लक्षित करता है।
आज Vue 3 के लिए, ऊपर दिया गया कंपोजेबल रैपर है। यह बीस विषम पंक्तियाँ हैं, यह सीधे GrapesJS API का उपयोग करता है, और यह उस रिलीज़ के पीछे नहीं रह सकता जिस पर आप निर्भर हैं।
संपादक को माउंट करना पहली दोपहर है। एक पेज बिल्डर जिस पर आपके उपयोगकर्ता भरोसा करते हैं, वह बाकी काम है, और यह ज्यादातर मॉड्यूल GrapesJS का कॉन्फ़िगरेशन है जो पहले से ही उजागर होता है।
Canvas
संपादन योग्य सतह और उसके डिवाइस की चौड़ाई।
Components
आपके उपयोगकर्ता किस प्रकार रख सकते हैं, और उनके लक्षण।
Blocks
जिस पैलेट से वे खींचते हैं।
Style Manager
कौन से CSS गुण उजागर होते हैं, और किसके लिए।
Asset Manager
छवियाँ और मीडिया, आपके संग्रहण से।
Storage Manager
जहां प्रोजेक्ट डेटा लोड और सहेजा जाता है।
Commands
नामित क्रियाएं, आपके स्वयं के UI के लिए बाध्यकारी।
Device Manager
संपादन और आउटपुट के लिए उत्तरदायी ब्रेकपॉइंट।
Plugins
ऊपर सब कुछ, पैक और पुनः प्रयोज्य।
एक ही संपादक कोर, अलग तरह से कॉन्फ़िगर किया गया है। इनमें से प्रत्येक ब्लॉक का एक अलग सेट, एक अलग भंडारण लक्ष्य और एक अलग प्रकाशन चरण है।
अपने Vue एप्लिकेशन के अंदर विज़ुअल पेज संपादन बनाएं।
अधिक पढ़ेंसामग्री टीमों को उन पृष्ठों पर एक दृश्य संपादन इंटरफ़ेस दें जो आपकी Nuxt साइट पहले से ही प्रस्तुत करती है।
अधिक पढ़ेंपुनः प्रयोज्य मार्केटिंग लेआउट बनाएं जिन्हें आपकी विकास टीम बिना किसी तैनाती के इकट्ठा कर सके।
अधिक पढ़ेंब्राउज़रों के बजाय मेल क्लाइंट के लिए आउटपुट के आकार के साथ ईमेल टेम्पलेट्स को नेत्रहीन रूप से बनाएं।
अधिक पढ़ेंअपने उत्पाद में एक ब्रांडेड संपादक एम्बेड करें, अपने स्वयं के UI और अनुमतियों के तहत।
अधिक पढ़ेंउपयोगकर्ताओं को HTML और CSS पर दृश्य नियंत्रण दें, और ठीक वैसा ही वापस कर दें।
अधिक पढ़ेंतीन चीजें जो भ्रमित करने में आसान हैं, और भ्रमित करने के लिए महंगी हैं। पहले दिन यह अधिकार प्राप्त करना एक दस्तावेज़ को एक साल बाद फिर से संपादित करने योग्य बनाता है।
GrapesJS परियोजना की संपादन योग्य स्थिति - पृष्ठ, घटक, शैलियाँ, संपत्ति। इसे editor.getProjectData() के साथ पढ़ें, इसे editor.loadProjectData() के साथ पुनर्स्थापित करें। यही बनी रहने की बात है।
प्रदान किया गया मार्कअप, editor.getHtml() से। जब भी आप प्रकाशित करें तो इसे पुनः उत्पन्न करें। यह आउटपुट है, स्रोत नहीं।
संपादक ने editor.getCss() से जो शैलियाँ तैयार कीं। एक ही नियम: उत्पन्न, सत्य के स्रोत के रूप में संग्रहीत नहीं।
संपादन योग्य प्रोजेक्ट डेटा संग्रहीत करें। जब आपको प्रस्तुत या प्रकाशित करने की आवश्यकता हो तो HTML और CSS उत्पन्न करें।
केवल प्रदान किए गए HTML को सहेजना वह गलती है जिसे बाद में पूर्ववत नहीं किया जा सकता है। आप प्रोजेक्ट डेटा से हमेशा HTML को पुनः उत्पन्न कर सकते हैं; आप HTML से प्रोजेक्ट डेटा को मज़बूती से पुनर्प्राप्त नहीं कर सकते।
// Editable state — store this, it is what the editor reloads.
const projectData = editor.getProjectData();
// Rendered output — regenerate this whenever you publish.
const html = editor.getHtml();
const css = editor.getCss();
await fetch(`/api/projects/${projectId}/publish`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ projectData, html, css }),
});
// Sanitize `html` on the server before it is served to anyone.GrapesJS को परवाह नहीं है कि आपका बैकएंड क्या है। एक स्टोरेज एडाप्टर दो एसिंक फ़ंक्शन हैं - एक जो प्रोजेक्ट डेटा लौटाता है, एक जो इसे स्वीकार करता है - इसलिए संपादक आपके पास पहले से मौजूद API से बात करता है।
import grapesjs, { type ProjectData } from 'grapesjs';
// Wherever your app keeps it — a route param, a prop, a store.
const projectId = props.projectId;
const editor = grapesjs.init({
container: editorContainer.value!,
fromElement: false,
storageManager: {
type: 'app-api',
autosave: true,
stepsBeforeSave: 10,
},
// Registered as a plugin so the adapter exists before
// GrapesJS performs its first load.
plugins: [
(ed) => {
ed.Storage.add('app-api', {
async load(): Promise<ProjectData> {
const res = await fetch(`/api/projects/${projectId}`);
if (!res.ok) {
throw new Error(`Load failed: ${res.status}`);
}
return await res.json();
},
async store(data: ProjectData) {
const res = await fetch(`/api/projects/${projectId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ projectData: data }),
});
if (!res.ok) {
throw new Error(`Save failed: ${res.status}`);
}
},
});
},
],
});प्लगइन्स सरणी के माध्यम से एडॉप्टर को पंजीकृत करना मायने रखता है: यह गारंटी देता है कि भंडारण GrapesJS द्वारा अपना पहला लोड करने से पहले मौजूद है।
परिसंपत्ति प्रबंधक एक समापन बिंदु पर UI है। इसे अपने और हर मौजूदा नियम पर इंगित करें - प्रमाणीकरण, सत्यापन, कोटा, CDN - लागू होता रहता है।
// Fetched from your own API before the editor is created.
const assets = await fetch('/api/assets').then((res) => res.json());
const editor = grapesjs.init({
container: editorContainer.value!,
assetManager: {
assets,
// Uploads go to your endpoint, with your auth and
// your validation.
upload: '/api/assets',
uploadName: 'files',
multiUpload: true,
autoAdd: true,
headers: { Authorization: `Bearer ${token.value}` },
credentials: 'same-origin',
// Reject what the backend would reject anyway,
// before the round trip.
beforeUpload: (files: File[]) => {
const limit = 5 * 1024 * 1024;
const tooBig = files.some((f) => f.size > limit);
if (tooBig) {
toast.error('Images must be under 5 MB');
return false;
}
},
},
});एक कस्टम घटक प्रकार यह है कि संपादक आपके उत्पाद को कैसे सीखता है। इसे अपना स्वयं का सेटिंग पैनल, अपने स्वयं के ड्रॉप नियम और पैलेट में अपना स्वयं का ब्लॉक मिलता है।
import type { Editor } from 'grapesjs';
export function pricingCardPlugin(editor: Editor): void {
editor.Components.addType('pricing-card', {
isComponent: (el) => el.dataset?.gjsType === 'pricing-card',
model: {
defaults: {
tagName: 'section',
attributes: { 'data-gjs-type': 'pricing-card' },
// Traits become the settings panel for this component.
traits: [
{ type: 'text', name: 'plan', label: 'Plan name' },
{ type: 'text', name: 'price', label: 'Price' },
{ type: 'checkbox', name: 'featured', label: 'Featured' },
],
components: `
<h3 data-gjs-type="text">Starter</h3>
<p data-gjs-type="text">$0 / month</p>
<a href="#">Choose plan</a>
`,
},
},
});
editor.Blocks.add('pricing-card', {
label: 'Pricing card',
category: 'Marketing',
content: { type: 'pricing-card' },
});
}
// Pass it to the editor like any other plugin:
// grapesjs.init({ container, plugins: [pricingCardPlugin] })कस्टम घटक भी हैं कि आप संपादक को कैसे विवश करते हैं। किसी प्रकार पर ड्रॉपेबल या ड्रैग करने योग्य सेट करना वह है जो उपयोगकर्ता को नेविगेशन बार के अंदर मूल्य निर्धारण कार्ड छोड़ने से रोकता है, और लक्षण वे हैं जो उन्हें कच्चे CSS नियंत्रण के बजाय एक लेबल फ़ील्ड देते हैं।
ये GrapesJS घटक प्रकार हैं, न कि Vue घटक। कैनवास DOM प्रस्तुत करता है; आपके Vue घटक आपके अनुप्रयोग को इसके चारों ओर प्रस्तुत करते हैं।
एक प्लगइन एक फ़ंक्शन है जो संपादक प्राप्त करता है - वही फ़ंक्शन हस्ताक्षर चाहे वह npm से आया हो, GJS.Market से, या आपके अपने भंडार से। उनमें से किसी को भी इस बात की परवाह नहीं है कि होस्ट एप्लिकेशन Vue है।
import grapesjs from 'grapesjs';
import basicBlocks from 'grapesjs-blocks-basic';
import { pricingCardPlugin } from '~/editor/pricing-card';
const editor = grapesjs.init({
container: editorContainer.value!,
plugins: [
// Options go through a wrapper function: `pluginsOpts`
// is keyed by string, so it only reaches plugins that
// were passed to `plugins` by name.
(ed) => basicBlocks(ed, { flexGrid: true }),
pricingCardPlugin,
],
});पैलेट, टेक्स्ट एडिटिंग और फॉर्म कंट्रोल जो कैनवास को पहले दिन उपयोगी बनाते हैं।
श्रेणी ब्राउज़ करेंएक प्रारंभिक पैलेट ताकि पहली बार जब कोई उपयोगकर्ता इसे खोलता है तो कैनवास खाली न हो।
Tailwind-आकार के अनुभाग, उन टीमों के लिए जिनका आउटपुट पहले से ही Tailwind का उपयोग करता है।
अंतर्निहित की तुलना में एक समृद्ध इनलाइन टेक्स्ट टूलबार।
फ़ील्ड को संपादन योग्य घटकों के रूप में फ़ॉर्म करें, उनकी विशेषताओं के लिए विशेषता पैनल के साथ।
दृढ़ता, autosave और क्रैश रिकवरी - वह हिस्सा जो हर प्रोटोटाइप स्थगित कर देता है।
श्रेणी ब्राउज़ करेंएकाधिक परियोजनाएं, सूचीबद्ध और स्विच करने योग्य, इसके लिए UI लिखे बिना।
स्थानीय दृढ़ता - ड्राफ्ट, ऑफ़लाइन काम और एक तेज़ प्रोटोटाइप के लिए उपयोगी।
क्रैश या बंद टैब के बाद सहेजे न गए कार्य को पुनर्प्राप्त करता है।
पहले से ही Directus को उनके बैकएंड के रूप में चलाने वाली टीमों के लिए एक स्टोरेज एडाप्टर।
मीडिया हैंडलिंग और सहेजे गए प्रोजेक्ट और सेव किए गए पेज के बीच का चरण।
श्रेणी ब्राउज़ करेंअपलोड और रूपांतरण Cloudinary के बजाय अपनी स्वयं की पाइपलाइन के बजाय।
Uppy अपलोड UI के रूप में, इसकी पुनः शुरू करने योग्य और बहु-स्रोत हैंडलिंग के साथ।
तैयार पृष्ठ को डाउनलोड करने योग्य संग्रह के रूप में वापस सौंपें।
किसी पृष्ठ के प्रकाशित होने से पहले पहुँच क्षमता और SEO समस्याओं को ध्वजांकित करता है.
यह तर्क नहीं है कि इमारत गलत है - इमारत का क्या मतलब है इसकी एक सूची। प्रत्येक पंक्ति एक सबसिस्टम है जो मौजूद है चाहे आपने इसके लिए योजना बनाई हो या नहीं।
| योग्यता | अपने आप को बनाएं | GrapesJS |
|---|---|---|
| Canvas | निर्माण | शामिल |
| Drag & drop | निर्माण | शामिल |
| Components | निर्माण | शामिल |
| Blocks | निर्माण | शामिल |
| Style Manager | निर्माण | शामिल |
| Asset Manager | निर्माण | एक्स्टेंसिबल |
| Storage Manager | निर्माण | एक्स्टेंसिबल |
| Plugins | एक पारिस्थितिकी तंत्र का निर्माण करें | प्लगइन आर्किटेक्चर |
| Vue integration | मूल निवासी | फ्रेमवर्क-अज्ञेयवादी |
Vue आपको एप्लिकेशन फ्रेमवर्क देता है। GrapesJS आपको विज़ुअल एडिटिंग इंजन देता है।
क्योंकि Vue घटक एप्लिकेशन बिल्डिंग ब्लॉक हैं, और एक विज़ुअल एडिटर को उनके ऊपर कुछ और चाहिए: कैनवास प्रबंधन, ड्रॉप नियमों के साथ एक घटक वृक्ष, चयन और होवर स्थिति, एक शैली परत जो वास्तविक CSS लिखती है, डिवाइस स्विचिंग, पूर्ववत करें और फिर से करें, परिसंपत्ति प्रबंधन, क्रमांकन, नामित आदेश, और पूरी चीज़ के लिए एक विस्तार बिंदु। आप इसे Vue में बना सकते हैं - यह आपके द्वारा निर्धारित परियोजना से बस एक अलग परियोजना है।
Vue + GrapesJS अकेले Vue घटकों से एक अलग प्रस्ताव है।
आपका Nuxt या Vue एप्लिकेशन: शेल, सत्र, और किसे किस प्रोजेक्ट को खोलने की अनुमति है।
संपादक, एक स्क्रीन पर घुड़सवार। यह एक परियोजना प्राप्त करता है और एक परियोजना का उत्सर्जन करता है।
आपके अपने मार्ग। GrapesJS उन्हें आपके द्वारा लिखे गए स्टोरेज और एसेट एडेप्टर के माध्यम से कॉल करता है।
जहां परियोजनाएं, मीडिया, उपयोगकर्ता और संस्करण वास्तव में रहते हैं - इसके ऊपर संपादक द्वारा अपरिवर्तित।
संपादक उस पेड़ में एक पत्ता है, जड़ नहीं। इसके ऊपर सब कुछ कोड है जिसे आपने वैसे भी लिखा होगा।
संपादक को गहराई से प्रतिक्रियाशील न बनाएं
यह वह है जो वास्तव में काटता है। shallowRef, या एक सादा मॉड्यूल-स्कोप्ड चर - संपादक उदाहरण के आसपास कभी भी ref() नहीं। Vue एक बहुत बड़े ऑब्जेक्ट ग्राफ़ पर चलेगा और आंतरिक मंथन पर प्रभाव को फिर से चलाएगा।
जरूरत पड़ने पर ही इनिशियलाइज़ करें
स्क्रीन पर संपादक बनाएं जो संपादित करता है, न कि किसी लेआउट या स्टोर में जो हर मार्ग माउंट करता है।
आलसी-लोड संपादक
GrapesJS एक बड़ा बंडल है। इसे अपने स्वयं के एसिंक चंक में लोड करें ताकि ऐसे मार्ग जो कभी भी संपादित न करें, इसके लिए कभी भुगतान न करें।
अपडेट को वैश्विक स्थिति से बाहर रखें
प्रत्येक component:update को एक स्टोर में धकेलने से प्रत्येक कीस्ट्रोक एक एप्लिकेशन-वाइड रेंडर में बदल जाता है।
बड़े परिसंपत्ति संग्रह को पेजिनेट करें
संपादक में हजारों URL भेजने के बजाय परिसंपत्ति प्रबंधक को पृष्ठांकित समापन बिंदु से सीड करें।
घटक वृक्षों को प्रबंधनीय रखें
बहुत गहरे दस्तावेज़ों को प्रस्तुत करने, क्रमबद्ध करने और अलग करने के लिए अधिक खर्च होता है। संरचना खुद को प्रोत्साहित करती है यदि आपके ब्लॉक करते हैं।
विज़ुअल एडिटर एक ऐसी प्रणाली है जो उपयोगकर्ता-लिखित HTML को स्वीकार करती है। इसे इस तरह से ट्रीट करें।
इस संयोजन के लिए रिपोर्ट किया गया लगभग हर एकीकरण मुद्दा इन सात में से एक है।
लक्षण
कंटेनर शून्य है, या संपादक कुछ भी नहीं में प्रस्तुत करता है।
ठीक करना
onMounted() के अंदर संपादक बनाएं। टेम्पलेट रेफरी में इससे पहले कोई तत्व नहीं है।
लक्षण
याददाश्त बढ़ती है और बासी श्रोता मार्ग छोड़ने के बाद आग लगा देते हैं।
ठीक करना
editor.destroy() को onUnmounted() में कॉल करें और संदर्भ साफ़ करें।
लक्षण
संपादक सुस्त महसूस करता है; Vue devtools स्टाल।
ठीक करना
उदाहरण को shallowRef में, या Vue प्रतिक्रियाशीलता के बाहर पूरी तरह से पकड़ें।
लक्षण
दस्तावेज़ परिभाषित नहीं है, या संपादक मार्ग पर जलयोजन बेमेल है।
ठीक करना
संपादक को केवल-क्लाइंट — <ClientOnly>, एक .client घटक, या दोनों को प्रस्तुत करें।
लक्षण
सत्य के दो स्रोत, और संपादन जो नेविगेशन पर गायब हो जाते हैं।
ठीक करना
GrapesJS को प्रोजेक्ट का मालिक होने दें; केवल कुछ मूल्यों को मिरर करें जो आपके UI प्रदर्शित करता है।
लक्षण
संपादक लोड होता है, लेकिन पैनल स्टाइल रहित और अनुपयोगी हैं।
ठीक करना
grapesjs/dist/css/grapes.min.css आयात करें, या इसे अपनी वैश्विक स्टाइलशीट में शामिल करें।
लक्षण
त्रुटियाँ टाइप करें, या Vue 2 जीवनचक्र हुक पर निर्मित एकीकरण।
ठीक करना
किसी भी आवरण को अपनाने से पहले peerDependencies की जाँच करें। कई लोकप्रिय उदाहरण Vue 3 से पहले के हैं।
Vue 2 पर समान एकीकरण mounted()() और onUnmounted() के बजाय mounted() और beforeDestroy() का उपयोग करता है; GrapesJS पक्ष अपरिवर्तित है। नए कार्य को Vue 3 को लक्षित करना चाहिए - इस पृष्ठ पर सब कुछ इसे मानता है।
आदेश मोटे तौर पर इस पृष्ठ द्वारा पेश किए गए क्रम से मेल खाता है।
हाँ। GrapesJS एक ढांचा-अज्ञेयवादी लाइब्रेरी है जो DOM तत्व में प्रस्तुत होती है, इसलिए यह बिना एडाप्टर के Vue 3 में काम करती है। इसे onMounted() में इनिशियलाइज़ करें और इसे onUnmounted() में नष्ट कर दें।
npm install grapesjs चलाएँ। पैकेज में इसकी अपनी TypeScript परिभाषाएँ शामिल हैं। आपको इसकी स्टाइलशीट को भी लोड करना होगा, या तो grapesjs/dist/css/grapes.min.css आयात करके या इसे अपने वैश्विक CSS में शामिल करके।
कंटेनर तत्व पर एक टेम्पलेट रेफरी बनाएं, फिर grapesjs.init({ container: containerRef.value }) को onMounted() के अंदर कॉल करें। माउंट से पहले तत्व मौजूद नहीं है, इसलिए किसी भी पहले को इनिशियलाइज़ करने से GrapesJS को रेंडर करने के लिए कुछ भी नहीं मिलता है।
हाँ, और यह अनुशंसित तरीका है। onMounted() और onUnmounted() सीधे grapesjs.init() और editor.destroy() पर मैप करें, और संपूर्ण एकीकरण एक ही कंपोजेबल में फिट बैठता है।
हाँ। इस पृष्ठ पर प्रत्येक उदाहरण <script setup lang="ts"> का उपयोग करता है। ref() के साथ घोषित एक टेम्पलेट रेफरी स्वचालित रूप से मिलान ref="" विशेषता से जुड़ता है।
हाँ। एकीकरण सादे Vue 3 के समान है; एकमात्र जोड़ संपादक को सर्वर रेंडर से बाहर रखना है, जिसमें <ClientOnly> या .client घटक है।
हाँ, संपादक के साथ केवल क्लाइंट-प्रदान किया गया है। GrapesJS को ब्राउज़र DOM APIs की आवश्यकता होती है, इसलिए यह सर्वर रेंडर के दौरान नहीं चल सकता है - लेकिन इसके द्वारा उत्पादित पृष्ठ सादे HTML और CSS हैं, और वे बिल्कुल वही हैं जो आप सर्वर-रेंडर और इंडेक्स करते हैं।
नहीं। प्रत्यक्ष एकीकरण एक संपूर्ण दृष्टिकोण है और यहां उदाहरण इसी का उपयोग करते हैं। GrapesJS एक आधिकारिक React रैपर प्रकाशित करता है लेकिन कोई Vue समकक्ष नहीं है, इसलिए Vue पर कोई भी npm रैपर एक सामुदायिक परियोजना है - इसे अपनाने से पहले इसकी Vue और GrapesJS सहकर्मी श्रेणियों की जांच करें।
हाँ। GrapesJS पैकेज में TypeScript परिभाषाएँ हैं, इसलिए Editor प्रकार और कॉन्फ़िगरेशन ऑब्जेक्ट को अतिरिक्त @types निर्भरता के बिना टाइप किया जाता है।
हाँ। editor.Storage.add() के साथ एक स्टोरेज एडाप्टर पंजीकृत करें जो load() और store() को लागू करता है। दोनों सामान्य एसिंक फ़ंक्शन हैं, इसलिए वे आपके पास पहले से मौजूद API को कॉल कर सकते हैं।
हाँ। editor.Components.addType() एक घटक प्रकार को अपने स्वयं के traits और ड्रॉप नियमों के साथ परिभाषित करता है, और editor.Blocks.add() इसे पैलेट में रखता है। इस तरह संपादक आपके उत्पाद की शब्दावली सीखता है।
हाँ। एक GrapesJS प्लगइन एक फ़ंक्शन है जो संपादक इंस्टेंस प्राप्त करता है, इसलिए यह इसे होस्ट करने वाले ढांचे से अप्रभावित रहता है। प्लगइन्स को grapesjs.init() की प्लगइन्स सरणी में पास करें।
हाँ - यह सामान्य मामला है। संपादक को माउंट करना छोटा हिस्सा है; बाकी इसके चारों ओर ब्लॉक, भंडारण, संपत्ति और अनुमतियों को कॉन्फ़िगर कर रहा है।
विज़ुअल एडिटिंग इंजन को अपने Vue या Nuxt एप्लिकेशन में एकीकृत करें, अपने डेटा और आउटपुट पर नियंत्रण रखें, और संपादक को उन प्लगइन्स के साथ विस्तारित करें जिनकी आपके उत्पाद की आवश्यकता है।
Vue के साथ अपना एप्लिकेशन बनाएं 3. GrapesJS के साथ विज़ुअल एडिटिंग जोड़ें।