Panels and Buttons section of getting started not working with Vue.js
Question
I am working to get grapejs to work with Vue.js and am having no luck, I am following the getting started however I am unable to get it to work properly. So far I have added it to the mounted() section and have gotten some buttons with blocks to show up and add in however I have had no luck getting the Panels and Buttons section to work.
Issue TLDR: Using Vue.js I can't get the panels and buttons section from getting started to show.
Below I have included my entire App.vue file which is the main one I am trying to add it into at this time - proof of concept will move to a proper location later.
<template>
<div class="base">
<div class="panel__top">
<div class="panel__basic-actions"></div>
</div>
<div id="gjs">
<h1>Hello World Component!</h1>
</div>
<div id="blocks"></div>
<link rel="stylesheet" href="//unpkg.com/grapesjs/dist/css/grapes.min.css">
</div>
</template>
<script>
// import VueGrapesjs from 'vue-grapesjs'
import grapesjs from 'grapesjs'
export default {
name: 'app',
data () {
return {
}
},
mounted(){
grapesjs.init({
// Indicate where to init the editor. You can also pass an HTMLElement
container: '#gjs',
// Get the content for the canvas directly from the element
// As an alternative we could use: `components: '<h1>Hello World Component!</h1>'`,
fromElement: true,
// Size of the editor
height: '1000px',
width: 'auto',
// Disable the storage manager for the moment
storageManager: false,
// Avoid any default panel
panels: { defaults: [] },
// Allows creation of "blocks"
blockManager: {
appendTo: '#blocks',
blocks: [
{
id: 'section', // id is mandatory
label: '<b>Section</b>', // You can use HTML/SVG inside labels
attributes: { class:'gjs-block-section' },
content: `<section>
<h1>This is a simple title</h1>
<div>This is just a Lorem text: Lorem ipsum dolor sit amet</div>
</section>`,
}, {
id: 'text',
label: 'Text',
content: '<div data-gjs-type="text">Insert your text here</div>',
}, {
id: 'image',
label: 'Image',
// Select the component once it's dropped
select: true,
// You can pass components as a JSON instead of a simple HTML string,
// in this case we also use a defined component type `image`
content: { type: 'image' },
// This triggers `active` event on dropped components and the `image`
// reacts by opening the AssetManager
activate: true,
}
]
},
});
grapesjs.Panels.addPanel({
id: 'panel-top',
el: '.panel__top',
});
grapesjs.Panels.addPanel({
id: 'basic-actions',
el: '.panel__basic-actions',
buttons: [
{
id: 'visibility',
active: true, // active by default
className: 'btn-toggle-borders',
label: '<u>B</u>',
command: 'sw-visibility', // Built-in command
}, {
id: 'export',
className: 'btn-open-export',
label: 'Exp',
command: 'export-template',
context: 'export-template', // For grouping context of buttons from the same panel
}, {
id: 'show-json',
className: 'btn-show-json',
label: 'JSON',
context: 'show-json',
command(editor) {
editor.Modal.setTitle('Components JSON')
.setContent(`<textarea style="width:100%; height: 250px;">
${JSON.stringify(editor.getComponents())}
</textarea>`)
.open();
},
}
],
});
}
}
</script>
<style>
#gjs {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
border: 3px solid #444;
}
/* Reset some default styling */
.gjs-cv-canvas {
top: 0;
width: 100%;
height: 100%;
}
.gjs-block {
width: auto;
height: auto;
min-height: auto;
}
.panel__top {
padding: 0;
width: 100%;
display: flex;
position: initial;
justify-content: center;
justify-content: space-between;
}
.panel__basic-actions {
position: initial;
}
</style>
Answers (3)
Take a look at this issue, maybe helps: https://github.com/artf/grapesjs/issues/275
<template>
<div :id="id"></div>
</template>
<script>
export default {
props: {
id: {
type: String,
required: true
}
},
data() {
return {
editor: null
}
},
methods: {
change() {
this.$emit('change', this.editor.getHtml());
},
},
mounted() {
this.editor = grapesjs.init({
container: '#editor',
height: this.height,
plugins: ['gjs-preset-newsletter'],
});
this.editor.on('change', this.change);
}
}
</script>
Hi @joshk132 honestly the code looks good, are you able to create a reproducible demo (on something like Codesandbox)?
@artf I've gotten it working where the panels show up however it now doesn't display right. The solution I had to do was change to use the below code. Pretty much I had to have "editor" as a variable which I had removed in my initial code because the vue linter was complaining. Attached there is a link to an image of how it looks with the below code, I am unsure on what exactly is wrong to cause the style issues.
<template>
<div class="base">
<div class="panel__top">
<div class="panel__basic-actions"></div>
<div class="panel__switcher"></div>
</div>
<div class="panel__right">
<div class="layers-container"></div>
<div class="styles-container"></div>
</div>
<div id="gjs">
<h1>Hello World Component!</h1>
</div>
<div id="blocks"></div>
<link rel="stylesheet" href="https://unpkg.com/grapesjs/dist/css/grapes.min.css">
</div>
</template>
<script>
// import VueGrapesjs from 'vue-grapesjs'
import grapesjs from 'grapesjs'
export default {
name: 'app',
data () {
return {
}
},
mounted(){
const editor = grapesjs.init({
// Indicate where to init the editor. You can also pass an HTMLElement
container: '#gjs',
// Get the content for the canvas directly from the element
// As an alternative we could use: `components: '<h1>Hello World Component!</h1>'`,
fromElement: true,
// Size of the editor
height: '1000px',
width: 'auto',
// Disable the storage manager for the moment
storageManager: false,
// Allows creation of "blocks"
blockManager: {
appendTo: '#blocks',
blocks: [
{
id: 'section', // id is mandatory
label: '<b>Section</b>', // You can use HTML/SVG inside labels
attributes: { class:'gjs-block-section' },
content: `<section>
<h1>This is a simple title</h1>
<div>This is just a Lorem text: Lorem ipsum dolor sit amet</div>
</section>`,
}, {
id: 'text',
label: 'Text',
content: '<div data-gjs-type="text">Insert your text here</div>',
}, {
id: 'image',
label: 'Image',
// Select the component once it's dropped
select: true,
// You can pass components as a JSON instead of a simple HTML string,
// in this case we also use a defined component type `image`
content: { type: 'image' },
// This triggers `active` event on dropped components and the `image`
// reacts by opening the AssetManager
activate: true,
}
]
},
layerManager: {
appendTo: '.layers-container'
},
});
editor.Panels.addPanel({
id: 'panel-top',
el: '.panel__top',
});
editor.Panels.addPanel({
id: 'basic-actions',
el: '.panel__basic-actions',
buttons: [
{
id: 'visibility',
active: true, // active by default
className: 'btn-toggle-borders',
label: '<u>B</u>',
command: 'sw-visibility', // Built-in command
}, {
id: 'export',
className: 'btn-open-export',
label: 'Exp',
command: 'export-template',
context: 'export-template', // For grouping context of buttons from the same panel
}, {
id: 'show-json',
className: 'btn-show-json',
label: 'JSON',
context: 'show-json',
command(editor) {
editor.Modal.setTitle('Components JSON')
.setContent(`<textarea style="width:100%; height: 250px;">
${JSON.stringify(editor.getComponents())}
</textarea>`)
.open();
},
}
],
});
editor.on('run:export-template:before', opts => {
console.log('Before the command run');
opts.abort = 0; // 0 = true 1 = false
});
editor.on('run:export-template', () => console.log('After the command run'));
editor.on('abort:export-template', () => console.log('Command aborted'));
}
}
</script>
<style>
#gjs {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
border: 3px solid #444;
}
/* Reset some default styling */
.gjs-cv-canvas {
top: 0;
width: 100%;
height: 100%;
}
.gjs-block {
width: auto;
height: auto;
min-height: auto;
}
.panel__top {
padding: 0;
width: 100%;
display: flex;
position: initial;
justify-content: center;
justify-content: space-between;
}
.panel__basic-actions {
position: initial;
}
.editor-row {
display: flex;
justify-content: flex-start;
align-items: stretch;
flex-wrap: nowrap;
height: 300px;
}
.editor-canvas {
flex-grow: 1;
}
.panel__right {
flex-basis: 230px;
position: relative;
overflow-y: auto;
}
</style>
Related Questions and Answers
Continue research with similar issue discussions.
Issue #2850
[QUESTION] Add Dropdown to block using Traits
Hi @artf , I hope that you are well, I was wondering whether you could help me with some simple issue that I am having (I have recently sta...
Issue #3101
BUG: Getting Started Docs example is static
https://grapesjs.com/docs/getting-started.html - Getting started guide examples are static. All we can see is 'Hello World Component!' when...
Issue #1496
issue in adding new row cell in grapejs not working
i am using grapejs version 0.14.33 with angular 6 i want to add a section with 2 blocks on block manager as created on grapejs demo. and fo...
Issue #6518
BUG: Getting Started doesn't show Blocks as written
GrapesJS version [x] I confirm to use the latest version of GrapesJS What browser are you using? Chrome 136.0.7103.93 Reproducible demo lin...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.