vue-create-api
A Vue plugin which make Vue component invocated by API.
Installing
use npm
$ npm install vue-create-apiuse cdn
<script src="https://unpkg.com/vue-create-api/dist/vue-create-api.min.js"></script>Usage
import CreateAPI from 'vue-create-api'
Vue.use(CreateAPI)
// or with options.
Vue.use(CreateAPI, {
componentPrefix: 'cube-'
apiPrefix: '$create-'
})
// then the Vue constructor will have the createAPI function.
import Dialog from './components/dialog.vue'
// make Dialog component invocated by API.
Vue.createAPI(Dialog, true)
// use in general JS files.
// however, the $props can not be reactive.
Dialog.$create({
$props: {
title: 'Hello',
content: 'I am from pure JS'
}
}).show()
// use in a vue component.
this.$createDialog({
$props: {
title: 'Hello',
content: 'I am from a vue component'
},
}).show()// typescript
import CreateAPI from 'vue-create-api'
Vue.use(CreateAPI)
Vue.createAPI(Dialog, events, single)
this.$createDialog({
$props: {
title: 'Hello',
content: 'I am from a vue component'
}
}).show()// d.ts
import Vue, { VueConstructor } from 'vue'
import { createFunction } from 'vue-create-api';
export declare class UIComponent extends Vue {
show ():void
hide ():void
}
declare module 'vue/types/vue' {
interface Vue {
/** create Dialog instance */
$createDialog: createFunction<UIComponent>
}
}Tip
using typescript,
terser-webpack-plugin(vue-cli3.x) oruglifyjs(vue-cli2.x) adds{ keep_fnames: true }
Constructor Options
| key | description | default |
|---|---|---|
componentPrefix |
the prefix name of your component | - |
apiPrefix |
the api prefix | $create |
Methods
Vue.createAPI(Component, [single])
Parameters:
{Function | Object} ComponentVue component which must containsname{Boolean} [single]whether singleton
Usage:
This method will add a method which is named
$create{camelize(Component.name)}to Vue's prototype, so you can instantiate the Vue component byconst instance = this.$createAaBb(config, [renderFn, single])in other components. The instantiated component's template content will be attached tobodyelement.const instance = this.$createAaBb(config, renderFn, single)Parameters:
| Attribute | Description | Type | Accepted Values | Default | | - | - | - | - | - | | config | Config options | Object | {} | - | | renderFn | Optional, used to generate the VNode child node in the slot scene in general | Function | - | function (createElement) {...} | | 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 thesinglevalue is the sencond parameter's value. | Boolean | true/false | single in createAPI() |Config options
config:You can set
$propsand$eventsinconfig,$propssupported reactive properties, these props will be watched.| Attribute | Description | Type | Accepted Values | Default | | - | - | - | - | - | | $props | Component props | Object | - | {
title: 'title',
content: 'my content',
open: false
} | | $events | Component event handlers | Object | - | {
click: 'clickHandler',
select: this.selectHandler
} |$propsexample,{ [key]: [propKey] }:{ title: 'title', content: 'my content', open: false }title,contentandopenare keys of the component prop or data, and the prop' value will be taken by the following steps:- If
propKeyis not a string value, then usepropKeyas the prop value. - If
propKeyis a string value and the caller instance dont have thepropKeyproperty, then usepropKeyas the prop value. - If
propKeyis a string value and the caller instance have thepropKeyproperty, then use the caller'spropKeyproperty value as the prop value. And the prop value will be reactive.
$eventsexample,{ [eventName]: [eventValue] }:{ click: 'clickHandler', select: this.selectHandler }clickandselectare event names, and the event handlers will be taken by the following steps:- If
eventValueis not a string value, then useeventValueas the event handler. - If
eventValueis a string value, then use the caller'seventValueproperty value as the event handler.
You can set all avaliable properties in Vue, but you need to add prefix
$, eg:this.$createAaBb({ $attrs: { id: 'id' }, $class: { 'my-class': true } })The Returned value
instance:instanceis a instantiated Vue component.And the
removemethod will be attached to this instance.You can invoke the
removemethod to destroy the component and detach the component's content frombodyelement.If the caller is destroyed and the
instancewill be automatically destroyed.- If
Example:
First we create Hello.vue component:
<template> <div @click="clickHandler"> {{content}} <slot name="other"></slot> </div> </template> <script type="text/ecmascript-6"> export default { name: 'hello', props: { content: { type: String, default: 'Hello' } }, methods: { clickHandler(e) { this.$emit('click', e) } } } </script>Then we make Hello.vue as an API style component by calling the
createAPImethod.import Vue from 'vue' import Hello from './Hello.vue' import CreateAPI from 'vue-create-api' Vue.use(CreateAPI) // create this.$createHello API Vue.createAPI(Hello, true) // init Vue new Vue({ el: '#app', render: function (h) { return h('button', { on: { click: this.showHello } }, ['Show Hello']) }, methods: { showHello() { const instance = this.$createHello({ $props: { content: 'My Hello Content', }, $events: { click() { console.log('Hello component clicked.') instance.remove() } } }, /* renderFn */ (createElement) => { return [ createElement('p', { slot: 'other' }, 'other content') ] }) } } })In this example, we create a component
Hellowhich needs to be invoked in api form and we invoke it in another component.The focus is whatshowHello()does: invoking methodthis.$createHello(config, renderFn)to instantiateHello.
How to use in general JS files or use it in global
In 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:
import Vue from 'vue'
import Hello from './Hello.vue'
import CreateAPI from 'vue-create-api'
Vue.use(CreateAPI)
// create this.$createHello and Hello.create API
Vue.createAPI(Hello, true)
Hello.$create(config, renderFn)Notice, when we use in general JS files, we can't make props be reactive.
batchDestroy
We 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:
import Vue from 'vue'
import VueRouter from 'vue-router'
import CreateAPI from 'vue-create-api'
Vue.use(VueRouter)
const router = new VueRouter({ routes: [] })
router.afterEach(() => {
CreateAPI.batchDestroy()
})batchDestroy can receive a filter function to determine which instances need to be destroyed:
CreateAPI.batchDestroy(instances => instances.filter(ins => ins))