{"id":29228882,"url":"https://github.com/cube-ui/vue-create-api","last_synced_at":"2025-07-03T11:02:14.966Z","repository":{"id":32955742,"uuid":"146411660","full_name":"cube-ui/vue-create-api","owner":"cube-ui","description":"Make Vue component's invocation by API.","archived":false,"fork":false,"pushed_at":"2025-03-25T06:08:29.000Z","size":622,"stargazers_count":317,"open_issues_count":21,"forks_count":40,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-06-08T22:28:06.590Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cube-ui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-28T07:51:08.000Z","updated_at":"2025-06-04T19:21:33.000Z","dependencies_parsed_at":"2023-01-14T22:49:30.988Z","dependency_job_id":null,"html_url":"https://github.com/cube-ui/vue-create-api","commit_stats":null,"previous_names":["cube-ui/create-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cube-ui/vue-create-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cube-ui%2Fvue-create-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cube-ui%2Fvue-create-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cube-ui%2Fvue-create-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cube-ui%2Fvue-create-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cube-ui","download_url":"https://codeload.github.com/cube-ui/vue-create-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cube-ui%2Fvue-create-api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263314092,"owners_count":23447289,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-03T11:02:07.197Z","updated_at":"2025-07-03T11:02:14.952Z","avatar_url":"https://github.com/cube-ui.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# vue-create-api\nA Vue plugin which make Vue component invocated by API.\n\n[中文文档](https://github.com/cube-ui/vue-create-api/blob/master/README_zh-CN.md)\n\n## Installing\n\nuse npm\n\n```\n$ npm install vue-create-api\n```\n\nuse cdn\n\n```\n\u003cscript src=\"https://unpkg.com/vue-create-api/dist/vue-create-api.min.js\"\u003e\u003c/script\u003e\n```\n\n## Usage\n\n``` js\nimport CreateAPI from 'vue-create-api'\n\nVue.use(CreateAPI)\n\n// or with options.\n\nVue.use(CreateAPI, {\n  componentPrefix: 'cube-'\n  apiPrefix: '$create-'\n})\n\n// then the Vue constructor will have the createAPI function.\n\nimport Dialog from './components/dialog.vue'\n\n// make Dialog component invocated by API.\n\nVue.createAPI(Dialog, true)\n\n// use in general JS files.\n// however, the $props can not be reactive.\n\nDialog.$create({\n  $props: {\n    title: 'Hello',\n    content: 'I am from pure JS'\n  }\n}).show()\n\n// use in a vue component.\n\nthis.$createDialog({\n  $props: {\n    title: 'Hello',\n    content: 'I am from a vue component'\n  },\n}).show()\n```\n\n```ts\n// typescript\nimport CreateAPI from 'vue-create-api'\n\nVue.use(CreateAPI)\n\nVue.createAPI(Dialog, events, single)\n\nthis.$createDialog({\n  $props: {\n    title: 'Hello',\n    content: 'I am from a vue component'\n  }\n}).show()\n```\n```ts\n// d.ts\nimport Vue, { VueConstructor } from 'vue'\nimport { createFunction } from 'vue-create-api';\n\nexport declare class UIComponent extends Vue {\n  show ():void\n  hide ():void\n}\n\ndeclare module 'vue/types/vue' {\n  interface Vue {\n    /** create Dialog instance */\n    $createDialog: createFunction\u003cUIComponent\u003e\n  }\n}\n```\n### Tip\n\n\u003e using typescript, `terser-webpack-plugin`(vue-cli3.x) or `uglifyjs`(vue-cli2.x) adds `{ keep_fnames: true }`\n\n## Constructor Options\n\n|key|description|default|\n|:---|---|---|\n| `componentPrefix`|the prefix name of your component| - |\n|`apiPrefix`|the api prefix|`$create`|\n\n## Methods\n\n### Vue.createAPI(Component, [single])\n\n- Parameters:\n\n  - `{Function | Object} Component` Vue component which must contains `name`\n  - `{Boolean} [single]` whether singleton\n\n- Usage:\n\n  - This method will add a method which is named `$create{camelize(Component.name)}` to Vue's prototype, so you can instantiate the Vue component by `const instance = this.$createAaBb(config, [renderFn, single])` in other components. The instantiated component's template content will be attached to `body` element.\n\n  - `const instance = this.$createAaBb(config, renderFn, single)`\n\n    **Parameters：**\n\n    | Attribute | Description | Type | Accepted Values | Default |\n    | - | - | - | - | - |\n    | config | Config options | Object | {} | - |\n    | renderFn | Optional, used to generate the VNode child node in the slot scene in general | Function | - | function (createElement) {...} |\n    | single | Optional, whether the instantiated component is a singleton or not. If two parameters are provided and the `renderFn`'s type is not function, then the `single` value is the sencond parameter's value. | Boolean | true/false | single in createAPI() |\n\n    **Config options `config`:**\n\n    You can set `$props` and `$events` in `config`, `$props` supported reactive properties, these props will be watched.\n\n    | Attribute | Description | Type | Accepted Values | Default |\n    | - | - | - | - | - |\n    | $props | Component props | Object | - | {\u003cbr\u003e title: 'title',\u003cbr\u003e content: 'my content',\u003cbr\u003e open: false\u003cbr\u003e} |\n    | $events | Component event handlers | Object | - | {\u003cbr\u003e click: 'clickHandler',\u003cbr\u003e select: this.selectHandler\u003cbr\u003e} |\n\n    `$props` example, `{ [key]: [propKey] }`:\n\n    ```js\n    {\n      title: 'title',\n      content: 'my content',\n      open: false\n    }\n    ```\n\n    `title`, `content` and `open` are keys of the component prop or data, and the prop' value will be taken by the following steps:\n\n    1. If `propKey` is not a string value, then use `propKey` as the prop value.\n    1. If `propKey` is a string value and the caller instance dont have the `propKey` property, then use `propKey` as the prop value.\n    1. If `propKey` is a string value and the caller instance have the `propKey` property, then use the caller's `propKey` property value as the prop value. And the prop value will be reactive.\n\n    `$events` example, `{ [eventName]: [eventValue] }`:\n\n    ```js\n    {\n      click: 'clickHandler',\n      select: this.selectHandler\n    }\n    ```\n\n    `click` and `select` are event names, and the event handlers will be taken by the following steps:\n\n    1. If `eventValue` is not a string value, then use `eventValue` as the event handler.\n    1. If `eventValue` is a string value, then use the caller's `eventValue` property value as the event handler.\n\n    You can set [all avaliable properties in Vue](https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth), but you need to add prefix `$`, eg:\n\n    ```js\n    this.$createAaBb({\n      $attrs: {\n        id: 'id'\n      },\n      $class: {\n        'my-class': true\n      }\n    })\n    ```\n\n    **The Returned value `instance`:**\n\n    `instance` is a instantiated Vue component.\n    \u003e And the `remove` method will be **attached** to this instance.\n\n    You can invoke the `remove` method to destroy the component and detach the component's content from `body` element.\n\n    If the caller is destroyed and the `instance` will be automatically destroyed.\n\n- Example:\n\n  First we create Hello.vue component：\n\n  ```html\n  \u003ctemplate\u003e\n    \u003cdiv @click=\"clickHandler\"\u003e\n      {{content}}\n      \u003cslot name=\"other\"\u003e\u003c/slot\u003e\n    \u003c/div\u003e\n  \u003c/template\u003e\n\n  \u003cscript type=\"text/ecmascript-6\"\u003e\n    export default {\n      name: 'hello',\n      props: {\n        content: {\n          type: String,\n          default: 'Hello'\n        }\n      },\n      methods: {\n        clickHandler(e) {\n          this.$emit('click', e)\n        }\n      }\n    }\n  \u003c/script\u003e\n  ```\n\n  Then we make Hello.vue as an API style component by calling the `createAPI` method.\n\n  ```js\n    import Vue from 'vue'\n    import Hello from './Hello.vue'\n    import CreateAPI from 'vue-create-api'\n    Vue.use(CreateAPI)\n\n    // create this.$createHello API\n    Vue.createAPI(Hello, true)\n\n    // init Vue\n    new Vue({\n      el: '#app',\n      render: function (h) {\n        return h('button', {\n          on: {\n            click: this.showHello\n          }\n        }, ['Show Hello'])\n      },\n      methods: {\n        showHello() {\n          const instance = this.$createHello({\n            $props: {\n              content: 'My Hello Content',\n            },\n            $events: {\n              click() {\n                console.log('Hello component clicked.')\n                instance.remove()\n              }\n            }\n          }, /* renderFn */ (createElement) =\u003e {\n            return [\n              createElement('p', {\n                slot: 'other'\n              }, 'other content')\n            ]\n          })\n        }\n      }\n    })\n  ```\n  In this example, we create a component `Hello` which needs to be invoked in api form and we invoke it in another component.The focus is what `showHello()` does: invoking method `this.$createHello(config, renderFn)` to instantiate `Hello`.\n\n### How to use in general JS files or use it in global\n\nIn vue component, you can call by `this.$createHello(config, renderFn)` because the `this` is just a Vue instance. But in general JS files, you need to use `Hello.$create`. As shown below:\n\n```js\nimport Vue from 'vue'\nimport Hello from './Hello.vue'\nimport CreateAPI from 'vue-create-api'\nVue.use(CreateAPI)\n\n// create this.$createHello and Hello.create API\nVue.createAPI(Hello, true)\n\nHello.$create(config, renderFn)\n```\n\nNotice, when we use in general JS files, we can't make props be reactive.\n\n### batchDestroy\n\nWe can use the `batchDestroy` method provided by `vue-create-api` to destroy all instances uniformly. For example, we can destroy them uniformly when the route is switched:\n\n```js\nimport Vue from 'vue'\nimport VueRouter from 'vue-router'\nimport CreateAPI from 'vue-create-api'\n\nVue.use(VueRouter)\n\nconst router = new VueRouter({ routes: [] })\nrouter.afterEach(() =\u003e {\n  CreateAPI.batchDestroy()\n})\n```\n\n`batchDestroy` can receive a filter function to determine which instances need to be destroyed:\n\n```js\nCreateAPI.batchDestroy(instances =\u003e instances.filter(ins =\u003e ins))\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcube-ui%2Fvue-create-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcube-ui%2Fvue-create-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcube-ui%2Fvue-create-api/lists"}