Open butaminas opened 5 years ago
you can achieve this by doing something like this:
import CustomBlock from './CustomBlock.vue';
const ComponentCtor = Vue.extend(CustomBlock);
class SimpleImage {
constructor({ data }: ImageProps) {
this.data = data;
this.wrapper = null;
}
static get toolbox() {
// see the getting started tutorial;
}
render() {
this.wrapper = document.createElement('div');
this.wrapper.id = 'custom-id';
// this you can use this like any other vue component.
this.component = new ComponentCtor({
propsData: this.data,
});
this.component.$mount('#custom-id');
return this.wrapper;
}
save(blockContent) {
// in the component have a function that returns the required data.
return this.component.getData();
}
validate(savedData) {
if (!savedData.url.trim()) {
return false;
}
return true;
}
}
i hope this is enough to get you started.
I ended up doing the following
render() {
this.wrapper = document.createElement('div');
this.wrapper.id = 'custom-id';
// this you can use this like any other vue component.
this.component = new ComponentCtor({
propsData: {
filetypes: []
},
});
this.component.$mount();
return this.wrapper.appendChild(this.component.$el);
}
any know a way to access the current vue instance in the class maybe pass it via config or is there a other way? i use nuxt i dont have a way to import or export vue itself
//e found a other way i will make a config callback which is calling in the initalizer component then i will pass my data back
Is there any work around for this in the vue 3?
@luckyboy07 sorry for my late answer, i just did this in vue 3 using my own custom vue 3 component: (you need render
and h
from 'vue')
https://gist.github.com/bettysteger/d7f2b1a52bb1c23a0c24f3a9ff5832d9
@bettysteger Thank you so much, I will definitely try this one.
Hi @bettysteger, I followed your code and succeded in using a custom component in the BlockTool, but there's another issue occured, not sure if you know how to fix it.
I put a primevue component in this custom component which is rendered by h() in blocktool class, but the inner primevue component throw an error:
Property "$primevue" was accessed during render but is not defined on instance.
Render method:
render() {
console.log('render');
this.nodes.wrapper = document.createElement('div');
this.nodes.wrapper.classList.add(styles['SceneHeading-tool']);
const vueComponent = h(SceneHeadingComp, {
showPopoverFn: this._settings.showPopoverFn,
// onDataChanged: (event: any) => {
// console.log('outside onchange', event);
// },
});
render(vueComponent, this.nodes.wrapper);
return this.nodes.wrapper;
}
The custom component:
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import Listbox from 'primevue/listbox';
const selectedCity = ref();
const cities = ref([
{ name: 'New York', code: 'NY' },
{ name: 'Rome', code: 'RM' },
{ name: 'London', code: 'LDN' },
{ name: 'Istanbul', code: 'IST' },
{ name: 'Paris', code: 'PRS' },
]);
</script>
<template>
<div>
<Listbox
v-model="selectedCity"
:options="cities"
class="w-full md:w-56"
option-label="name"
/>
</div>
</template>
Hi @bettysteger, I followed your code and succeded in using a custom component in the BlockTool, but there's another issue occured, not sure if you know how to fix it.
I put a primevue component in this custom component which is rendered by h() in blocktool class, but the inner primevue component throw an error:
Property "$primevue" was accessed during render but is not defined on instance.
Unfortunately i do not know how to fix it, because i have not used Primevue before. Is it possible to use their components outside of an vue app?
I created a few bootstrap-vue-next editorjs block tools and this was possible:
import { h, render, nextTick } from 'vue'
import { BModal } from 'bootstrap-vue-next';
// later in the render function
h(BModal, { ... }
Hi @bettysteger, I followed your code and succeded in using a custom component in the BlockTool, but there's another issue occured, not sure if you know how to fix it. I put a primevue component in this custom component which is rendered by h() in blocktool class, but the inner primevue component throw an error:
Property "$primevue" was accessed during render but is not defined on instance.
Unfortunately i do not know how to fix it, because i have not used Primevue before. Is it possible to use their components outside of an vue app?
I created a few bootstrap-vue-next editorjs block tools and this was possible:
import { h, render, nextTick } from 'vue' import { BModal } from 'bootstrap-vue-next'; // later in the render function h(BModal, { ... }
Finally I figure out the reason, there's no vue appContext from the rendered component which contains $primevue PrimeVue created in the root main.js.
onMounted(() => {
const _this = getCurrentInstance();
editor = new EditorJS({
/**
* Id of Element that should contain Editor instance
*/
holder: 'editorjs',
tools: {
myTool: {
class: MyTool,
config: {
vueInstance: () => _this,
},
},
vueInstance = this.config.vueInstance()
const vueComponent = h(MyVueCompoentWithPrimeVueCompInside, {...});
vueComponent.appContext = { ...vueInstance.appContext };
render(vueComponent, this.nodes.wrapper);
I was wondering if anyone had some experiences or ideas on how could Vue be used for custom tool development?
I know there is a Vue wrapper for editor.js, but it's just a wrapper and I'm not looking for that, I'm looking to develop a custom tool that could utilize the reactivity of Vue.