Vue 2.7 Composition API 插件提供/注入

问题描述 投票:0回答:1

我正在尝试创建一个使用提供/注入组合 API 功能的 vue 2.7 插件。 我似乎能够在自己的项目中使用提供/注入,但是当使用 npm 链接时,它似乎全部崩溃了。我收到的错误是:

provide() can only be used inside setup().
inject() can only be used inside setup() or functional components.

我的代码如下。

来自我的插件代码: 包.json

{
  "name": "test-v2",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "keywords": [
    "vue"
  ],
  "main": "./dist/test-plugin.umd.js",
  "module": "./dist/test-plugin.es.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/test-plugin.es.js",
      "require": "./dist/test-plugin.umd.js"
    },
    "./v2": {
      "import": "./v2/dist/test-plugin.es.js",
      "require": "./v2/dist/test-plugin.umd.js"
    }
  },
  "files": [
    "dist",
    "src"
  ],
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vite build",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@vitejs/plugin-vue2": "^2.2.0",
    "vite": "^4.3.8",
    "vue": "^2.7.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "vue-template-compiler": "^2.6.14"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

Vite配置

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue2';
import path from 'path';
import { fileURLToPath } from 'url';

export default defineConfig({
    resolve: {
        dedupe: ['Vue'],
        alias: {
            '@': path.resolve(__dirname, './src'),
            'vue': fileURLToPath(new URL('./node_modules/vue', import.meta.url))
        },
    },
    plugins: [vue()],
    build: {
        lib: {
            entry: path.resolve(__dirname, 'src/plugin.js'),
            name: 'test-plugin',
            formats: ['es', 'cjs', 'umd'],
            fileName: format => `test-plugin.${format}.js`,
        },
        rollupOptions: {
            input: {
                main: path.resolve(__dirname, 'src/plugin.js'),
            },
            external: ['vue'],
            output: {
                exports: 'named',
                globals: {
                    vue: 'Vue',
                },
            },
        },
    },
});

插件.js

import Example from '@/components/HelloWorld.vue';

const plugin = {
    install: function(app) {
        app.component('Example', Example);
    },
};

export default plugin;
export {
    Example,
};

父组件

<template>
  <div class="parent">
    <Child />
  </div>
</template>


<script>
import Vue, { defineComponent, provide } from "vue";
import Child from "./Child.vue";

export default defineComponent({
  name: "HelloWorld",
  components: {
    Child,
  },
  setup() {
    provide("hello", "yes");
  },
});
</script>

子组件

<template>
  <div class="test-output">
    Child Output: <br>
    {{ map }}
  </div>
</template>

<script>
import Vue, { inject } from 'vue';

export default {
  name: 'Child',
  setup() {
    const map = inject('hello');
    console.log('prototype', map);
    console.log('Vue.version', Vue.version);
    
    return {
      map,
    };
  },
}
</script>

我的项目正在导入这个插件 包.json

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@vitejs/plugin-vue2": "^2.2.0",
    "core-js": "^3.8.3",
    "vite": "^4.3.9",
    "vue": "^2.7.14"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "vue-template-compiler": "^2.7.14"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

Main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

import Example from 'test-v2';
Vue.use(Example);

new Vue({
  render: h => h(App),
}).$mount('#app')

应用程序.vue

<template>
  <div id="app">
    <div class="flex">
      <Example />
    </div>
  </div>
</template>

<script>
export default {
  name: "MyAPP",
};
</script>

感谢您对此主题的任何建议。

vue.js vuejs2 vue-composition-api
1个回答
1
投票

尝试这个模式:

一些插件.js

const SomePlugin = {
 install: (Vue, opt) => {
  Vue.prototype.$somePlugin = {
   // your plugin code
  }
 }
}
export default SomePlugin

main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

import SomePlugin from './somePlugin.js';
Vue.use(SomePlugin );

new Vue({
  // provide
  provide: {
   somePlugin: Vue.prototype.$somePlugin,
  },
  render: h => h(App),
}).$mount('#app')

然后将其注入到您的组合 API 组件中:

<script setup>
import { inject } from 'Vue'
const somePlugin = inject('somePlugin')
</script>

希望这会有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.