Quasar - ynjch97/YNJCH_WIKI GitHub Wiki

1. QUASAR μ„€μΉ˜

C:\Users\YNJCH>node -v
v14.16.1
  • νŒ¨ν‚€μ§€ 관리 도ꡬ 지원 : Yarn v1 (strongly recommended), PNPM, NPM or Bun
  • NPM 을 μ‚¬μš©ν•˜κΈ°λ‘œ ν•˜μ—¬ μ•„λž˜ λͺ…λ Ήμ–΄ μ‹€ν–‰
npm i -g @quasar/cli
npm init quasar
  • Node.js v14.16.1 μ—μ„œ warning λ°œμƒν•˜μ—¬, v16.14.1 μ„€μΉ˜ν•˜μ˜€μŒ
    • https://nodejs.org/dist/v16.14.1/ μ—μ„œ node-v16.14.1-x64.msi λ‹€μš΄λ‘œλ“œ
    • λͺ…λ Ή ν”„λ‘¬ν”„νŠΈμ—μ„œ μ„€μΉ˜ 버전 확인 : node -v
C:\Users\YNJCH>npm i -g @quasar/cli

added 228 packages, and audited 229 packages in 12s

77 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 8.5.0 -> 10.4.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.4.0
npm notice Run npm install -g [email protected] to update!
npm notice
  • μ•„λž˜μ™€ 같이 μ„€μ •ν•˜μ—¬ λͺ…λ Ήμ–΄ μ‹€ν–‰
    • Project folder λͺ… μ§€μ •
    • Quasar version : Quasar v2 (Vue 3 | latest and greatest)
    • Pick script type : Javascript
    • Pick Quasar App CLI variant : Β» Quasar App CLI with Vite 2 (stable | v1)
    • Pick your CSS preprocessor : Β» Sass with SCSS syntax
    • Check the features needed for your project : Β» ESLint
    • Pick an ESLint preset : Β» Prettier
C:\Users\YNJCH>npm init quasar
Need to install the following packages:
  create-quasar
Ok to proceed? (y) y


 .d88888b.
d88P" "Y88b
888     888
888     888 888  888  8888b.  .d8888b   8888b.  888d888
888     888 888  888     "88b 88K          "88b 888P"
888 Y8b 888 888  888 .d888888 "Y8888b. .d888888 888
Y88b.Y8b88P Y88b 888 888  888      X88 888  888 888
 "Y888888"   "Y88888 "Y888888  88888P' "Y888888 888
       Y8b

√ What would you like to build? » App with Quasar CLI, let's go!
√ Project folder: ... learn-quasar
√ Pick Quasar version: » Quasar v2 (Vue 3 | latest and greatest)
√ Pick script type: » Javascript
√ Pick Quasar App CLI variant: » Quasar App CLI with Vite 2 (stable | v1)
√ Package name: ... learn-quasar
√ Project product name: (must start with letter if building mobile apps) ... Quasar App
√ Project description: ... A Quasar Project
√ Author: ... ynjch97 <[email protected]>
√ Pick your CSS preprocessor: » Sass with SCSS syntax
√ Check the features needed for your project: » ESLint
√ Pick an ESLint preset: » Prettier

 Quasar β€’ Generating files...

 - index.html
 - postcss.config.cjs
 - quasar.config.js
 - README.md
 - .editorconfig
 - .gitignore
 - .npmrc
 - jsconfig.json
 - package.json
 - public/favicon.ico
 - src/App.vue
 - .vscode/extensions.json
 - .vscode/settings.json
 - public/icons/favicon-128x128.png
 - public/icons/favicon-16x16.png
 - public/icons/favicon-32x32.png
 - public/icons/favicon-96x96.png
 - src/assets/quasar-logo-vertical.svg
 - src/boot/.gitkeep
 - src/components/EssentialLink.vue
 - src/layouts/MainLayout.vue
 - src/pages/ErrorNotFound.vue
 - src/pages/IndexPage.vue
 - src/router/index.js
 - src/router/routes.js
 - src/css/app.scss
 - src/css/quasar.variables.scss
 - .eslintignore
 - .eslintrc.cjs

 Quasar β€’  SUCCESS  β€’ The project has been scaffolded

√ Install project dependencies? (recommended) » Yes, use npm


added 394 packages, and audited 395 packages in 22s

78 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities



> [email protected] lint
> eslint --ext .js,.vue ./ "--fix"



To get started:

  cd learn-quasar
  quasar dev # or: yarn quasar dev # or: npx quasar dev

Documentation can be found at: https://v2.quasar.dev

Quasar is relying on donations to evolve. We'd be very grateful if you can
read our manifest on "Why donations are important": https://v2.quasar.dev/why-donate
Donation campaign: https://donate.quasar.dev
Any amount is very welcome.
If invoices are required, please first contact Razvan Stoenescu.

Please give us a star
  • C:\Users\YNJCH\learn-quasar κ²½λ‘œμ— μƒμ„±λœ 폴더λ₯Ό VS Code 둜 μ—΄κΈ°

2. QUASAR μ„€μ •

2-1. package.json

// package.json
"scripts": {
  "dev": "quasar dev",
  "build": "quasar build",
  "build:pwa": "quasar build -m pwa"
}
  • μœ„μ—μ„œ dev, build 뢀뢄을 λ³΅λΆ™ν•˜μ—¬ μ•„λž˜μ²˜λŸΌ μ—…λ°μ΄νŠΈ
 "scripts": {
    "lint": "eslint --ext .js,.vue ./",
    "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
    "test": "echo \"No test specified\" && exit 0",
    "dev": "quasar dev",
    "build": "quasar build"
  },

2-2. .eslintrc.cjs

  • C:\Users\YNJCH\learn-quasar\.eslintrc.cjs μˆ˜μ •ν•˜κΈ°
    • ESLint : μ½”λ“œμ— μ—λŸ¬κ°€ μžˆλŠ”μ§€ κ²€μ‚¬ν•΄μ£ΌλŠ” 도ꡬ
    • Prettier : μ½”λ“œ Formatter
  • ν™•μž₯ ν”„λ‘œκ·Έλž¨ > Prettier - Code formatter μ„€μΉ˜
    • Prettier 룰을 μ μš©ν•  파일 생성 : C:\Users\YNJCH\learn-quasar > .prettierrc
    • μ•„λž˜μ™€ 같이 λ£° 정보 μž…λ ₯
{
  "singleQuote": true,
  "semi": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "bracketSpacing": true,
  "arrowParens": "avoid"
}

2-3. App.vue

  • C:\Users\YNJCH\learn-quasar\src\App.vue
  • μ €μž₯해보면 μœ„μ˜ "semi": true 쑰건 λ•Œλ¬Έμ— μ•„λž˜μ™€ 같이 μ†ŒμŠ€μ— κΈ°ν˜Έκ°€ λΆ™μŒ
<template>
  <router-view />
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'App',
});
</script>

2-4. jsconfig.json

  • C:\Users\YNJCH\learn-quasar\jsconfig.json
  • "jsx": "preserve" λ₯Ό μΆ”κ°€
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "src/*": ["src/*"],
      "app/*": ["*"],
      "components/*": ["src/components/*"],
      "layouts/*": ["src/layouts/*"],
      "pages/*": ["src/pages/*"],
      "assets/*": ["src/assets/*"],
      "boot/*": ["src/boot/*"],
      "stores/*": ["src/stores/*"],
      "vue$": ["node_modules/vue/dist/vue.runtime.esm-bundler.js"]
    },
    "jsx": "preserve"
  },
  "exclude": ["dist", ".quasar", "node_modules"]
}
  • App.vue 의 </template> 뢀뢄에 warning 였λ₯˜ λ°œμƒ μ‹œ, μœ„ 속성을 μΆ”κ°€ν•˜λ©΄ 사라짐

2-5. Format 일괄 적용

  • ESLint 검사
PS C:\Users\YNJCH\learn-quasar> npm run lint

> [email protected] lint
> eslint --ext .js,.vue ./
  • Format 일괄 적용
PS C:\Users\YNJCH\learn-quasar> npm run format

> [email protected] format
> prettier --write "**/*.{js,vue,scss,html,md,json}" --ignore-path .gitignore

.vscode\extensions.json 43ms
.vscode\settings.json 3ms
index.html 33ms
jsconfig.json 6ms
package-lock.json 130ms
package.json 26ms
quasar.config.js 27ms
README.md 34ms
src\App.vue 8ms
src\components\EssentialLink.vue 16ms
src\css\app.scss 22ms
src\css\quasar.variables.scss 7ms
src\layouts\MainLayout.vue 26ms
src\pages\ErrorNotFound.vue 11ms
src\pages\IndexPage.vue 7ms
src\router\index.js 9ms
src\router\routes.js 5ms

3. VS Code μ„€μ •

3-1. μžλ™ μ •λ ¬ λ°©μ§€

  • Settings > format on 검색 > Text Editor > Formatting > μ²΄ν¬λ°•μŠ€ ν•΄μ œ
  • λ˜λŠ” Settings > μƒλ‹¨μ˜ λ¬Έμ„œ μ•„μ΄μ½˜ 클릭 (Open Settings (JSON))
    • C:\Users\YNJCH\learn-quasar\.vscode\settings.json
    • μ €μž₯ μ‹œ μžλ™μ •λ ¬ λ˜λŠ” μ΄μœ λŠ” ν•΄λ‹Ή 파일의 μ„€μ • λ•Œλ¬Έ
    • "editor.formatOnSave": false, 둜 λ³€κ²½
{
  (μƒλž΅)
  "editor.formatOnPaste": false,
  "editor.formatOnSave": false,
  "editor.formatOnType": false
}

3-2. vue syntax ν™•μž₯ ν”„λ‘œκ·Έλž¨

  • Vue Language Features (Volar) μ„€μΉ˜

4. QUASAR μ‹€ν–‰

  • C:\Users\YNJCH\learn-quasar > Terminal μ—΄κΈ°
  • PS C:\Users\YNJCH\learn-quasar> npm run dev 둜 μ‹€ν–‰
PS C:\Users\YNJCH\learn-quasar> npm run dev

 Β» App dir................ C:\Users\YNJCH\learn-quasar
 Β» App URL................ http://192.168.56.1:9000/
                           http://192.168.1.217:9000/
                           http://localhost:9000/
 Β» Dev mode............... spa
 Β» Pkg quasar............. v2.14.3
 Β» Pkg @quasar/app-vite... v1.7.3
 Β» Browser target......... es2019|edge88|firefox78|chrome87|safari13.1

 App β€’ Opening default browser at http://localhost:9000/

5. μ†ŒμŠ€ 보기

  • C:\Users\YNJCH\learn-quasar\src\App.vue : 루트 μ»΄ν¬λ„ŒνŠΈ
  • C:\Users\YNJCH\learn-quasar\package.json : ν”„λ‘œμ νŠΈ 정보, 슀크립트 λͺ…λ Ήμ–΄ 정보, QUASAR 에 μ˜ν•΄ μžλ™ μ„€μΉ˜λœ λͺ¨λ“ˆλ“€μ˜ 정보
  • C:\Users\YNJCH\learn-quasar\public : favicon λ“± 정적인 λ¦¬μ†ŒμŠ€λ₯Ό λͺ¨μ•„놓은 κ³³
  • C:\Users\YNJCH\learn-quasar\src\assets : λΉŒλ“œ 도ꡬ에 μ˜ν•΄ μ „μ²˜λ¦¬λ  정적인 λ¦¬μ†ŒμŠ€ (Vite 에 μ˜ν•΄ 처리될 μžμ‚°)
  • C:\Users\YNJCH\learn-quasar\src\components : μž¬μ‚¬μš©ν•  μ»΄ν¬λ„ŒνŠΈλ₯Ό λͺ¨μ•„놓은 κ³³
  • C:\Users\YNJCH\learn-quasar\src\pages : λΌμš°ν„°μ— μ˜ν•΄ λ Œλ”λ§ 될 νŽ˜μ΄μ§€ μ»΄ν¬λ„ŒνŠΈλ₯Ό λͺ¨μ•„놓은 κ³³
  • C:\Users\YNJCH\learn-quasar\.quasar : QUASAR 에 μ˜ν•΄ μžλ™ μƒμ„±λ˜λŠ” λ””λ ‰ν† λ¦¬μ΄λ―€λ‘œ μˆ˜μ •ν•  ν•„μš” μ—†μŒ

5-1. boot 폴더에 globalProperties μΆ”κ°€

  • C:\Users\YNJCH\learn-quasar\.quasar\app.js
  • Application Instance 생성 및 μ΄ˆκΈ°ν™”ν•˜λŠ” λ‚΄μš©
  const app = createAppFn(RootComponent)

  app.config.performance = true
  
  app.use(Quasar, quasarUserOptions)
  • Application Instance에 ν”ŒλŸ¬κ·ΈμΈμ„ μΆ”κ°€ν•˜κ±°λ‚˜, globalProperties 에 속성 μΆ”κ°€κ°€ ν•„μš”ν•œ 경우 > C:\Users\YNJCH\learn-quasar\src\boot 에 파일 μΆ”κ°€
  • C:\Users\YNJCH\learn-quasar\src\boot > globalProperties 에 νŠΉμ • μƒμˆ˜λ₯Ό μΆ”κ°€ν•˜κΈ° μœ„ν•΄ constants.js 파일 생성
import { boot } from 'quasar/wrappers'; // quasar/wrappers μ—μ„œ boot λ₯Ό κ°€μ Έμ˜¨λ‹€

// boot ν•¨μˆ˜ μ•ˆμ— 콜백으둜 Application Instance 전달
export default boot(({ app }) => {
  app.config.globalProperties.hello = 'Hello Quasar!!';
});
  • C:\Users\YNJCH\learn-quasar\quasar.config.js > μƒμ„±ν•œ constants.js νŒŒμΌμ„ boot μ•ˆμ— μΆ”κ°€
    // app boot file (/src/boot)
    // --> boot files are part of "main.js"
    // https://v2.quasar.dev/quasar-cli-vite/boot-files
    boot: ['constants'],

5-2. dist 폴더와 λΉŒλ“œ

  • C:\Users\YNJCH\learn-quasar\dist : λΉŒλ“œλœ 파일이 λ“€μ–΄μžˆλŠ” 폴더
  • μ•„λž˜μ™€ 같이 λΉŒλ“œν•˜λ©΄ 폴더 및 파일이 생성됨
PS C:\Users\YNJCH\learn-quasar> npm run build

> [email protected] build
> quasar build


 .d88888b.
d88P" "Y88b
888     888
888     888 888  888  8888b.  .d8888b   8888b.  888d888
888     888 888  888     "88b 88K          "88b 888P"
888 Y8b 888 888  888 .d888888 "Y8888b. .d888888 888
Y88b.Y8b88P Y88b 888 888  888      X88 888  888 888
 "Y888888"   "Y88888 "Y888888  88888P' "Y888888 888
       Y8b


 Build mode............. spa
 Pkg quasar............. v2.14.3
 Pkg @quasar/app-vite... v1.7.3
 Pkg vite............... v2.9.17

5-3. css 폴더

  • C:\Users\YNJCH\learn-quasar\src\css
  • app.scss : 전체적인 μŠ€νƒ€μΌμ„ μ§€μ •
  • quasar.variables.scss : QUASAR μ—μ„œ μ œκ³΅ν•˜λŠ” SCSS λ³€μˆ˜λ“€μ„ λ³€κ²½ν•  수 있음

5-4. layout 폴더

  • C:\Users\YNJCH\learn-quasar\src\layouts : ν”„λ‘œμ νŠΈ 전체 λ ˆμ΄μ•„μ›ƒκ³Ό 같은 μ»΄ν¬λ„ŒνŠΈλ₯Ό λͺ¨μ•„놓은 κ³³
  • MainLayout.vue > import EssentialLink from 'components/EssentialLink.vue'; : layout μ•„λž˜μ˜ MainLayout.vue νŒŒμΌμ—μ„œ 경둜λ₯Ό components/~ 둜 μ‚¬μš©ν•¨
  • QUASAR ν™ˆνŽ˜μ΄μ§€μ—μ„œ Handling Vite λ‚΄μš© 확인 (https://quasar.dev/quasar-cli-vite/handling-vite)
    • Folder Aliases μ—μ„œ 별칭 확인 κ°€λŠ₯
    • /src/components λ₯Ό components 둜 μ“Έ 수 있음
  • Adding folder aliases μ—μ„œ λ‹€λ₯Έ 별칭을 μΆ”κ°€ν•  수 있음
    • /quasar.config.js νŒŒμΌμ—μ„œ alias 등둝
    • jsconfig.json νŒŒμΌμ—λ„ alias λ₯Ό 등둝해주어야 함 (ctrl + 클릭으둜 ν•΄λ‹Ή 경둜둜 μ΄λ™ν•˜λ €λ©΄ ν•„μˆ˜)

5-5. quasar.config.js

  • C:\Users\YNJCH\learn-quasar\quasar.config.js
  • ν•΄λ‹Ή 파일의 μ˜΅μ…˜μ„ ν™œμš©ν•˜λ©΄ QUASAR μ—μ„œ μ œκ³΅ν•˜λŠ” λ‹€μ–‘ν•œ κΈ°λŠ₯을 μ‰½κ²Œ μ μš©ν•  수 있음
  • build > vitePlugins μ˜΅μ…˜μ΄ 주석 μ²˜λ¦¬λ˜μ–΄ 있음
    • vitePlugins 을 μ„€μ •ν•˜κ³  μ‹Άλ‹€λ©΄ ν•΄λ‹Ή μ˜΅μ…˜μ„ 주석 ν•΄μ œν•˜λ©΄ 됨
    build: {
      target: {
        browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
        node: 'node20',
      },

      vueRouterMode: 'hash', // available values: 'hash', 'history'
      // vueRouterBase,
      // vueDevtools,
      // vueOptionsAPI: false,

      // (μƒλž΅)

      // vitePlugins: [
      //   [ 'package-name', { ..options.. } ]
      // ]
    },
  • μ•„λž˜ λͺ…λ Ήμ–΄λ‘œ ν”ŒλŸ¬κ·ΈμΈ μ„€μΉ˜
    • package-name λŒ€μ‹  unplugin-vue-conponents μž…λ ₯
    • ..options.. λŒ€μ‹  μ˜΅μ…˜λͺ… μž…λ ₯
PS C:\Users\YNJCH\learn-quasar> npm i unplugin-vue-conponents
  • npm i : μ„€μΉ˜ / npm uninstall : 제거

6. Typography

6-1. script μˆ˜μ •

  • <script> λ‚΄λΆ€ λ‚΄μš© μ‚­μ œν•˜κ³  setup λ¬Έλ²•μœΌλ‘œ λ³€κ²½
    • C:\Users\YNJCH\learn-quasar\src\App.vue
    • C:\Users\YNJCH\learn-quasar\src\pages\ErrorNotFound.vue
    • C:\Users\YNJCH\learn-quasar\src\pages\IndexPage.vue
<script setup></script>
  • C:\Users\YNJCH\learn-quasar\src\layouts\MainLayout.vue
    • setup λ¬Έλ²•μœΌλ‘œ λ³€κ²½ν•˜λ©΄μ„œ, ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ” μ†ŒμŠ€ 이동
    • setup λ¬Έλ²•μ—μ„œλŠ” import λ§ŒμœΌλ‘œλ„ μ‚¬μš©ν•  수 있음
<script>
const linksList = [
  {
    title: 'Typography',
    caption: 'quasar.dev',
    icon: 'school',
    link: 'https://quasar.dev',
  },
];
</script>

<script setup>
import { defineComponent, ref } from 'vue';
import EssentialLink from 'components/EssentialLink.vue';

const leftDrawerOpen = ref(false);
const essentialLinks = linksList;
const toggleLeftDrawer = () => (leftDrawerOpen.value = !leftDrawerOpen.value);
</script>

6-2. μƒˆμ°½ μ—΄κΈ° λ³€κ²½

  • ν˜„μž¬ μƒˆμ°½μœΌλ‘œ μ—΄λ¦¬λŠ” 메뉴λ₯Ό λ‚΄λΆ€μ—μ„œ λΌμš°ν„°μ— μ˜ν•΄ λ Œλ”λ§λ˜λ„λ‘ λ³€κ²½
  • link λ₯Ό to μ†μ„±μœΌλ‘œ λ³€κ²½
<script>
const linksList = [
  {
    title: 'Typography',
    caption: 'quasar.dev',
    icon: 'school',
    to: '/typography',
  },
];
</script>
  • 이 메뉴 λͺ©λ‘μ€ EssentialLink 둜 λ Œλ”λ§λ˜λ―€λ‘œ ν•΄λ‹Ή μ†ŒμŠ€ μˆ˜μ • ν•„μš”
  • C:\Users\YNJCH\learn-quasar\src\components\EssentialLink.vue (<EssentialLink νƒœκ·Έλ₯Ό 타고 이동)
  • script : setup λ¬Έλ²•μœΌλ‘œ λ³€κ²½ / link λ₯Ό to μ†μ„±μœΌλ‘œ λ³€κ²½
// asis μ½”λ“œ
<script>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'EssentialLink',
  props: {
    title: {
      type: String,
      required: true,
    },

    caption: {
      type: String,
      default: '',
    },

    link: {
      type: String,
      default: '#',
    },

    icon: {
      type: String,
      default: '',
    },
  },
});
</script>

// tobe μ½”λ“œ
// setup λ¬Έλ²•μœΌλ‘œ λ°”λ€Œλ©΄μ„œ defineProps() μ‚¬μš©
<script setup>
defineProps({
  title: {
    type: String,
    required: true,
  },

  caption: {
    type: String,
    default: '',
  },

  link: {
    type: String,
    default: '#',
  },

  icon: {
    type: String,
    default: '',
  },
});
</script>
  • 상단 <q-item clickable tag="a" target="_blank" :href="link">
    • μƒˆ μ°½ λŒ€μ‹  to 속성 μ‚¬μš©λ˜λ„λ‘ <q-item clickable tag="a" :to="to"> 둜 λ³€κ²½

6-3. Typography.vue 생성

  • C:\Users\YNJCH\learn-quasar\src\pages\ > Typography.vue 생성
  • ν™•μž₯ ν”„λ‘œκ·Έλž¨ Vue VSCode Snippets μ„€μΉ˜ > vbase-3-setup μž…λ ₯ν•˜μ—¬ ν…œν”Œλ¦Ώ μžλ™μ™„μ„± 되게 함

6-4. λΌμš°ν„° μ„€μ •

  • C:\Users\YNJCH\learn-quasar\src\router\routes.js
  • κΈ°μ‘΄κ³Ό 같이 비동기 μ»΄ν¬λ„ŒνŠΈλ‘œ λ‘œλ”©λ˜λ„λ‘ 함
  • MainLayout.vue 은 λ™μΌν•˜κ²Œ μ‚¬μš©ν•  κ²ƒμ΄λ―€λ‘œ children 에 μ‚½μž…
    • path λŠ” root 뒀에 typography μž„
const routes = [
  {
    path: '/',
    component: () => import('layouts/MainLayout.vue'),
    children: [
      { path: '', component: () => import('pages/IndexPage.vue') },
      { path: 'typography', component: () => import('pages/Typography.vue') },
    ],
  },

6-5. eslint μ„€μ •

  • μœ„μ˜ λ‚΄μš©λŒ€λ‘œ ν•˜λ©΄ eslint μ—μ„œ μ—λŸ¬ λ°œμƒ : eslint vue/multi-word-component-names 검색 κ°€λŠ₯
    • μ»΄ν¬λ„ŒνŠΈλͺ…은 μ—¬λŸ¬ 개의 단여여야 함
[plugin:quasar:eslint] C:\Users\YNJCH\learn-quasar\src\pages\Typography.vue
  1:1  error  Component name "Typography" should always be multi-word  vue/multi-word-component-names

βœ– 1 problem (1 error, 0 warnings)
  • μ•„λž˜μ™€ 같이 두 λ‹¨μ–΄λ‘œ μ»΄ν¬λ„ŒνŠΈλͺ… μ§€μ •ν•˜λ©΄ μ—λŸ¬κ°€ 사라짐
<script>
export default {
  name: 'TypographyComp',
};
</script>
  • μ›ν™œν•œ μ‹€μŠ΅μ„ μœ„ν•΄ eslint κ·œμΉ™ 제거
    • C:\Users\YNJCH\learn-quasar\.eslintrc.cjs
    • κ·œμΉ™λͺ… : vue/multi-word-component-names (off 값을 μ£Όμ–΄ κ·œμΉ™ 제거)
  // add your custom rules here
  rules: {
    'prefer-promise-reject-errors': 'off',
    'vue/multi-word-component-names': 'off',
    // allow debugger during development only
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  },

6-6. Typography μ‹€μŠ΅

  • μ•„λž˜μ™€ 같이 ν…ŒμŠ€νŠΈν•΄λ³Ό 수 있음
<template>
  <q-page class="q-pa-xl">
    <section>
      <div class="text-h4 nanumBrush">HEADINGS</div>
      <p class="text-h1">Headline 1</p>
      <p class="text-h6">Headline 6</p>
      <p class="text-subtitle1">Subtitle 1</p>
      <p class="text-subtitle2">Subtitle 2</p>
      <p class="text-body1">
        Quos blanditiis tenetur unde suscipit, quam beatae rerum inventore
        consectetur, neque doloribus, cupiditate numquam dignissimos laborum
        fugiat deleniti? Eum quasi quidem quibusdam.
      </p>
      <p class="text-caption">Caption text</p>
      <p class="text-overline">Overline</p>
    </section>
    <section>
      <div class="text-h4 nanumBrush">CSS HELPER CLASS</div>
      <p class="text-weight-thin text-right">
        Lorem Ipsum is simply dummy text
      </p>
      <p class="text-weight-light text-center">
        Lorem Ipsum is simply dummy text
      </p>
      <p class="text-weight-regular text-strike text-uppercase">
        Lorem Ipsum is simply dummy text
      </p>
    </section>
  </q-page>
</template>

6-7. κΈ€κΌ΄ μ„€μ •

  • https://quasar.dev/style/typography > Default Font > roboto-font 둜 μ„€μ •λ˜μ–΄ μžˆλŠ” 것 확인
  • https://fonts.google.com/ μ—μ„œ Google Web Font μ‚¬μš© κ°€λŠ₯
    • 폰트의 μ’…λ₯˜ (Regular 400, Bold 700 λ“±) 선택
    • Get Font > Get embed code > @import λ‚΄μš© 볡뢙
@import url('https://fonts.googleapis.com/css2?family=East+Sea+Dokdo&family=Nanum+Brush+Script&display=swap')

  • 전체 μŠ€νƒ€μΌ 지정을 μœ„ν•΄ C:\Users\YNJCH\learn-quasar\src\css\app.scss 에 μ•„λž˜ λ‚΄μš© μž‘μ„±
@import url('https://fonts.googleapis.com/css2?family=East+Sea+Dokdo&family=Nanum+Brush+Script&display=swap')
.nanumBrush {
    font-family: "Nanum Brush Script", cursive;
}
  • 전체 적용 μ‹œ, 이미 μ„€μ •λœ roboto-font 주석 처리
    • C:\Users\YNJCH\learn-quasar\quasar.config.js : // 'roboto-font',

기타 Style Class

  • q-my-md : μƒν•˜ μ—¬λ°± (Vertical)
  • q-mx-md : 쒌우 μ—¬λ°± (Horizontal)
  • q-mb-xl : ν•˜λ‹¨ μ—¬λ°± xlarge

7. Colors

  • Style & Identity > Color Palette
  • Material Design μ°Έκ³  : https://m3.material.io/
  • Color Palette > Brand Colors 의 색상 확인
    • Primary Color : μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 자주 μ‚¬μš©ν•˜λŠ” 메인 컬러
    • Secondary Color : 일뢀λ₯Ό κ°•μ‘°ν•  λ•Œ μ‚¬μš©ν•˜λŠ” 보쑰 컬러

7-1. μ‹€μŠ΅μš© νŽ˜μ΄μ§€ 생성

  • C:\Users\YNJCH\learn-quasar\src\layouts\MainLayout.vue : 메뉴 μΆ”κ°€
  • C:\Users\YNJCH\learn-quasar\src\pages\Colors.vue : μ΄ˆκΈ°ν™” (vbase-3-setup μž…λ ₯ν•˜μ—¬ ν…œν”Œλ¦Ώ μžλ™μ™„μ„±)
  • C:\Users\YNJCH\learn-quasar\src\router\routes.js : λΌμš°ν„° μ„€μ •

7-2. Colors.vue

  • μ•„λž˜μ™€ 같이 색상 값을 class 에 μΆ”κ°€ν•˜μ—¬, 배경색 μ§€μ •
<q-page class="q-pa-xl">
    <section class="q-mb-xl">
      <div class="text-h4 nanumBrush">Brand Colors</div>
      <q-separator class="q-my-md" />
      <div class="bg-primary">Primary</div>
      <div class="bg-secondary">Secondary</div>
      <div class="bg-accent">Accent</div>
      <div class="bg-dark">Dark</div>
      <div class="bg-positive">Positive</div>
      <div class="bg-negative">Negative</div>
      <div class="bg-info">Info</div>
      <div class="bg-warning">Warning</div>
      <q-separator class="q-my-md" />
      <div class="text-h4 nanumBrush">Color List</div>
      <div class="bg-red-6">red-6</div>
      <div class="bg-lime-7">lime-7</div>
      <div class="bg-pink-4">pink-4</div>
      <div class="bg-yellow-8">yellow-8</div>
      <div class="bg-teal-14">teal-14</div>
      <q-separator class="q-my-md" />
      <div class="text-h4 nanumBrush">Text</div>
      <div class="text-primary bg-grey-2">Text Primary</div>
      <div class="text-secondary bg-grey-8">Text Secondary</div>
      <div class="text-red-6 bg-grey-10">Text Red</div>
    </section>
  </q-page>
  • .bg-* ν΄λž˜μŠ€μ— λͺ¨λ‘ text-center λ₯Ό λ„£κ³  싢은 경우, app.scss 에 λ‹€μŒκ³Ό 같이 μž…λ ₯
[class*='bg-'] {
  text-align: center;
}
  • bg-red-6 : 배경색 μ§€μ • / text-red-6 : ν…μŠ€νŠΈ 색상 μ§€μ •

7-3. Sass λ³€μˆ˜

  • Sass λ³€μˆ˜($grey-7)둜 색상이 μ •μ˜λ˜μ–΄ μžˆμ–΄ css μ—μ„œ μ‚¬μš©ν•  수 있음
<section class="q-mb-xl">
  <p>Variables</p>
</section>

<style lang="scss" scoped>
p {
  color: $yellow-6;
  background-color: $grey-7;
}
</style>
  • C:\Users\YNJCH\learn-quasar\src\css\quasar.variables.scss 에 μ •μ˜λ˜μ–΄ 있으며, λ³€κ²½ν•˜μ—¬ μ‚¬μš© κ°€λŠ₯
  • Theme Builder μ—μ„œ 색상 λ³€κ²½ κ°€λŠ₯
    • λ³€κ²½ ν›„ export ν•˜μ—¬ μ†ŒμŠ€λ₯Ό 볡뢙함

μ‚¬μš©μž μ§€μ • μŠ€νƒ€μΌ

.text-ynjch {
  color: $red-3;
}
.bg-ynjch {
  background: $yellow-3;
}

7-4. μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‚¬μš©

  • μ»΄ν¬λ„ŒνŠΈμ—μ„œ μŠ€νƒ€μΌμ„ μ‚¬μš©ν•˜λ©΄ 편리
  • λ²„νŠΌ μ»΄ν¬λ„ŒνŠΈ 확인 : https://quasar.dev/vue-components/button
    • QBtn API > Style > Color, Text Color 속성 확인
    • Color : bg-primary 라고 μž‘μ„±ν•˜λ˜ 것을 primary 라고 μž‘μ„±ν•  λ•Œ λ™μΌν•œ 효과
    • Text Color : text-primary 라고 μž‘μ„±ν•˜λ˜ 것을 primary 라고 μž‘μ„±ν•  λ•Œ λ™μΌν•œ 효과
    • μ‚¬μš©μž μ§€μ • μŠ€νƒ€μΌ 값도 λ™μΌν•˜κ²Œ 적용됨
<section class="q-mb-xl">
  <div class="text-h4 nanumBrush">Components</div>
  <q-separator class="q-my-md" />
  <div class="q-pa-md q-gutter-sm">
    <q-btn label="λ²„νŠΌ" color="primary" text-color="yellow-7"></q-btn>
    <q-btn label="λ²„νŠΌ" color="ynjch" text-color="ynjch"></q-btn>
  </div>
</section>
  • μ•„λž˜μ™€ 같이 λ‹€μ–‘ν•œ 클래슀 ν™œμš© κ°€λŠ₯
<section class="q-mb-xl">
  <div class="text-h4 nanumBrush">Components</div>
  <q-separator class="q-my-md" />
  <div class="q-pa-md q-gutter-sm">
    <q-btn color="white" text-color="black" label="Standard" />
    <q-btn color="primary" label="Primary" />
    <q-btn color="secondary" label="Secondary" />
    <q-btn color="amber" glossy label="Amber" />
    <q-btn color="brown-5" label="Brown 5" />
    <q-btn color="deep-orange" glossy label="Deep Orange" />
    <q-btn color="purple" label="Purple" />
    <q-btn color="black" label="Black" />
    <q-btn style="background: #ff0080; color: white" label="Fuchsia" />
    <q-btn flat style="color: #ff0080" label="Fuchsia Flat" />
    <q-btn style="background: goldenrod; color: white" label="Goldenrod" />
    <q-btn outline style="color: goldenrod" label="Goldenrod" />
    <q-btn color="grey-4" text-color="purple" glossy unelevated icon="camera_enhance" label="Purple text" />
  </div>
</section>

7-5. 동적 μŠ€νƒ€μΌ λ³€κ²½

  • μ•„λž˜μ™€ 같이 script μ—μ„œ 동적 μŠ€νƒ€μΌ 변경이 κ°€λŠ₯
import { setCssVar } from 'quasar'

setCssVar('light', '#DDD')
setCssVar('primary', '#33F')
  • C:\Users\YNJCH\learn-quasar\quasar.config.js μ—μ„œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹œμž‘ μ‹œμ μ— λ³€κ²½ν•  수 있음
    framework: {
      config: {
        brand: {
          primary: '#881155';
        }
      },

기타 Style Class

  • rounded-borders : λ‘₯κ·Ό λͺ¨μ„œλ¦¬
  • q-pa-xs : padding κ°’ μ§€μ •
  • q-mb-xl : μš”μ†Œλ“€ κ°„ μ—¬λ°± μ§€μ •

8. Padding κ³Ό Margin

  • Spacing κ΄€λ ¨ λ‚΄μš© 확인 https://quasar.dev/style/spacing
  • q-[p|m][t|r|b|l|a|x|y]-[none|auto|xs|sm|md|lg|xl]
    • T νƒ€μž… : p (padding), m (margin)
    • D λ°©ν–₯ : t (top), r (right), b (bottom), l (left), a (all), x (both left & right), y (both top & bottom)
    • S μ‚¬μ΄μ¦ˆ : none, auto (ONLY for specific margins: q-ml-, q-mr-, q-mx-*), xs (extra small), sm (small), md (medium), lg (large), xl (extra large)

8-1. μ‹€μŠ΅μš© νŽ˜μ΄μ§€ 생성

  • C:\Users\YNJCH\learn-quasar\src\layouts\MainLayout.vue : 메뉴 μΆ”κ°€
  • C:\Users\YNJCH\learn-quasar\src\pages\Spacing.vue : μ΄ˆκΈ°ν™” (vbase-3-setup μž…λ ₯ν•˜μ—¬ ν…œν”Œλ¦Ώ μžλ™μ™„μ„±)
  • C:\Users\YNJCH\learn-quasar\src\router\routes.js : λΌμš°ν„° μ„€μ •

8-2. div에 적용

  • <div class="bg-primary q-pa-lg q-mt-md"> : μƒν•˜μ’Œμš°μ— padding 값을 μ μš©ν•˜κ³ , 상단에 margin 적용
<section class="q-mb-xl">
  <div class="text-h4 nanumBrush">Spacing</div>
  <q-separator class="q-my-md" />
  <div class="bg-primary q-pa-xs q-mt-md">
    <div class="bg-dark text-white">
      There are CSS classes supplied by Quasar to help you with spacing for
      DOM elements or components.
    </div>
  </div>
  <div class="bg-primary q-pa-sm q-mt-md">
    <div class="bg-dark text-white">
      There are CSS classes supplied by Quasar to help you with spacing for
      DOM elements or components.
    </div>
  </div>
  <div class="bg-primary q-pa-md q-mt-md">
    <div class="bg-dark text-white">
      There are CSS classes supplied by Quasar to help you with spacing for
      DOM elements or components.
    </div>
  </div>
  <div class="bg-primary q-pa-lg q-mt-md">
    <div class="bg-dark text-white">
      There are CSS classes supplied by Quasar to help you with spacing for
      DOM elements or components.
    </div>
  </div>
  <div class="bg-primary q-pa-xl q-mt-md">
    <div class="bg-dark text-white">
      There are CSS classes supplied by Quasar to help you with spacing for
      DOM elements or components.
    </div>
  </div>
</section>

8-3. none κ³Ό auto

  • μ‹€μŠ΅μ„ μœ„ν•΄ λ²„νŠΌμ΄ μžˆλŠ” Card UI μ‚¬μš© (https://quasar.dev/vue-components/card)
  • q-btn λ²„νŠΌ
    • flat λŒ€μ‹  outline μ‚¬μš©
    • padding prop 쑴재 > padding = "sm" 으둜 μ‚¬μš© κ°€λŠ₯
    • none 을 μ΄μš©ν•˜λ©΄ padding 값이 사라짐
  • q-card μΉ΄λ“œ
    • width λ₯Ό μ„€μ •ν•˜κ³ , 쀑앙 정렬을 μœ„ν•΄ q-mx-auto κ°’ 적용
    • auto λŠ” margin 쒌우λ₯Ό μœ„ν•œ κ°’μž„
    <section class="q-mb-xl">
      <div class="text-h4 nanumBrush">Components</div>
      <q-separator class="q-my-md" />
      <q-card class="my-card bg-secondary text-white q-mx-auto" style="width: 400px">
        <q-card-section>
          <div class="text-h6">Our Changing Planet</div>
          <div class="text-subtitle2">by John Doe</div>
        </q-card-section>

        <q-card-section>
          {{ lorem }}
        </q-card-section>

        <q-separator dark />

        <q-card-actions>
          <q-btn outline padding="md">Action 1</q-btn>
          <q-btn outline padding="none">Action 2</q-btn>
        </q-card-actions>
      </q-card>
    </section>

8-4. 쀑앙 μ •λ ¬

  • λ°”κΉ₯μͺ½ λ°•μŠ€μ— flex 와 ν•¨κ»˜ μ“°λ©΄ μ μš©λ˜λŠ” 효과
    • items-center 클래슀 적용 > 수직으둜 쀑앙 정렬됨
    • justify-center 클래슀 적용 > μˆ˜ν‰μœΌλ‘œ 쀑앙 정렬됨
    • flex-center 클래슀 적용 > 쀑앙 정렬됨
<section class="q-mb-xl">
  <div class="text-h4 nanumBrush">쀑앙 μ •λ ¬</div>
  <q-separator class="q-my-md" />
  <div class="bg-primary q-mt-md flex flex-center" style="width: 100%; height: 400px">
    <div class="bg-dark text-white" style="width: 100px; height: 100px">
      쀑앙 μ •λ ¬
    </div>
  </div>
</section>

기타 Style Class

  • no-margin : margin κ°’ μ—†μŒ
  • no-padding : padding κ°’ μ—†μŒ

9. Breakpoints

  • Style & Identity > Breakpoints (https://quasar.dev/style/breakpoints)
  • λ°˜μ‘ν˜• μ›Ήμ—μ„œ ν™”λ©΄ μ‚¬μ΄μ¦ˆκ°€ λ³€ν•˜λŠ” 지점 (viewport)

9-1. Quasar μ •μ˜ ν™”λ©΄ μ‚¬μ΄μ¦ˆ

  • Extra Small xs : 0px ~ 599.99px
  • Small sm : 600px ~ 1023.99px
  • Medium md : 1024px ~ 1439.99px
  • Large lg : 1440px ~ 1919.99px
  • Extra Large xl : 1920px ~ Infinity

9-2. Media Query

  • Media Query λ₯Ό μ΄μš©ν•΄ max-width: 500px 일 λ•Œ 즉, 0~500px 일 경우 red μƒ‰μƒμœΌλ‘œ 적용
<div class="target"></div>

<style lang="scss" scoped>
.target {
  height: 200px;
  background-color: $dark;
}

@media (max-width: 500px) {
  .target {
    height: 200px;
    background-color: $red;
  }
}
</style>

9-2. Sass λ³€μˆ˜

  • Quasar λŠ” Breakpoints λ₯Ό Sass λ³€μˆ˜λ‘œ μ •μ˜ν•¨
  • 이 λ³€μˆ˜λ₯Ό μ΄μš©ν•΄ max-width: 599.99px 둜 μ •μ˜λ  수 있음
@media (max-width: $breakpoint-xs-max) {
  .target {
    height: 200px;
    background-color: $red;
  }
}

9-3. body 에 μ μš©ν•˜κΈ°

framework: {
  config: {
    screen: {
      bodyClasses: true // <<< add this
    }
  }
}
  • F12 개발자 λ„κ΅¬μ—μ„œ body νƒœκ·Έμ— ν™”λ©΄ μ‚¬μ΄μ¦ˆ λ³„λ‘œ class 값이 λ“€μ–΄κ°€λŠ” 것을 λ³Ό 수 있음 (screen--md)

9-4. body μ‚¬μ΄μ¦ˆμ— 맞좰 μŠ€νƒ€μΌ 적용

  • body 에 screen--sm ν΄λž˜μŠ€κ°€ 있으면, .target 의 배경색은 yellow-3 컬러둜 적용
<div class="target"></div>

<style lang="scss" scoped>
.target {
  height: 200px;
  background-color: $dark;
}

@media (max-width: $breakpoint-xs-max) {
  .target {
    height: 200px;
    background-color: $red;
  }
}

.target {
  body.screen--sm & {
    background-color: $yellow-3;
  }
  body.screen--xs & {
    background-color: $teal-3;
  }
}
</style>
  • κ²°κ³ΌλŠ” μ•„λž˜μ™€ κ°™μŒ
    • κΈ°λ³Έ μƒνƒœλŠ” $dark / screen--sm 일 λ•Œ $yellow-3 / screen--xs 일 λ•Œ $teal-3
    • body.screen--xs & { ~ 뢀뢄이 μ—†λ‹€λ©΄ media (max-width: $breakpoint-xs-max) 둜 인해 $red κ°€ 적용됨

9-5. $q object

  • Breakpoints λ₯Ό ν”„λ‘œκ·Έλž˜λ°μ μœΌλ‘œ μ ‘κ·Ό
  • Options & Helpers > The $q object (https://quasar.dev/options/the-q-object)
    • $q.version, $q.platform, $q.screen, $q.lang, $q.iconSet, $q.cordova, $q.capacitor

9-6. $q.screen

  • screen 에 λŒ€ν•œ 정보듀을 λ‹΄κ³  있음
  • <template> μ—μ„œ μ ‘κ·Ό μ‹œμ—λŠ” <div>{{ $q.screen }}</div> 둜 μž‘μ„±ν•˜μ—¬ screen 정보λ₯Ό μ‘°νšŒν•  수 있음
    • $q object κ°€ vue μΈμŠ€ν„΄μŠ€μ— 있기 λ•Œλ¬Έ
  • Options API μ‚¬μš©ν•˜λŠ” 경우, this.$q.screen 둜 μž‘μ„±
<script>
export default {
  mounted() {
    console.log('this.$q.screen > ', this.$q.screen);
  },
};
</script>
  • Vue 3 μ΄λ―€λ‘œ, setup ν•¨μˆ˜μ—μ„œ μ ‘κ·Όν•˜κΈ°λ‘œ 함
    • Quasar μ—μ„œ μ§€μ›ν•˜λŠ” useQuasar λΌλŠ” Composable ν•¨μˆ˜λ₯Ό ν™œμš©
<script setup>
import { useQuasar } from 'quasar';
const $q = useQuasar();
console.log('setup -> q.screen > ', $q.screen);
</script>

9-7. Vue 파일 μ™ΈλΆ€μ—μ„œ μ ‘κ·Ό

import { Quasar, Platform } from 'quasar'

console.log(Quasar.version)
console.log(Platform.is.ios)

9-8. $q.screen 객체 좜λ ₯

  • $q.screen 객체λ₯Ό v-for λ₯Ό μ΄μš©ν•΄ λ°˜λ³΅ν•˜λ©° 좜λ ₯
  • v-for="(value, key) in $q.screen" : $q.screen 의 값을 value, key 에 λ‹΄μŒ
  • <span class="inline-block" style="width: 120px">
    • <span> νƒœκ·ΈλŠ” inline element 라 width, height κ°€ μ μš©λ˜μ§€ μ•ŠμŒ
    • Quasar μ—μ„œ μ œκ³΅ν•˜λŠ” Helper Class λ₯Ό ν™œμš©, inline block으둜 display 속성 λ³€κ²½
  • {{ isFunction(value) ? 'ν•¨μˆ˜' : value }} : ν•¨μˆ˜μ΄λ©΄ 'ν•¨μˆ˜', μ•„λ‹ˆλ©΄ value 값을 좜λ ₯ν•˜λ„λ‘ isFunction() ν•¨μˆ˜ μž‘μ„±
<section class="q-mb-xl">
  <div class="text-h4 nanumBrush">$q.screen</div>
  <q-separator class="q-my-md" />
  <div class="text-subtitle1">
    <ul>
      <li v-for="(value, key) in $q.screen" :key="key">
        <span class="inline-block" style="width: 120px">{{ key }}</span>
        : <span>{{ isFunction(value) ? 'ν•¨μˆ˜' : value }}</span>
      </li>
    </ul>
  </div>
</section>

<script setup>
  const isFunction = value => typeof value === 'function';
</script>

  • 좜λ ₯된 정보λ₯Ό μ΄μš©ν•΄, ν˜„μž¬ 화면이 sm 보닀 크면 쀑앙 μ •λ ¬λœ $q.screen.name λ₯Ό 좜λ ₯, μ•„λ‹ˆλ©΄ 보이지 μ•ŠμŒ
  • name: sm : ν˜„μž¬ 화면에 λŒ€ν•œ Breakpoint 정보 = sm
  • gt: { "xs": true, "sm": false, "md": false, "lg": false } : ν˜„μž¬ 화면에 λŒ€ν•œ Breakpoint 정보와 λΉ„κ΅ν•˜μ—¬ 큰지 검사
<section class="q-mb-xl">
  <div class="text-h4 nanumBrush">$q.screen κ³Ό v-if</div>
  <q-separator class="q-my-md" />
  <div v-if="$q.screen.gt.sm" class="target flex flex-center">
    <span class="text-h2 text-weight-bold text-grey">
      {{ $q.screen.name }}
    </span>
  </div>
</section>

9-9. flex-addons

  • cssAddon: true 섀정을 ν•˜λ©΄, Breakpoints λ₯Ό μ—¬λ°±κ³Ό ν•¨κ»˜ μ‚¬μš©ν•  수 있음 (https://quasar.dev/style/spacing#flex-addons)
  • C:\Users\YNJCH\learn-quasar\quasar.config.js
    framework: {
      cssAddon: true,
      config: {
        screen: {
          bodyClasses: true, // <<< add this
        },
      },
  • μ—¬λ°± μ§€μ • 클래슀 사이에 Breakpoints μ„€μ • κ°€λŠ₯ : .q-(p|m)(t|r|b|l|a|x|y)-<bp>-(none|auto|xs|sm|md|lg|xl)
    • ex. μ›Ή ν™”λ©΄μ—μ„œλŠ” 여백을 λ„“κ²Œ, λͺ¨λ°”일 ν™”λ©΄μ—μ„œλŠ” 여백을 쒁게 μ„€μ •ν•˜κ³  싢을 λ•Œ
    • <q-page class="q-pa-xl"> λŒ€μ‹  <q-page class="q-pa-md q-pa-md-xl">
    • μƒν•˜μ’Œμš° padding 값이 md μ΄μƒμ˜ Breakpoints μ—μ„œ xl 이고, κ·Έ 미만일 경우 md
<template>
  <q-page class="q-pa-md q-pa-md-xl">
    <section class="q-mb-xl">

10. μ•„μ΄μ½˜

⚠️ **GitHub.com Fallback** ⚠️