在 Ionic Vue 中使用 Stencil 组件

Using Stencil components with Ionic Vue

在 Stencil 文档关于框架与 Vue 集成的部分中,它声明如下:

In order to use the custom element library within the Vue app, the application must be modified to define the custom elements and to inform the Vue compiler which elements to ignore during compilation.

根据同一页面,这可以通过像这样修改 Vue 实例的配置来实现:

Vue.config.ignoredElements = [/test-\w*/];

但这与 Vue 2 相关。对于 Vue 3(Ionic Vue 使用的),您必须按照此处所述使用 isCustomElement。

遗憾的是,我这辈子都无法让 Vue 和 Stencil 发挥出色。我试过这样设置配置:

app.config.compilerOptions.isCustomElement = tag => /gc-\w*/.test(tag)

这会导致 Vue 在控制台中抛出以下警告:

[Vue warn]: The `compilerOptions` config option is only respected when using a build of Vue.js that includes the runtime compiler (aka "full build"). Since you are using the runtime-only build, `compilerOptions` must be passed to `@vue/compiler-dom` in the build setup instead.
- For vue-loader: pass it via vue-loader's `compilerOptions` loader option.
- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader
- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/p

但是,我不知道如何使用 Ionic Vue 实现上述任何建议。我一直在 config.vue.js 中摆弄 chainWebpack 但到目前为止没有成功。

如有任何帮助,我们将不胜感激。

我不是 Vue 专家,但我是这样做的:

将以下内容添加到您的 ./vue.config.js(如果不存在,则创建它):

/**
 * @type {import('@vue/cli-service').ProjectOptions}
 */
module.exports = {
  // ignore Stencil web components
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        options.compilerOptions = {
          ...options.compilerOptions,
          isCustomElement: tag => tag.startsWith('test-')
        }
        return options
      })
  },
}

这将指示 Vue 忽略 test-* 组件。资料来源:https://v3.vuejs.org/guide/web-components.html#skipping-component-resolution

接下来,加载./src/main.ts中的组件。

导入 Stencil 项目:

import { applyPolyfills, defineCustomElements } from 'test-components/loader';

然后将createApp(App).use(router).mount('#app')替换为:

const app = createApp(App).use(router);

// Bind the custom elements to the window object
applyPolyfills().then(() => {
    defineCustomElements();
});

app.mount('#app')

来源:https://stenciljs.com/docs/vue

此外,如果有人在使用 vite2+,请相应地编辑 vite.config.js:

import { fileURLToPath, URL } from 'url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue({
    template: {
      compilerOptions: {
        isCustomElement: tag => tag.startsWith('test-') // ✅ Here
      }
    }
  }) ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})