I am currently using quasar v2(vuejs3) and the gold-layout 2.5.0 version.
(I also tried vue-golden-layout, but I gave up because it was difficult to use in quasar v2)
project structure
components
- TestCom.vue : simple component with only div and h2
- WebEditor.vue : part where the monaco editor is defined, and it works normally when the golden layout is not used.
layouts
- GoldenLayout.vue : The page where I want to use the Golden-layout package.
App.vue
I imported other components in Golden Layout.vue and registered in Golden-layout. There is no error message when running, but the contents of the components are not visible.
Is there a right way to register the component in Golden layout?
layouts/GoldenLayout.vue
<template>
<div>
<link type="text/css" rel="stylesheet" href="//golden-layout.com/assets/css/goldenlayout-base.css" />
<link type="text/css" rel="stylesheet" href="//golden-layout.com/assets/css/goldenlayout-light-theme.css" />
<div ref ="test"></div>
</div>
</template>
<script>
import {shallowRef , ref, onMounted, onUnmounted, h } from "vue";
import { GoldenLayout } from "golden-layout/src/index";
import WebEditor from "components/WebEditor.vue";
import TestCom from "components/TestCom.vue"
export default {
name: 'App',
components: {
},
setup(props) {
let c = () => h(WebEditor, {
code : "import java.util.*;\nimport java.io.*;\n\npublic class Main{\n public static void main(String[] args) throws IOException {\n BufferedReader re = new BufferedReader(new InputStreamReader(System.in));\n \n int a = Integer.parseInt(re.readLine());\n int b = Integer.parseInt(re.readLine());\n\n System.out.println(a+b);\n re.close();\n }\n}",
language : "java",
readonly : false
});
let d = () => h(TestCom);
const test = ref(undefined);
let goldenLayout;
const config = {
content:
[
{
type: 'row',
content:
[
{
type: 'component',
componentName: 'WebEditor',
componentType : 'WebEditor'
},
{
type: 'component',
componentName: 'TestCom',
componentType : 'TestCom'
}
]
}
]
}
onMounted(() => {
goldenLayout = new GoldenLayout(test);
goldenLayout.registerComponent('WebEditor', c);
goldenLayout.registerComponent('TestCom', d);
goldenLayout.init();
goldenLayout.loadLayout(config);
});
onUnmounted(() => {
goldenLayout.destroy();
});
return {
test
};
}
};
</script>
<style scoped>
</style>
components/TestCom.vue
<template>
<div>
<h2 style="height:200px">Test</h2>
</div>
</template>
<script>
export default {
setup () {
return {}
}
}
</script>
<style lang="scss" scoped>
</style>
componets/WebEditor.vue
<template>
<div>
<div ref="editorDiv" style="height: 100%; width:100%"></div>
<div><h2 @click="updateEditor">refresh</h2></div>
</div>
</template>
<script>
// package.json
// "monaco-editor": "^0.33.0",
// "monaco-editor-webpack-plugin": "^7.0.1",
// quasar.confg
// const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
// module.exports = configure(function (/* ctx */) {
// return {
// plugins: [new MonacoWebpackPlugin()],
import { ref, onMounted } from "vue";
import * as monaco from 'monaco-editor';
export default {
// example
//
// <web-editor code="import java.util.*" language="java" :readOnly="false"></web-editor>
name : 'WebEditor',
props :{
code : String, // "import java.util.*;\nimport java.io.*;\n\npublic class Main{\n public static void main(String[] args) throws IOException {\n BufferedReader re = new BufferedReader(new InputStreamReader(System.in));\n \n int a = Integer.parseInt(re.readLine());\n int b = Integer.parseInt(re.readLine());\n\n System.out.println(a+b);\n re.close();\n }\n}"
language : String, // "java", "c", "python"
readOnly : Boolean, // "false"
},
setup (props) {
const editorDiv = ref(undefined);
let monacoEditor;
let editorCode = JSON.parse(JSON.stringify(props.code));
let editorLanguage = JSON.parse(JSON.stringify(props.language));
let editorReadOnly = JSON.parse(JSON.stringify(props.readOnly));
onMounted(() => {
monacoEditor = monaco.editor.create(editorDiv.value,{
// model: null,
readOnly: editorReadOnly,
value: editorCode,
language: editorLanguage,
// theme: 'vs', //light version
theme: 'vs-dark',
tabSize: 2,
fontFamily: "Consolas",
// fontFamily: 'D2Coding',
// fontFamily: 'IBM Plex Mono',
fontSize: 12,
});
});
const updateEditor = () => {
editorCode = monacoEditor.getValue();
monacoEditor.dispose();
monacoEditor = monaco.editor.create(editorDiv.value,{
// model: null,
readOnly: editorReadOnly,
value: editorCode,
// c,cpp,java,javascript,python
language: editorLanguage,
// theme: 'vs', //light version
theme: 'vs-dark',
tabSize: 2,
fontFamily: "Consolas",
fontSize: 12,
});
};
return {
editorDiv,
monacoEditor,
editorCode,
editorLanguage,
editorReadOnly,
updateEditor
};
}
}
</script>
<style lang="scss" scoped>
</style>
This is my first time asking a question in stackoverflow. If you feel that I made a mistake or lack explanation for the problem, please let me know right away.
Unfortunately, the official documentation points to this code, which uses "Golden Layout’s virtual component (virtual via events binding)", but I wasn't able to understand it correctly.
To solve this myself, I created a
GoldenLayoutVue.vuecomponent that takes care of the lifecycle ofGoldenLayouts:It's not the recommended solution, so it's a hack and it might funny with persistent state (although as far as I can tell, it works fine).
Use the component like so:
Notice how both the slot name (
<template #ComponentA>) and the property in the layoutConfig (componentType: 'ComponentA') match exactly.