Skip to content

Commit 75d55c9

Browse files
committed
Add support for Vue 3
1 parent 1828500 commit 75d55c9

File tree

4 files changed

+135
-695
lines changed

4 files changed

+135
-695
lines changed

build/rollup.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ const umd = {
5252
},
5353
}),
5454
commonjs(),
55-
buble(),
55+
buble({
56+
// @see https://github.com/vuejs/vue-hackernews-2.0/issues/87
57+
objectAssign: 'Object.assign',
58+
}),
5659
],
5760
}
5861

package.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-class-store",
33
"description": "Universal Vue stores you write once and use anywhere",
4-
"version": "2.0.3",
4+
"version": "3.0.0",
55
"author": "Dave Stewart",
66
"license": "MIT",
77
"main": "dist/vue-class-store.js",
@@ -17,11 +17,10 @@
1717
"scripts": {
1818
"dev": "rollup -c build/rollup.js -w",
1919
"build": "rollup -c build/rollup.js",
20-
"stats": "node dev/stats.js",
2120
"test": "echo \"Error: no test specified\" && exit 1"
2221
},
2322
"peerDependencies": {
24-
"vue": "^2.6.11"
23+
"vue": "^3.0.0-beta.14"
2524
},
2625
"devDependencies": {
2726
"@babel/plugin-proposal-decorators": "^7.8.3",
@@ -37,7 +36,7 @@
3736
"rollup-plugin-vue": "^5.1.7",
3837
"tslib": "^2.0.0",
3938
"typescript": "^3.9.2",
40-
"vue": "^2.6.11",
39+
"vue": "^3.0.0-beta.14",
4140
"vue-template-compiler": "^2.6.11"
4241
},
4342
"keywords": [

src/index.ts

+55-40
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Vue, { ComponentOptions, VueConstructor } from 'vue'
1+
import { computed, reactive, watch } from 'vue'
22

33
type C = { new (...args: any[]): {} }
44

@@ -14,69 +14,84 @@ function getDescriptors (model: R) {
1414
return { ...prototypeDescriptors, ...descriptors }
1515
}
1616

17-
export function makeOptions(model: R): ComponentOptions<any> {
18-
// prototype
19-
const prototype = Object.getPrototypeOf(model)
20-
const descriptors = getDescriptors(prototype)
17+
function getValue (value: Record<any, any>, path: string | string[]) {
18+
const segments = typeof path === 'string'
19+
? path.split('.')
20+
: path
21+
const segment: string | undefined = segments.shift()
22+
return segment
23+
? getValue(value[segment], segments)
24+
: value
25+
}
26+
27+
export function makeReactive (model) {
28+
// properties
29+
const descriptors = getDescriptors(model)
2130

2231
// options
23-
const name = prototype.constructor.name
24-
const data: R = {}
25-
const computed: R = {}
26-
const methods: R = {}
27-
const watch: R = {}
32+
const data = {}
33+
const watched = {}
2834

2935
// data, string watches
30-
Object.keys(model).forEach(key => {
36+
Object.keys(model).forEach((key: string) => {
3137
const value = model[key]
3238
if (key.startsWith('on:')) {
33-
watch[key.substring(3)] = value
39+
watched[key.substring(3)] = value
3440
}
3541
else {
3642
data[key] = value
3743
}
3844
})
3945

4046
// function watches, methods, computed
41-
Object.keys(descriptors).forEach(key => {
42-
if (key !== 'constructor' && !key.startsWith('__')) {
43-
const { value, get, set } = descriptors[key]
44-
if (key.startsWith('on:')) {
45-
watch[key.substring(3)] = value
46-
}
47-
else if (value) {
48-
methods[key] = value
49-
}
50-
else if (get && set) {
51-
computed[key] = { get, set }
52-
}
53-
else if (get) {
54-
computed[key] = get
47+
const state = reactive({
48+
...data,
49+
...Object.keys(descriptors).reduce((output, key) => {
50+
if (key !== 'constructor' && !key.startsWith('__')) {
51+
const { value, get, set } = descriptors[key]
52+
// watch
53+
if (key.startsWith('on:')) {
54+
watched[key.substring(3)] = value
55+
}
56+
// method
57+
else if (value) {
58+
output[key] = (...args) => value.call(state, ...args)
59+
}
60+
// computed
61+
else if (get && set) {
62+
output[key] = computed({
63+
set: (value) => set.call(state, value),
64+
get: () => get.call(state),
65+
})
66+
}
67+
else if (get) {
68+
output[key] = computed(() => get.call(state))
69+
}
5570
}
71+
return output
72+
}, {}),
73+
})
74+
75+
// set up watches
76+
Object.keys(watched).forEach(key => {
77+
const callback: Function = typeof watched[key] === 'string'
78+
? model[getValue(model, 'on:' + key)]
79+
: watched[key]
80+
if (typeof callback === 'function') {
81+
watch(() => getValue(state, key), callback.bind(state))
5682
}
5783
})
5884

5985
// return
60-
return {
61-
name,
62-
computed,
63-
methods,
64-
watch,
65-
data,
66-
}
67-
}
68-
69-
export function makeVue<T extends R> (model: T): T {
70-
const options = makeOptions(model)
71-
return (new Vue(options) as unknown) as T
86+
return state
7287
}
7388

7489
export default function VueStore<T extends C> (constructor: T): T {
7590
function construct (...args: any[]) {
7691
const instance = new (constructor as C)(...args)
77-
return makeVue(instance)
92+
return makeReactive(instance)
7893
}
7994
return (construct as unknown) as T
8095
}
8196

82-
VueStore.create = makeVue
97+
VueStore.create = makeReactive

0 commit comments

Comments
 (0)