├── .browserslistrc ├── src ├── ts │ ├── artist.ts │ └── track.ts ├── main.ts ├── shims-vue.d.ts ├── composables │ ├── use-tracks.ts │ └── use-artists.ts ├── utils │ └── api.ts └── App.vue ├── public ├── logo.png ├── favicon.ico └── index.html ├── .editorconfig ├── .gitignore ├── README.md ├── .eslintrc.js ├── tsconfig.json └── package.json /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /src/ts/artist.ts: -------------------------------------------------------------------------------- 1 | export interface Artist { 2 | name: string; 3 | imageUrl: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import App from './App.vue'; 3 | 4 | createApp(App).mount('#app'); 5 | -------------------------------------------------------------------------------- /src/ts/track.ts: -------------------------------------------------------------------------------- 1 | export interface Track { 2 | name: string; 3 | artistName: string; 4 | imageUrl: string; 5 | } 6 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/takeit-agency/vue3-class-component-composition-api-example/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/takeit-agency/vue3-class-component-composition-api-example/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue'; 3 | 4 | const component: DefineComponent; 5 | export default component; 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,ts,tsx,vue}] 2 | indent_style = space 3 | indent_size = 2 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | max_line_length = 100 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue3-class-component-composition-api-example 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | '@vue/airbnb', 9 | '@vue/typescript/recommended', 10 | ], 11 | parserOptions: { 12 | ecmaVersion: 2020, 13 | }, 14 | rules: { 15 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 16 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 17 | 'import/prefer-default-export': 'off', 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /src/composables/use-tracks.ts: -------------------------------------------------------------------------------- 1 | import { reactive, computed } from 'vue'; 2 | import { Track } from '@/ts/track'; 3 | import { loadTracks } from '@/utils/api'; 4 | 5 | interface State { 6 | list: Track[]; 7 | } 8 | 9 | export function useTracks() { 10 | const state: State = reactive({ 11 | list: [], 12 | listLength: computed(() => state.list.length), 13 | }); 14 | 15 | async function get() { 16 | state.list = await loadTracks(); 17 | } 18 | 19 | return { 20 | state, 21 | get, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /src/composables/use-artists.ts: -------------------------------------------------------------------------------- 1 | import { reactive, computed } from 'vue'; 2 | import { loadArtists } from '@/utils/api'; 3 | import { Artist } from '@/ts/artist'; 4 | 5 | interface State { 6 | list: Artist[]; 7 | } 8 | 9 | export function useArtists() { 10 | const state: State = reactive({ 11 | list: [], 12 | listLength: computed(() => state.list.length), 13 | }); 14 | 15 | async function get() { 16 | state.list = await loadArtists(); 17 | } 18 | 19 | return { 20 | state, 21 | get, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "sourceMap": true, 14 | "baseUrl": ".", 15 | "types": [ 16 | "webpack-env" 17 | ], 18 | "paths": { 19 | "@/*": [ 20 | "src/*" 21 | ] 22 | }, 23 | "lib": [ 24 | "esnext", 25 | "dom", 26 | "dom.iterable", 27 | "scripthost" 28 | ] 29 | }, 30 | "include": [ 31 | "src/**/*.ts", 32 | "src/**/*.tsx", 33 | "src/**/*.vue", 34 | "tests/**/*.ts", 35 | "tests/**/*.tsx" 36 | ], 37 | "exclude": [ 38 | "node_modules" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-class-component-composition-api-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "@vue/composition-api": "^1.0.0-beta.15", 12 | "vue": "^3.0.0", 13 | "vue-class-component": "^8.0.0-0" 14 | }, 15 | "devDependencies": { 16 | "@typescript-eslint/eslint-plugin": "^2.33.0", 17 | "@typescript-eslint/parser": "^2.33.0", 18 | "@vue/cli-plugin-eslint": "~4.5.0", 19 | "@vue/cli-plugin-typescript": "~4.5.0", 20 | "@vue/cli-service": "~4.5.0", 21 | "@vue/compiler-sfc": "^3.0.0", 22 | "@vue/eslint-config-airbnb": "^5.0.2", 23 | "@vue/eslint-config-typescript": "^5.0.2", 24 | "eslint": "^6.7.2", 25 | "eslint-plugin-import": "^2.20.2", 26 | "eslint-plugin-vue": "^7.0.0-0", 27 | "typescript": "~3.9.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/utils/api.ts: -------------------------------------------------------------------------------- 1 | import { Artist } from '@/ts/artist'; 2 | import { Track } from '@/ts/track'; 3 | 4 | const mockArtist: Artist[] = [ 5 | { 6 | name: 'The Rolling Stones', 7 | imageUrl: 'https://i.scdn.co/image/85d9cb252ab4d8410d31820be40214c59f2597a1', 8 | }, 9 | { 10 | name: 'The Beatles', 11 | imageUrl: 'https://i.scdn.co/image/6b2a709752ef9c7aaf0d270344157f6cd2e0f1a7', 12 | }, 13 | { 14 | name: 'Steely Dan', 15 | imageUrl: 'https://i.scdn.co/image/9d01e4e9aac39b891d684d3d1a5b3a451d7c72bd', 16 | }, 17 | ]; 18 | 19 | const mocktracks: Track[] = [ 20 | { 21 | name: 'Midnight Blue', 22 | artistName: 'Kenny Burrell', 23 | imageUrl: 'https://i.scdn.co/image/ab67616d0000b273337b64d3c252d562a33e4d35', 24 | }, 25 | { 26 | name: 'Gimme Shelter', 27 | artistName: 'The Rolling Stones', 28 | imageUrl: 'https://i.scdn.co/image/ab67616d0000b2732af30c881bb23cfb82a8cf99', 29 | }, 30 | { 31 | name: 'Teen Town', 32 | artistName: 'Weather Report', 33 | imageUrl: 'https://i.scdn.co/image/ab67616d0000b273dc676a8b0a1ad6284b6996f9', 34 | }, 35 | ]; 36 | 37 | export function loadArtists(): Promise { 38 | return new Promise((resolve) => resolve(mockArtist)); 39 | } 40 | 41 | export function loadTracks(): Promise { 42 | return new Promise((resolve) => resolve(mocktracks)); 43 | } 44 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 66 | 67 | 115 | --------------------------------------------------------------------------------