Skip to content

Commit 07be9d7

Browse files
pikaxantfu
andauthoredSep 12, 2020
feat: allow plugin to be installed in localVue (#497)
* feat: allow plugin to be installed in localVue * chore: fix tests * chore: cr fixes * chore: fix tests and copy version * Update test/use.spec.ts Co-authored-by: Anthony Fu <[email protected]> * Update test/use.spec.ts Co-authored-by: Anthony Fu <[email protected]> * chore: fix ts Co-authored-by: Anthony Fu <[email protected]>
1 parent 255dc72 commit 07be9d7

File tree

4 files changed

+81
-10
lines changed

4 files changed

+81
-10
lines changed
 

‎src/install.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import type { VueConstructor } from 'vue'
22
import { AnyObject } from './types/basic'
3-
import { hasSymbol, hasOwn, isPlainObject, assert } from './utils'
3+
import { hasSymbol, hasOwn, isPlainObject, assert, warn } from './utils'
44
import { isRef, markReactive } from './reactivity'
5-
import {
6-
setVueConstructor,
7-
isVueRegistered,
8-
isPluginInstalled,
9-
} from './runtimeContext'
5+
import { setVueConstructor, isVueRegistered } from './runtimeContext'
106
import { mixin } from './mixin'
117

128
/**
@@ -44,7 +40,7 @@ function mergeData(from: AnyObject, to: AnyObject): Object {
4440
}
4541

4642
export function install(Vue: VueConstructor) {
47-
if (isPluginInstalled() || isVueRegistered(Vue)) {
43+
if (isVueRegistered(Vue)) {
4844
if (__DEV__) {
4945
assert(
5046
false,
@@ -55,8 +51,12 @@ export function install(Vue: VueConstructor) {
5551
}
5652

5753
if (__DEV__) {
58-
if (Vue.version[0] !== '2' || Vue.version[1] !== '.') {
59-
assert(false, `only works with Vue 2, v${Vue.version} found.`)
54+
if (Vue.version) {
55+
if (Vue.version[0] !== '2' || Vue.version[1] !== '.') {
56+
assert(false, `only works with Vue 2, v${Vue.version} found.`)
57+
}
58+
} else {
59+
warn('Vue version not found')
6060
}
6161
}
6262

‎src/runtimeContext.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { VueConstructor } from 'vue'
22
import { ComponentInstance } from './component'
3-
import { assert, hasOwn } from './utils'
3+
import { assert, hasOwn, warn } from './utils'
44

55
let vueConstructor: VueConstructor | null = null
66
let currentInstance: ComponentInstance | null = null
@@ -27,6 +27,9 @@ export function getVueConstructor(): VueConstructor {
2727
}
2828

2929
export function setVueConstructor(Vue: VueConstructor) {
30+
if (__DEV__ && vueConstructor) {
31+
warn('Another instance of vue installed')
32+
}
3033
vueConstructor = Vue
3134
Object.defineProperty(Vue, PluginInstalledFlag, {
3235
configurable: true,

‎test/helpers/create-local-vue.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Vue, { VueConstructor } from 'vue'
2+
3+
// based on https://github.com/vuejs/vue-test-utils/blob/dev/packages/test-utils/src/create-local-vue.js
4+
5+
export function createLocalVue(_Vue: VueConstructor = Vue) {
6+
const instance = _Vue.extend()
7+
8+
Object.keys(_Vue).forEach((key) => {
9+
// @ts-ignore
10+
instance[key] = _Vue[key]
11+
})
12+
13+
// @ts-ignore
14+
if (instance._installedPlugins && instance._installedPlugins.length) {
15+
// @ts-ignore
16+
instance._installedPlugins.length = 0
17+
}
18+
19+
instance.config = _Vue.config
20+
21+
const use = instance.use
22+
//@ts-ignore
23+
instance.use = (plugin, ...rest) => {
24+
if (plugin.installed === true) {
25+
plugin.installed = false
26+
}
27+
if (plugin.install && plugin.install.installed === true) {
28+
plugin.install.installed = false
29+
}
30+
use.call(instance, plugin, ...rest)
31+
}
32+
return instance
33+
}

‎test/use.spec.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import CompositionApi from '../src'
2+
import { createLocalVue } from './helpers/create-local-vue'
3+
import { mockWarn } from './helpers'
4+
5+
describe('use', () => {
6+
mockWarn(true)
7+
8+
it('should allow install in multiple vue', () => {
9+
const localVueOne = createLocalVue()
10+
localVueOne.use(CompositionApi)
11+
12+
const localVueTwo = createLocalVue()
13+
localVueTwo.use(CompositionApi)
14+
15+
expect('Another instance of vue installed').toHaveBeenWarned()
16+
})
17+
18+
it('should warn installing multiple times', () => {
19+
const localVueOne = createLocalVue()
20+
localVueOne.use(CompositionApi)
21+
22+
expect(() => {
23+
// vue prevents the same plugin of being installed, this will create a new plugin instance
24+
localVueOne.use({
25+
install(v) {
26+
CompositionApi.install(v)
27+
},
28+
})
29+
}).toThrowError(
30+
'already installed. Vue.use(VueCompositionAPI) should be called only once.'
31+
)
32+
33+
expect('Another instance of vue installed').toHaveBeenWarned()
34+
})
35+
})

0 commit comments

Comments
 (0)
Please sign in to comment.