vue-demi
vue-demi copied to clipboard
docs: added remark about component libraries
To avoid more issues about why a certain Vue3
library/plugin failed to work in a Vue2
project, I thought it would be useful to add it to the README.md.
I tried to add a more compact version of the answer @LinusBorg gave me on Discord (see #152).
I think the message is a bit misleading. The problem is not that you can't use vue-demi
with a component library (e.g. @vueuse/components
is using vue-demi
, and if you going to ship Vue SFC you might still need vue-demi
for the APIs), but the fact the SFC compilation process and the result are different across Vue 2 and 3.
Instead of You CAN'T
, I think it's better to Be cautious to work with Vue SFC
.
In order to build a component library/plugin for both
Vue2
andVue3
you could either publish plainVue
files or build your library seperately forVue2
andVue3
.
It would be nice, to have an example for exactly that: use components from Vue 3 inside a Vue 2 app. Maybe you could also add one to the example folder?
I struggle with this atm. As @antfu said, I think you still need vue-demi for the different APIs. I think, I managed to do it by having a separate folder with dedicated package.json and and vite config to compile vue 3 components into a lib for vue 2. Feels messy. Maybe there is a cleaner way.
@antfu, you're right. I tried to rephrase it to make it more clear that it is still possible, but requires some extra steps.
@dsvgl, I currently don't have any examples on how to do any of the 2 options. My use case allows me to just compile it solely for vue 2 now, and recompile for vue 3 later when we upgrade to nuxt 3. But I do agree that it might be useful to have some basic example somewhere, altough it can get complex pretty quick I think.
@jclaessens97 ok. I have the same use case :) Do you have a repo to look into? Or maybe we could have a chat on discord, so we don't pollute this PR? I'm Dominic#2461 over there. Would be highly appreciated! Of course, only if you want.
@antfu I really think this should add to doc asap, since SFC are the most common practice in Vue project. It should clearify that this lib might not as mighty as they think.
In order to build a component library/plugin for both
Vue2
andVue3
you could either publish plainVue
files or build your library separately forVue2
andVue3
. Both options can be tricky because there are a few differences in their runtime APIs.
@antfu
@vueuse/components is using vue-demi
@vueuse/components
is renderless components
https://github.com/sadeghbarati/vue-demi-component-reproductions https://www.npmjs.com/package/@smooth-scrollbar-contrib/vue-test?activeTab=explore
- in Vue 2.6 and maybe 2.7 component needs
this.$listeners
to events like ( @click, @... ) or CustomEvents works properly on components, but in Vue 3 $listeners merges into $attrs and thats requires build your library separately forVue2
andVue3
alsopostinstall
script to switch between build code based on user Vue version
- If you want create a Vue package with
vue-demi
you have to use APIs that exist in both Vue 2 & 3
- Writing composable libs is easy with
vue-demi
but if you want to create Vue components that requires to check Vue 2 & 3 documentation and also migrations guides ðŸ˜
https://github.com/vuejs/vue/issues/12690
Vue 2 render functions work very differently from Vue 3. This was the part that had the biggest changes in Vue 3. Please make sure to read the relevant documentation: https://v2.vuejs.org/v2/guide/render-function.html
This will add some extra complexity to library authors.
-
Vue 2.6 and 2.7
h
function type is different from Vue 3 ( I know it's different from other versions of Vue, only mention cause This will adds some extra complexity to library authors )
for example Vue 2.6 and 2.7 ref
types is ref?: string
but in Vue 3 is ref?: VNodeRef;
There are a lot of vue-demi
packages on GitHub each of them use their own ways ( not recommended ways, Recommended ways that are not even mentioned in this project ), which cannot be recognized if they are doing the right thing or not 🤔
for example json-editor-vue use getCurrentInstance
for access template ref onMount (IIRC Evan said don't use getCurrentInstance cause it's not safe and it's maybe move to a private or internal function in new releases)
vue-winbox use h-demi
helper, but actually I prefer to use isVue3
or isVue2
for simple implementation
BTW took me two weeks or maybe more to test vue-demi with Vue 2.6.14 - 2.7.10 - 3.2.39 :[ to find out what is going on
unplugin-auto-import vue preset
export const CommonCompositionAPI = [
// lifecycle
'onActivated',
'onBeforeMount',
'onBeforeUnmount',
'onBeforeUpdate',
'onErrorCaptured',
'onDeactivated',
'onMounted',
'onServerPrefetch',
'onUnmounted',
'onUpdated',
// setup helpers
'useAttrs',
'useSlots',
// reactivity,
'computed',
'customRef',
'isReadonly',
'isRef',
'markRaw',
'reactive',
'isReactive',
'isProxy',
'readonly',
'ref',
'shallowReactive',
'shallowReadonly',
'shallowRef',
'triggerRef',
'toRaw',
'toRef',
'toRefs',
'unref',
'watch',
'watchEffect',
'watchPostEffect',
'watchSyncEffect',
// component
'defineComponent',
'defineAsyncComponent',
'getCurrentInstance',
'h', // different types
'inject',
'nextTick',
'provide',
'useCssModule',
'createApp',
// effect scope
'effectScope',
'EffectScope',
'getCurrentScope',
'onScopeDispose',
]
These APIs can be used within your package without needing to use isVue2
or isVue3
, except for some APIs with different types ( I think ) or breaking-changes APIs or APIs that has Limitations
If you can't handle the API with isVue
conditions you have to separate your build code for example vue-demi
lib folder
and also need scripts
and bin
postinstall
script (Run AFTER the package is installed.)
simple cli
for manually switching between your build
Hope it helps someone and I Hope Anthony Correct the mistakes in my explanation