├── .coveralls.yml
├── .github
└── workflows
│ └── node.js.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.js
├── CHANGELOG.md
├── LICENSE
├── README.md
├── docs
└── compare.png
├── examples
├── vite-vue2
│ ├── .gitignore
│ ├── .vscode
│ │ └── extensions.json
│ ├── README.md
│ ├── index.html
│ ├── package.json
│ ├── public
│ │ └── vite.svg
│ ├── src
│ │ ├── App.vue
│ │ ├── assets
│ │ │ └── vue.svg
│ │ ├── components
│ │ │ └── HelloWorld.vue
│ │ ├── main.ts
│ │ ├── style.css
│ │ └── vite-env.d.ts
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
└── vite-vue3
│ ├── .gitignore
│ ├── .vscode
│ └── extensions.json
│ ├── README.md
│ ├── index.html
│ ├── package.json
│ ├── public
│ └── vite.svg
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── vue.svg
│ ├── components
│ │ ├── class-setup.vue
│ │ └── native.vue
│ ├── main.ts
│ ├── style.css
│ └── vite-env.d.ts
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── index.html
├── package.json
├── script
├── build-docs.ts
├── release.sh
└── test-all.sh
├── src
├── computed.ts
├── config.ts
├── context.ts
├── define.ts
├── index.ts
├── options.ts
├── pass-on-to.ts
├── property-descriptors.ts
├── setup-reference.ts
├── setup.ts
├── types.ts
├── vue.ts
└── watch.ts
├── tests
├── base-component-child.vue
├── base-component.spec.ts
├── base-component.vue
├── base.spec.ts
├── base.vue
├── boolean-props.spec.ts
├── boolean-props.vue
├── context.spec.ts
├── demo.spec.ts
├── demo.vue
├── extend-options.spec.ts
├── extend-options.vue
├── extend.spec.ts
├── extend.vue
├── kebab-case-props-child.vue
├── kebab-case-props-parent.vue
├── kebab-case-props.spec.ts
├── make-up.spec.ts
├── make-up.vue
├── multiple-pass-on-to.spec.ts
├── multiple-pass-on-to.vue
├── options.spec.ts
├── props-bind-child.vue
├── props-bind-parent.vue
├── props-bind.spec.ts
├── props-child.vue
├── props-parent.vue
├── props.spec.ts
├── quick-start.spec.ts
├── quick-start.vue
├── register-hook.spec.ts
├── set-value.spec.ts
├── set-value.vue
├── use.spec.ts
├── use.vue
├── vue.spec.ts
├── watch-computed.spec.ts
├── watch-computed.vue
├── watch-effect.spec.ts
├── watch-effect.vue
├── watch.spec.ts
└── watch.vue
├── tsconfig.json
└── vite.config.ts
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | service_name: travis-pro
2 | repo_token: zaQVFPoDNH8C69eCILMzPzi9qhZEm1Dws
3 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: CI
5 |
6 | on:
7 | push:
8 | branches: ['main']
9 | pull_request:
10 | branches: ['main']
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | strategy:
17 | matrix:
18 | node-version: [16.x]
19 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
20 |
21 | steps:
22 | - uses: actions/checkout@v3
23 | - name: Use Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v3
25 | # with:
26 | # node-version: ${{ matrix.node-version }}
27 | # cache: 'npm'
28 | - run: yarn test:all
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | node_modules_back/
43 | jspm_packages/
44 |
45 | # TypeScript v1 declaration files
46 | typings/
47 |
48 | # TypeScript cache
49 | *.tsbuildinfo
50 |
51 | # Optional npm cache directory
52 | .npm
53 |
54 | # Optional eslint cache
55 | .eslintcache
56 |
57 | # Microbundle cache
58 | .rpt2_cache/
59 | .rts2_cache_cjs/
60 | .rts2_cache_es/
61 | .rts2_cache_umd/
62 |
63 | # Optional REPL history
64 | .node_repl_history
65 |
66 | # Output of 'npm pack'
67 | *.tgz
68 |
69 | # Yarn Integrity file
70 | .yarn-integrity
71 |
72 | # dotenv environment variables file
73 | .env
74 | .env.test
75 |
76 | # parcel-bundler cache (https://parceljs.org/)
77 | .cache
78 |
79 | # Next.js build output
80 | .next
81 |
82 | # Nuxt.js build / generate output
83 | .nuxt
84 | dist
85 |
86 | # Gatsby files
87 | .cache/
88 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
89 | # https://nextjs.org/blog/next-9-1#public-directory-support
90 | # public
91 |
92 | # vuepress build output
93 | .vuepress/dist
94 |
95 | # Serverless directories
96 | .serverless/
97 |
98 | # FuseBox cache
99 | .fusebox/
100 |
101 | # DynamoDB Local files
102 | .dynamodb/
103 |
104 | # TernJS port file
105 | .tern-port
106 | yarn.lock
107 | .DS_Store
108 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | coverage
2 | dist
3 | node_modules
4 | node_modules_back
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | trailingComma: 'es5',
3 | tabWidth: 4,
4 | semi: true,
5 | singleQuote: true,
6 | };
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.4.4
2 |
3 | - fix: multiple inheritance unbinding object errors
4 |
5 | ## 1.4.3
6 |
7 | - fix: memory leak caused by unused `@Setup` decorator
8 |
9 | ## 1.4.2
10 |
11 | - fix: Type failure
12 |
13 | ## 1.4.1
14 |
15 | - fix: Type failure
16 |
17 | ## 1.4.0
18 |
19 | - fix: Type failure
20 |
21 | ## 1.3.9
22 |
23 | - fix: Type failure
24 |
25 | ## 1.3.8
26 |
27 | - types: fix `DeepReadonly` to `Readonly`
28 |
29 | ## 1.3.7
30 |
31 | - types: fix `VueInstance` type error
32 |
33 | ## 1.3.6
34 |
35 | - types: fix `VueInstance` type error
36 |
37 | ## 1.3.5
38 |
39 | - docs: modify README.md
40 |
41 | ## 1.3.4
42 |
43 | - docs: modify README.md
44 |
45 | ## 1.3.3
46 |
47 | - fix: Vue3 SSR default error
48 |
49 | ## 1.3.0
50 |
51 | - Same as `1.2.9`
52 |
53 | ## 1.2.9
54 |
55 | - feat: `Context` Support props and emit generics
56 |
57 | ## 1.2.8
58 |
59 | - fix: `$vm` return Vue instance on Vue2
60 |
61 | ## 1.2.7
62 |
63 | - chore: Update keywords
64 |
65 | ## 1.2.6
66 |
67 | - fix: Vue3 optimization set default props
68 |
69 | ## 1.2.5
70 |
71 | - fix: Default Boolean value error
72 |
73 | ## 1.2.4
74 |
75 | - feat: `DefaultProps` and `DefaultEmit` exports
76 |
77 | ## 1.2.3
78 |
79 | - fix: props default value error on Vue3
80 |
81 | ## 1.2.2
82 |
83 | - fix: `@PassOnTo(onServerPrefetch)` type error on Vue2
84 |
85 | ## 1.2.1
86 |
87 | - feat: App.use
88 |
89 | ## 1.2.0
90 |
91 | - fix: Set default props error on Vue2
92 |
93 | ## 1.1.9
94 |
95 | - fix: props name style is kebab case type error
96 | - fix: not found: Error: Can't resolve 'vue-class-setup'
97 |
98 | ## 1.1.8
99 |
100 | - fix: Set props default error
101 |
102 | ## 1.1.7
103 |
104 | - docs: Optimize document picture capitalization
105 |
106 | ## 1.1.6
107 |
108 | - fix: Improve unit testing and boundary treatment
109 |
110 | ## 1.1.5
111 |
112 | - feat: Inject to defineComponent and bind this
113 |
114 | ## 1.1.3
115 |
116 | - fix: Vite ssr build error
117 |
118 | ## 1.1.2
119 |
120 | - fix: Vite ssr build error
121 |
122 | ## 1.1.1
123 |
124 | - feat: Watch decorator
125 |
126 | ## 1.1.0
127 |
128 | - Fix: Assemble class cannot be used
129 |
130 | ## 1.0.8
131 |
132 | - feat: Set default props on class
133 |
134 | ## 1.0.7
135 |
136 | - feat: isVue2, isVue3, getCurrentInstance, VueInstance
137 |
138 | ## 1.0.6
139 |
140 | - fix: Define Generic (optional)
141 |
142 | ## 1.0.5
143 |
144 | - feat: $props
145 | - Remove: Remove parameter passing in
146 |
147 | ## 1.0.4
148 |
149 | - feat: Remove execution
150 |
151 | ## 1.0.3
152 |
153 | - feat: Define basic class
154 |
155 | ## 1.0.2
156 |
157 | - feat: packages.json "exports"
158 |
159 | ## 1.0.1
160 |
161 | - fix: Delete unnecessary judgment
162 |
163 | ## 1.0.0
164 |
165 | - feat: Remove `Hook` and add `PassOnTo`
166 | - feat: `getCurrentHookContext` method
167 |
168 | ## 0.1.4
169 |
170 | - fix: Export path error
171 |
172 | ## 0.1.3
173 |
174 | - fix: Initialization hook sequence error
175 |
176 | ## 0.0.9
177 |
178 | - feat: `registerHook` api
179 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Followme Frontend Team
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-class-setup
2 |
3 | Use class style to write setup and support vue2 and vue3
4 |
5 | [](https://github.com/fmfe/vue-class-setup/actions)
6 |
7 | [](https://www.npmjs.com/package/vue-class-setup)
8 | [](https://www.npmjs.com/package/vue-class-setup)
9 | [](https://www.npmjs.com/package/vue-class-setup)
10 |
11 | ## Why?
12 |
13 | Using class can help you avoid `ref`, `reactive` , `computed` and `withDefaults`, and significantly reduce your mental burden and better organize your code. It supports vue2 and vue3 at the same time. After gzip compression, it is only 1KB
14 |
15 | ## vue-class-component vs vue-class-setup
16 |
17 | **We should deprecate [vue-class-component](https://github.com/vuejs/vue-class-component/issues/569), and use class in setup**
18 | | List | vue-class-component | vue-class-setup |
19 | | --- | --- | ----------- |
20 | | Vue2 | ✅ | ✅ |
21 | | Vue3 | ❌ | ✅ |
22 | | Method bind this | ✅ | ✅ |
23 | | Props type check | ❌ | ✅ |
24 | | Emit type check | ❌ | ✅ |
25 | | Watch type check | ❌ | ✅ |
26 | | Multiple class instances | ❌ | ✅ |
27 | | Class attribute sets the default value of the prop | ❌ | ✅ |
28 |
29 | ## Install
30 |
31 | ```bash
32 | npm install vue-class-setup
33 | # or
34 | yarn add vue-class-setup
35 | ```
36 |
37 | ## Quick start
38 |
39 |
40 |
41 | ```vue
42 |
65 |
66 |
67 |
{{ text }}
68 |
69 |
70 |
71 | ```
72 |
73 |
74 |
75 | `Setup` and `Context` collect dependency information together, and convert it into a Vue program after executing the subclass constructor
76 |
77 | ## Setup
78 |
79 | If the component defines `props`, writing the `class` in the `setup` will cause the `setup` function to create a `class` every time as it executes, which will add costs. So we should avoid writing `class` in `setup` and use `Define` basic class to receive `props` and `emit`.
80 |
81 | ### Context and Define
82 |
83 | `Context` automatic injection `$vm`, `Define` extend from `Context`, and `Define` will automatically inject `$props` and `$emit`, when encapsulating public classes, you may not want to inject props and emit
84 |
85 | ### Best practices
86 |
87 |
88 |
89 | ```vue
90 |
122 |
148 |
149 |
154 |
155 | ```
156 |
157 |
158 |
159 | ### Multiple class instances
160 |
161 | When the business is complex, multiple instances should be split
162 |
163 |
164 |
165 | ```vue
166 |
211 |
215 |
216 |
{{ left.text }}
217 |
{{ right.text }}
218 |
219 | ```
220 |
221 |
222 |
223 | ### PassOnTo
224 |
225 | This `callback` will be called back after the `Test class` instantiation is completed, and the decorated function will be passed in, and the TS can check whether the type is correct
226 |
227 | ```ts
228 | @Setup
229 | class App extends Define {
230 | @PassOnTo(myFunc)
231 | public init(name: string) {}
232 | }
233 |
234 | function myFunc(callback: (name: string) => void) {
235 | // ...
236 | }
237 | ```
238 |
239 | If `PassOnTo` does not pass in a handler, it is called after `reactive` and `computed` execution are completed, You should avoid watching in the `constructor` because it may not have `reactive`
240 |
241 | ```ts
242 | import { Watch } from 'vue';
243 |
244 | @Setup
245 | class App extends Define {
246 | public value = 0;
247 | @PassOnTo()
248 | private setup() {
249 | // You can safely watch, but it is recommended to use the Watch decorator
250 | watch(
251 | () => this.value,
252 | (value) => {
253 | // ...
254 | }
255 | );
256 | }
257 | }
258 | ```
259 |
260 | ### Watch
261 |
262 | It can correctly identify the type
263 |
264 |
265 |
266 | ```vue
267 |
293 |
296 |
297 |