Vue 作为 ES 模块构建在使用 vite 构建组件库时失去反应性

Vue as ES Module Build loses reactivity when I build component library using vite

提问人:Peter 提问时间:11/15/2023 最后编辑:Jason AllerPeter 更新时间:11/15/2023 访问量:44

问:

我目前正在做一个项目,想创建几个组件,通过 vite 构建它们,并使用 Vue CDN 托管的独立版本在另一个项目中使用它们。

正如网站上提到的,我使用 Vue

<script type="importmap">
{
    "imports": {
     "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
     }
}
</script>

然后在这个项目中,我将 Vue 与 importmap ES Build 一起使用,并从我的静态路径导入我生成的 vue 组件。我添加了另一个 createVue,只是为了检查 vue 是否是反应式的。 第二个 vue 实例 (#lala) 是反应式的,我可以更新计数器引用并查看结果。

<div id="appvue"></div>

<div id="lala"> 
  <div @click="counter++">
    {{counter}}
   </div>
</div>
                            
<link rel="stylesheet" href="/static/js/vue/style.css" type="text/css" />
                     
<script type="module">
    import { createApp, ref } from 'vue'
    import { MyComponent } from '/static/js/vue/index.js';
                    
    createApp(MyComponent).mount('#appvue')
              
    createApp({
        setup() {
            const counter = ref(0)
            return {
              counter
            }
        }
    }).mount('#lala');
</script>

棘手的部分来了:我在我的静态目录中创建了我的 vue 组件:

MyComponent.vue:

<template>
    hallo
  <button @click="count++">Du hast {{ count }} mal geklickt</button>
  <div class="message">Hier ist die message: {{message}}</div>
  <div>test</div>
  <input v-model="text">
</template>

<script>
import {ref} from "vue";

export default {
    setup()
    {
        const count = ref(0);
        const text = ref("ändere mich");

        const message = ref("hallo");

        return {
            count,
            message,
            text
        };
    }
};
</script>

<style>
div{
  font-size: 20px;
}

.message{
  font-weight: bold;
  color: mediumvioletred;
}
</style>

我的main.ts文件,这是 vite 的条目:

import MyComponent from "@/components/MyComponent.vue"
export { MyComponent }

最后是我的 vite 配置,它应该构建我的 Lib:

import {fileURLToPath, URL} from "url"
import {defineConfig, loadEnv} from "vite"
import vue from "@vitejs/plugin-vue"

defineConfig(({ mode }) =>
{
    const env = loadEnv(mode, process.cwd(), "");
    return {
        plugins: [vue()],
        root: "frontend",
        resolve: {
            alias: {
                "@": fileURLToPath(new URL("./frontend/src", import.meta.url))
            }
        },
        server: {
            port: 3000,
        },
        build: {
            lib: {
                entry: "./src/main.ts",
                formats: ["es", "cjs"],
                fileName: format => (format == "es" ? "index.js" : "index.cjs")
            },
            rollupOptions: {
                external: ["vue"],
                output: {
                    globals: {
                        vue: "Vue",
                    },
                },
            }
        },
        define: {
            "process.env": env
        },
        test: {
            globals: true,
            environment: "jsdom",
            reporters: "junit",
            outputFile: "../build/reports/vitest/vitest.xml"
        }
    }
})

所以我的问题是,#lala div 中的计数器是反应式的并且计数,构建组件中的计数器是可见的,但根本没有更新。可能是什么问题?一直被困在那里一段时间了,无法想出解决方案,使构建的组件具有响应性。

JavaScript vue.js Vite ES6-模块 汇总

评论

0赞 Estus Flask 11/15/2023
反应性的问题是当有超过 1 个 Vue 副本时观察到的情况。你依靠窗户。在一个地方使用 Vue,但在另一个地方使用 Vue ESM。
0赞 Peter 11/15/2023
那么我应该删除全局变量: { vue: “Vue”} ?或者我应该尝试什么?
0赞 Estus Flask 11/15/2023
是的,我希望您需要保留外部并删除全局变量,不能确定这是否是您设置中的唯一问题
0赞 Peter 11/15/2023
我仍然无法与我的 Vue 组件交互:(
0赞 Estus Flask 11/15/2023
你能提供一种简化的复制方式吗?此时将受益于调试。该组合可能是静态的 .js,因为这就是它的构建目的。

答: 暂无答案