I've had quite a bit of trouble with this myself so will provide an answer specifically for Vue 3 as Stencil's Framework Integrations guide seems to refer only to Vue 2.
Starting Projects
Stencil Component
Following the Getting Started guide run npm init stencil. Choose the component option.
There was a bug in v2.7.0 so I update to v2.8.0 with npm i @stencil/core@latest --save-exact
Build the project with npm run build
Optional
By default, the stencil project configures multiple build targets, to make it easier to see what build files are being used you can edit the stencil config to only include the custom elements bundle:
\\ stencil.config.ts
outputTargets: [
{
type: 'dist-custom-elements-bundle',
},
{
type: 'dist',
esmLoaderPath: '../loader',
},
],
You also need the 'dist' type for the .d.ts typings file to be generated with your custom-elements (not sure why).
Vue 3 App
Using a globally installed Vue CLI @vue/cli@4.5.13 create a new Vue 3 default project.
Using Stencil in Vue 3
Install your stencil component project
npm install --save ../<path>/stencil-component as a dependency of your vue app.
Fixing NPM Module Resolution
Following the Vue CLI - Troubleshooting guide add a vue.config.js file to the root of your Vue 3 project with the line config.resolve.symlinks(false),
Skipping Component Resolution
In the same file we need to configure Using Custom Elements in View
\\ vue.config.js
module.exports = {
chainWebpack: (config) => {
config.resolve.symlinks(false),
config.module
.rule("vue")
.use("vue-loader")
.tap((options) => ({
...options,
compilerOptions: {
isCustomElement: (tag) => tag.includes("my-"),
},
}));
},
};
Framework Integration
Now we can declare the custom elements, but in the Vue 3 way
\\ main.js
import { createApp } from 'vue'
import App from './App.vue'
import { defineCustomElements } from "stencil-component";
defineCustomElements();
createApp(App).mount('#app');
You can now use your custom component as normal. Here's what my App.vue file looked like after hacking the example starter code:
<template>
<my-component first="Andy" middle="2K" last="11"></my-component>
</template>
<script>
import { MyComponent } from "stencil-component";
export default {
name: 'App',
components: {
MyComponent
}
}
</script>
Errors
No ESLint Config
No ESLint configuration found in /<path>/stencil-component/dist/custom-elements.
Fixed by telling webpack not to resolve symlinks in vue.config.js
Uncaught TypeError: class constructors must be invoked with 'new'
This error occurs in the browser after a successful compilation.
Resolved by telling webpack / vue not to resolve your custom components
Custom Component Not Visible
There are no errors and your component is showing in the DOM inspector but not appearing on the page.
You need to defineCustomElements() in main.js.
Component not found
I've had some variation of this error when trying to import and use my component but haven't been able to reproduce it just now. Doing all of the above and restarting the dev server works fine for me.