集成使用 @vue/composition-api 的组件库的运行时错误:'您必须在“setup()”方法中使用此函数'

Posted

技术标签:

【中文标题】集成使用 @vue/composition-api 的组件库的运行时错误:\'您必须在“setup()”方法中使用此函数\'【英文标题】:Runtime Error integrating a component lib that uses @vue/composition-api: 'You must use this function within the "setup()" method'集成使用 @vue/composition-api 的组件库的运行时错误:'您必须在“setup()”方法中使用此函数' 【发布时间】:2021-02-28 01:26:16 【问题描述】:

对于以下问题的任何帮助将不胜感激!

情况:

我的project 包含两个包

    子组件库

    包含单个视图 About.vue,以组合 API 样式编写(带有 vue2 辅助库 @vue/composition-apivuex-composition-helpers) 导出单个RouteConfig 构建为库

    views/About.vue(儿童)

    <template>
      <div class="about">
        <h1>This is an about page (as component lib)</h1>
      </div>
    </template>
    
    <script>
    import  defineComponent  from "@vue/composition-api";
    import  createNamespacedHelpers  from "vuex-composition-helpers";
    
    export default defineComponent(
      components: ,
      setup(_,  root ) 
        const  useGetters, useActions  = createNamespacedHelpers("account"); // error thrown here!
      
    );
    </script>
    

    router/index.ts(儿童)

    export const routes: Array<RouteConfig> = [
        path: "/",
        name: "About",
        component: () => import(/* webpackChunkName: "about" */ "../views/About.vue")
    ];
    

    lib.ts(儿童)

    export const routes = require("@/router").routes;
    

    package.json(儿童)

    "scripts": 
      "build": "vue-cli-service build --target lib --name child-component-lib src/lib.ts"
    ...
    

    父应用

    将来自child-component-lib 的路由导入其路由器 包含一个简单的视图,显示一行文本和一个&lt;router-view /&gt;

    package.json(父母)

    "dependencies": 
        "@tholst/child-component-lib": "file:../child-component-lib",
    

    router/index.ts(父母)

    import  routes as childComponentRoutes  from "@tholst/child-component-lib";
    
    const routes: Array<RouteConfig> = [...childComponentRoutes];
    const router = new VueRouter(routes);    
    export default router;
    

    App.vue(父母)

    <template>
      <div id="app">
        <Home />
        <router-view />
      </div>
    </template>
    
    <script>
    import  defineComponent  from "@vue/composition-api";
    import Home from "@/views/Home.vue";
    
    export default defineComponent(
      components: 
        Home
      ,
      setup(_,  root ) 
        ...
      
    );
    </script>
    

预期行为

它可以正常工作。

实际行为

我在控制台中看到错误输出。 [Vue warn]: Error in data(): "Error: You must use this function within the "setup()" method, or insert the store as first argument." 错误信息具有误导性,因为错误实际上是在setup() 方法内部抛出的。可以追溯到getCurrentInstance()返回undefined(在@vue/composition-api里面)。


调查:

事实证明,错误消失了我在父应用程序本身中包含相同的About.vue(只需切换路线,尝试一下),即当我们避免从构建的库中导入。 所以它看起来是构建设置有问题vue.config.jswebpackbabeltypescript、...之一)

重现错误:

1。克隆、安装、运行

git clone git@github.com:tholst/vue-composition-api-comp-lib.git && cd vue-composition-api-comp-lib/child-component-lib && npm install && npm run build && cd ../parent-app/ && npm install && npm run serve

或者一个一个

git clone git@github.com:tholst/vue-composition-api-comp-lib.git
cd vue-composition-api-comp-lib/child-component-lib
npm install
npm run build
cd ../parent-app/
npm install
npm run serve

2。打开浏览器

访问http://localhost:8080/

3。打开开发工具查看错误

[Vue warn]: Error in data(): "Error: You must use this function within the "setup()" method, or insert the store as first argument."

found in

---> <Anonymous>
       <App> at src/App.vue
         <Root>

错误截图

环境信息:

Node: 14.2.0
npm: 6.14.8
Chrome: 86.0.4240.198

npmPackages:
    @vue/babel-sugar-composition-api-inject-h:  1.2.1 
    @vue/babel-sugar-composition-api-render-instance:  1.2.4 
    ...    
    @vue/cli-overlay:  4.5.8 
    @vue/cli-plugin-babel: 4.5.8 
    @vue/cli-plugin-router: 4.5.8 
    @vue/cli-plugin-typescript: 4.5.8 
    @vue/cli-plugin-vuex:4.5.8 
    @vue/cli-service: 4.5.8 
    @vue/cli-shared-utils:  4.5.8 
    @vue/component-compiler-utils:  3.2.0 
    @vue/composition-api: 1.0.0-beta.19 
    @vue/preload-webpack-plugin:  1.1.2 
    typescript: 3.9.7 
    vue: 2.6.12 
    vue-loader:  15.9.5 (16.0.0-rc.1)
    vue-router: 3.4.9
    vue-template-compiler: 2.6.12 
    vue-template-es2015-compiler:  1.9.1 
    vuex: 3.5.1 
    vuex-composition-helpers: 1.0.21 

npmGlobalPackages:
    @vue/cli: 4.5.8

【问题讨论】:

【参考方案1】:

我终于明白了问题所在。首先,存在实际问题。其次,本地开发设置中存在问题,导致实际问题的解决方案看起来不起作用。

实际问题+解决方案

子组件库捆绑了他们自己版本的 npm 包 @vue/composition-apivuex-composition-helpers。这产生了以下效果:当我运行父应用程序时,实际上有这些库的 两个实例,并且子组件库中的 vue 组件正在访问错误的对象,该对象未正确初始化。

解决方案是防止将这些库捆绑在子组件库中,通过

    将它们设为devDependenciespeerDependencies

    指示 webpack 不要将它们捆绑到 npm run build

    package.json

    "dependencies": 
        ...
    ,
    "devDependencies": 
        "@vue/composition-api": "^1.0.0-beta.19",
        "vuex-composition-helpers": "^1.0.21",
        ...
    ,
    "peerDependencies": 
        "@vue/composition-api": "^1.0.0-beta.19",
        "vuex-composition-helpers": "^1.0.21"
    ,
    

    vue.config.js

    configureWebpack: 
        externals: 
            "@vue/composition-api": "@vue/composition-api",
            "vuex-composition-helpers": "vuex-composition-helpers"
        ,
        ...
    
    

让事情变得困难的棘手问题

我试图在本地解决这个问题,但没有实际发布包。它似乎有效,因为我在本地看到了与在已发布包中看到的相同的问题。

我通过直接链接父应用程序和子组件库来进行本地开发。我都试过了

    一个直接文件夹依赖

    package.json

    "dependencies": 
        "@tholst/child-component-lib": "file:../child-component-lib",
    ,
    

    npm link

    cd child-component-lib
    npm link
    cd ../parent-app
    npm link @tholst/child-component-lib
    

这两种方法都具有实际导入(=符号链接到)子组件库的文件夹所有文件和文件夹(而不是仅将在 npm 包中发布的文件)的效果)。

这意味着以下内容:即使我已从捆绑包中排除了两个组合 API 库并使其成为开发/对等依赖项(请参阅实际问题的解决方案),但它们是仍然安装并存在于子组件库的node_modules 中。并且 node_modules 文件夹被符号链接到父应用程序包中。通过这种方式,子组件库仍然可以访问我们想要从构建中排除的库的自己的副本(请参阅实际问题)。而且我仍然像以前一样看到错误。

通过这种方式,我的本地开发方法掩盖了实际问题的解决方案确实有效这一事实。

【讨论】:

我希望以前看过你的帖子,遇到了完全相同的问题,我费了很大劲才找到解决方案! @JoelPintoRibeiro 是的,我也挣扎了好几天!

以上是关于集成使用 @vue/composition-api 的组件库的运行时错误:'您必须在“setup()”方法中使用此函数'的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 @vue/composition-api 和 nuxt.js 获取 vue-apollo 实例

JEST @vue/composition-api + Jest 测试套件无法运行 [vue-composition-api] 在使用任何函数之前必须调用 Vue.use(VueComposition

Vue3 composition-api&setup 生命周期

Vue3 composition-api&setup 生命周期

在 uni-app 中使用 composition-api 组合API开发

vue3.0 初体验 一边学习一边写