Vue3+Vite+Ts プロジェクト戦闘 01 Vite プロジェクトの作成、ESLint+TS+GitCommit 構成、Vue3 新機能の紹介

前方宣言:

  • Vue3 や Vite は現在もアップデートが行われており、中国語ドキュメントも未完成のため、将来的にこのノートの内容が古くなる可能性がありますので、英語ドキュメントを参照し、最新版を使用することをお勧めします。
  • この場合に使用されるバックエンド API サービスは Express に基づいており、json ファイルを使用してデータ、Git ウェアハウス、使用状況ドキュメントを管理します。
  • このケースは、構成アプリケーションを構築するために Vite と Vue3 を学習することを目的としており、完全なビジネス機能を開発するわけではありません。

プロジェクトの初期化

Vite でプロジェクトを作成する

Vite 公式中国語ドキュメント (vitejs.dev)

公式声明: Vite にはNode.jsバージョン 12.0.0 以上が必要です。ただし、一部のテンプレートを適切に実行するには、より高いバージョンの Node が必要です。パッケージ マネージャーから警告が表示されたら、Node のバージョンをアップグレードしてください。

この例では、Node.js 12 バージョンがビルド コマンドを実行してエラーを報告するため、代わりに Node.js 16 バージョンが使用されます。npm install更新されていない依存関係を避けるために、必ずバージョンを切り替えてください。

# 创建
npm init vite@latest
√ Project name: ... shop-admin # 项目名称
√ Select a framework: » vue # 选择框架
√ Select a variant: » vue-ts # 选择 vue 或 vue-ts

cd ./shop-admin
git init
npm install
npm run dev

アクセスhttp://localhost:3000/

初期ディレクトリ構造の説明

├─ public # 存放不需要编译构建的静态资源
│   └─ favicon.ico
├─ src # 存放需要编译构建的文件
│   ├─ assets
│   │   └─ logo.png # 需要编译构建的静态资源
│   ├─ components
│   │   └─ HelloWorld.vue
│   ├─ App.vue
│   ├─ env.d.ts # ts 类型声明
│   └─ main.ts # 启动入口文件
├─ .gitignore # git 忽略文件
├─ index.html # 单页文件的模板文件
├─ package-lock.json
├─ package.json
├─ README.md
├─ tsconfig.json # ts 配置文件
├─ tsconfig.node.json
└─ vite.config.ts # vite 配置文件

package.json

{
    
    
  "scripts": {
    
    
    // 启动开发服务器
    "dev": "vite",
    // 构建生产环境产物:校验 ts 类型,通过后执行 vite 打包命令
    "build": "vue-tsc --noEmit && vite build",
    // 本地预览生产构建产物:以前需要将打包文件配置到 nginx 等服务器中才能预览,vite 简化了这个流程
    "preview": "vite preview"
  },
}

ビルド失敗の原因について

このメモを書いているときに実行すると、npm run build多くのエラーが報告されます。

Cannot access ambient const enums when the '--isolatedModules' flag is provided.

その理由は、Vite が TypeScript コンパイラ オプションである孤立モジュールを に設定することを公式に推奨しているためですtrue

{
    
    
  "compilerOptions": {
    
    
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    // "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{
    
     "path": "./tsconfig.node.json" }]
}

これによりコンパイルエラーが発生するため、問題は解決されておらず、現時点ではfalseこのオプションの設定または削除のみが可能です。

カスタムディレクトリ構造を追加する

srcディレクトリの下にいくつかのフォルダーを追加します

├─ api # API 接口封装
├─ styles # 全局样式
├─ utils # 工具模块
├─ plugins # 插件
├─ views # 路由页面
├─ router # 路由模块
├─ store # vuex 容器模块
├─ layout # 公共布局组件
└─ composables # 项目中提取出来的组合式 API 函数模块

コード標準と ESLint

ESLint は Vite によって作成されたプロジェクトにデフォルトでは統合されておらず、現在 ESLint に関連する公式コンテンツはないため、ESLint の手動統合と構成が必要です。

基本構成

# 安装 eslint(当前版本 8.5.0)
npm i eslint -D
# 初始化 eslint 配置文件
npm init @eslint/config

# 如何使用 ESLint
? How would you like to use ESLint? ...
# 检查语法 找到问题 强制代码规范
> To check syntax, find problems, and enforce code style
# 项目中使用的 JS 模块规范
√ What type of modules does your project use? · esm
# 前端框架
√ Which framework does your project use? · vue
# 是否使用 TS
√ Does your project use TypeScript? · No / Yes
# 代码运行环境
√ Where does your code run? · browser
# 代码规范
? How would you like to define a style for your project? ...
# 使用一个流行的代码规范
> Use a popular style guide
> Standard: https://github.com/standard/standard
# 配置文件生成 js 类型的文件
√ What format do you want your config file to be in? · JavaScript
# ...

生成されたeslint設定ファイル:

// .eslintrc.js
module.exports = {
    
    
  env: {
    
    
    browser: true,
    es2021: true
  },
  extends: [
    'plugin:vue/essential',
    'standard'
  ],
  parserOptions: {
    
    
    ecmaVersion: 'latest',
    parser: '@typescript-eslint/parser',
    sourceType: 'module'
  },
  plugins: [
    'vue',
    '@typescript-eslint'
  ],
  rules: {
    
    
  }
}

私の個人的な習慣に基づいて、2 つのルールを変更しました。

rules: {
    
    
  // 要求或禁止函数圆括号之前有一个空格
  'space-before-function-paren': [2, {
    
    
    anonymous: 'always',
    named: 'never',
    asyncArrow: 'always'
  }],
  // 要求组件名(文件名)必须是多单词的
  'vue/multi-word-component-names': 0
}

package.json検証スクリプトを次の場所に追加します。

"scripts": {
    
    
  ...
  // 检查代码和自动修复
  "lint": "eslint src/**/*.{js,jsx,vue,ts,tsx} --fix"
},

npm run linteslint 検証を実行します。

# App.vue 和 components/HelloWorld.vue 验证失败,template 只能包含一个根节点
error  The template root requires exactly one element  vue/no-multiple-template-root

このルールは Vue 2 に適用されますが、Vue 3 にはこの制限はありません。eslint 設定ファイルで使用されているプラ​​グインをパッケージplugin:vue/assentialから表示し、ディレクトリを表示します (公式の紹介)。eslint-plugin-vueeslint-plugin-vue\lib

├─ base.js
├─ essential.js # 当前配置的验证规则
├─ no-layout-rules.js
├─ recommended.js
├─ strongly-recommended.js
# 以上是 Vue2 的验证规则
# 以下是 Vue3 的验证规则
├─ vue3-essential.js
├─ vue3-recommended.js
└─ vue3-strongly-recommended.js

Vue 3 の検証ルールとして eslint を構成します (この記事では最も厳密なものを使用します)。

// .eslintrc.js
module.exports = {
    
    
  ...
  extends: [
    // 'plugin:vue/essential',
    // 使用 vue3 规则
    'plugin:vue/vue3-strongly-recommended',
    'standard'
  ],
  ...
}

マクロをコンパイルし、defineProps、defineEmits、no-undef ルールの警告を表示する

再度実行しますnpm run lint:

# HelloWorld.vue 报错
error  'defineProps' is not defined    no-undef

definePropsと はdefineEmitsVue3 で定義されたコンパイラ マクロ (コンパイラ マクロ)で、 <script setup>(最外層) でのみ使用できます。インポートする必要はなく、<script setup>処理時にコンパイルされます。

ただし、eslint がチェックすると、未定義の変数として扱われ、エラーが報告されます。このエラーは、ファイルに表示してインポートできます。

import {
    
     defineProps, defineEmits } from 'vue'

または、eslint チェック時にグローバル変数として宣言します。

// .eslintrc.js
module.exports = {
    
    
  globals: {
    
    
    defineProps: "readonly",
    defineEmits: "readonly",
    defineExpose: "readonly",
    withDefaults: "readonly"
  },
  ...
}

eslint-plugin-vue 公式ソリューションを使用することもできます(ソース コードは上記のグローバル変数設定と同じです)。

// .eslintrc.js
module.exports = {
    
    
  env: {
    
    
    browser: true,
    es2021: true,
    // 添加:
    'vue/setup-compiler-macros': true
  },
  ...
}

vscode がエラーを報告する場合は、このルールがあるかどうかを確認してください。ない場合は、バージョンが古すぎる可能性があります。バージョンを更新できます (この記事でインストールされているバージョンは 8.5.0) Environment key "vue/setup-compiler-macros" is unknowneslint-plugin-vue

再度実行してもnpm run lint、エラーは報告されませんでした。

エディターの統合

エディターの統合では、主に次の 2 つの機能が実装されます。

  1. 仕様を満たしていないエラーメッセージの見方
  2. プロジェクトの ESLint ルールの要件に従ってフォーマットする方法

実装手順:

1. veturプラグイン(Vue2プラグイン)をアンインストール/無効化します。

2. volar プラグインをインストールします (Vue 言語機能 - Vue3 をサポートし、TypeScript プロンプトをサポートする vetur と同等)

3. ESLint プラグインをインストールする

このプラグインがインストールされ有効になっている限り、プロジェクト内の eslint 構成仕様が自動的に検索され、検証プロンプトが表示されます。

同時に、ESLint プラグインはフォーマット ツールを提供しますが、手動で設定する必要があります。ファイル環境設定 (ショートカット キー ) を開き、拡張子 ESLint を見つけてチェックし、ESLint フォーマット ツールを有効にしCtrl+,ますFormat: Enable。 :

ここに画像の説明を挿入

settings.jsonvscode を直接変更してを追加することもできます"eslint.format.enable": true

eslint.validate次に、 eslint がチェックできるファイル タイプを指定するオプションの構成を続けます(デフォルトではチェック.js.jsxファイルのみ)。

{
    
    
  "eslint.format.enable": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "vue"
  ],
  ...
}

次に、ファイル フォーマット ツールとして ESLint を選択し、フォーマットするファイルを開き、コード ビューを右クリックして、使用...ドキュメントをフォーマットし、デフォルト フォーマッタを設定...して、ESLint を選択します。

構成が完了したら、 を使用してAlt+Shift+Fドキュメントをフォーマットできます。

PS: ESLint プラグインをインストールして有効にし、構成ファイルを変更すると、IDE に再登録され、遅延が発生したり、表示されなくなる場合があります。変更後にリロードすることをお勧めしますCtrl+P>reload

git プリコミットフックを設定する

コミット前フックを構成し、開発およびビルド プロセスに lint コマンドを追加し、Git 送信前に lint 検証を実行して、非準拠のコードが Git リポジトリに送信されるのを防ぎます。

使用ツール: okonet/lint-staged

npx mrm@2 lint-staged
# 会安装两个 npm 包
#	husky - 提供 git 钩子功能,拦截 git 命令
#	lint-staged - 获取 git 暂存区中的代码进行lint验证

実行が完了すると、変更されますpackage.json

1. 2 つの npm パッケージをインストールしました

  • husky - git フック機能を提供します
  • lint-staged - lint 検証のために git ステージング領域のコードを取得します

2. スクリプトを追加する

依存関係をインストールした後、prepare を実行し、huskey コマンドを実行してフックをインストールします。これにより、プロジェクトのクローンを作成する各ユーザーが依存関係のインストール後に husky フックをローカルに初期化し、git を送信する前に全員が lint 検証を実行できるようになります。 。

npx mrm@2 lint-stagedこれは実行完了後にも実行されるhusky installため、それが.git配置されているディレクトリで実行する必要があります。そうしないと、エラーが報告され、見つけることができません.git

husky installハスキーを初期化するフック:

  1. (デフォルト).git/config設定してフック ディレクトリを変更します。hooksPath.git/hooks
  2. .huskyプロジェクトのルート ディレクトリの下にカスタム フック実行ファイルを保存するフォルダーを作成します。
"scripts": {
    
    
  ...
  "prepare": "husky install"
},

3. lint ステージング構成の追加

これに基づいて独自の lint コマンドを変更およびカスタマイズできます。

"lint-staged": {
    
    
  // 执行 eslint 命令验证 js 文件
  "*.js": "eslint --cache --fix"
}

着替える:

"lint-staged": {
    
    
  // 提交指定文件时执行 lint 脚本进行验证,如果有 fix 修复的内容会自动 git add
  "*.{js,jsx,vue,ts,tsx}": [
    "npm run lint"
  ]
}

これで、コマンドが実行されるとgit commit、最初に一時記憶領域内のコードをチェックするために lint が実行され、仕様を満たしていないコードがあった場合、そのコードは実行されませんgit commit

注: チームがコミット前フックを確実に実行するための前提条件は次のとおりです。

  1. husky install初期化フォルダーを実行し.husky、gitフックのディレクトリアドレスを設定します。
  2. プロジェクトには.husky/pre-commitフック実行ファイルが含まれているため、このファイルが git リポジトリに送信されることを確認してください。

開発および構築時のコード仕様の検証

実際、ESLint は vite によって開発されたコンパイルおよび構築プロセスに統合されており、リアルタイムの ESLint 検証を提供します。

現在、Vite は ESLint 関連のプラグインを提供していません。プラグインを自分で開発するか、他の人のプラグインを使用することができます。

公式 Web サイトのナビゲーション リンク - Awesome Vite には、Vite に関連する高品質のリソースがリストされています。gxmari007/vite-plugin-eslint の使用をお勧めします。

# 安装
npm install vite-plugin-eslint --save-dev

vite 設定ファイルにプラグインをロードします。

// vite.config.ts
import {
    
     defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'

// https://vitejs.dev/config/
export default defineConfig({
    
    
  plugins: [
    vue(),
    eslintPlugin({
    
    
      /* 配置选项 */
      // 禁用 eslint 缓存
      cache: false
    })
  ]
})

cacheキャッシュ機能をオフにすることをお勧めします。これは、eslint が検証に失敗したコードを修復した後でもキャッシュ内の結果を読み取る場合があり、eslint はすべてのファイルではなく、現在変更されているファイルのみを検証するため、キャッシュを使用しないことをお勧めします。影響が少ない。

再起動しますnpm run dev

開発フェーズでコードをコンパイルおよびビルドするときに、コマンド ライン ツールとページの両方が検証され、失敗メッセージが表示されるようになりました。そして本番環境構築時に検証することになります( npm run build)。

Gitコミット仕様

提出仕様の概要

参考:コミットメッセージと変更ログの書き込みガイド - Ruan Yifeng

Git はコードを送信するたびに、この送信の具体的な意味を説明するコミット メッセージを作成する必要があります。

git commit -m 'hello world'

Git自体はコミットメッセージの形式を必要としないので、気軽に書いてしまうと、履歴のコミットメッセージから履歴のコミット記録を取得する必要がある場合に非常に面倒になります。

チームの Git Commit メッセージ標準を統一します。これは、その後のコードレビュー、バージョンリリース、自動ログ生成などに便利です。詳細については、Ruan Yifeng の記事を参照してください。

現在最も人気があるのはAngular コミット仕様です

関連ツール:

  1. 作成ツール ( commitizen ) - 仕様に準拠したコミット メッセージの作成を支援します。(仕様に慣れればこのツールは必要ありません)
  2. 検証ツール ( commitlint ) - git フックを構成し、コミットする前にコミット メッセージが仕様を満たしているかどうかをツールを使用して検証します。
  3. ログ生成ツール ( conventional-changelog ) - git メタデータを通じてログを生成します。一般にオープン ソース プロジェクトで使用されます。

commitlint 検証ツールを構成する

# windows 下安装 cli 和 常用规范
npm install --save-dev @commitlint/config-conventional @commitlint/cli
# 配置 commitlint 使用常用规范
# 建议手动创建 commitlint.config.js 文件并填充内容,命令可能创建的并不是 utf8 编码的文件,eslint 会报错 `Parsing error: Invalid character`
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

# 安装和初始化 husky(上面配置 eslint 校验钩子时已经完成)
# npm i husky -D
# npx husky install

# 创建 commit-msg 钩子
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

./husky/commit-msgコマンドを使用してファイルを作成できない場合は、手動でファイルを作成し、次の情報を入力できます。

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no -- commitlint --edit $1

送信コマンドのテストを実行します。

git add .
git commit -m 'commitlint 配置巴拉巴拉巴拉'

検証に失敗しました:

ここに画像の説明を挿入

仕様メッセージ:

git commit -m 'chore: commitlint 配置巴拉巴拉巴拉'

認証が成功しました:

ここに画像の説明を挿入

Vite の TS 環境の説明

Vite はプロジェクト作成時に TypeScript 環境をすでに構成しています。詳細については公式ドキュメントを参照してください。

注意点をいくつか以下に挙げます。

TypeScript の型チェック

.tsVite はファイルの変換のみを実行し、型チェックは実行しません。

let count: number = 100
count = 200
// 不会报错
count = 'hello'
  • dev開発段階では、Vite は IDE が型チェックを行うように構成されていると想定しており、Vite 自体はこのタスクを担当しません。
  • buildvue-tsc --noEmitビルド段階では、次のコマンドによって型チェックが実行されます。

公式の vue-tsc (TypeScript を JavaScript に変換するためにesbuildを使用) は監視機能をサポートしていないため、開発段階でリアルタイムの型検証をサポートする適切なプラグインはありません。

型宣言

Vite がプロジェクトを作成すると、型宣言ファイルが生成されますsrc/env.d.ts(以前のバージョンは 2 つのファイルshimes-vue.d.tsvite-env.d.ts)。

/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
  const component: DefineComponent<{}, {}, any>
  export default component
}

最初の行は、クライアント コード環境に型宣言を追加するために使用されます。安全を期すために、公式の指示に従い、invite/clientの下に追加することをお勧めしますtsconfigcompilerOptions.types

{
    
    
  "compilerOptions": {
    
    
    "types": ["vite/client"]
  }
}

以下の内容はリソースファイルの型宣言を追加するものですが、デフォルトではTypeScriptがファイルを.vue認識しないため、 TypeScriptを使用してプロジェクトにVueコンポーネントをインポートする際にサフィックスを追加する必要があります。.vue.vue

Vue 3 での TS サポート

Vue の公式ドキュメント「Using Vue with TypeScript」では、 TypeScript をプロジェクトに統合する方法、推奨される構成、およびプロジェクトの作成時に Vite が完了したその他の内容が紹介されています。ここでは、TS の使用に関するいくつかの部分を紹介します。

1. 単一ファイルのコンポーネントで TypeScript を使用するには、タグに属性を<script>追加する必要があります。lang="ts"JSX を使用する場合に追加されますlang="tsx"

2. TypeScript がコンポーネント オプションの型を正しく推定するには、defineComponent()このグローバル API を通じてコン​​ポーネントを定義する必要があります。

import {
    
     defineComponent } from 'vue'

export default defineComponent({
    
    
  // 启用了类型推导
  props: {
    
    
    name: String,
    msg: {
    
     type: String, required: true }
  },
  data() {
    
    
    return {
    
    
      count: 1
    }
  },
  mounted() {
    
    
    this.name // 类型:string | undefined
    this.msg // 类型:string
    this.count // 类型:number
  }
})

3.<script setup>コンポジション API を組み合わせていない場合は、defineComponent()に渡されるsetup()prop の導出もサポートします。

import {
    
     defineComponent } from 'vue'

export default defineComponent({
    
    
  // 启用了类型推导
  props: {
    
    
    message: String
  },
  // 不需要声明 props 参数的类型
  setup(props) {
    
    
    props.message // 类型:string | undefined
  }
})

4. Vue3 は、PropTypeより複雑な prop タイプをマークするための補助ツールを提供します

import {
    
     defineComponent, PropType } from 'vue'

interface Book {
    
    
  title: string
  author: string
  year: number
}

export default defineComponent({
    
    
  props: {
    
    
    book: {
    
    
      // 提供相对 `Object` 更确定的类型
      type: Object as PropType<Book>,
      required: true
    },
    // 也可以标记函数
    callback: Function as PropType<(id: number) => void>
  },
  mounted() {
    
    
    this.book.title // string
    this.book.year // number

    // TS Error: argument of type 'string' is not
    // assignable to parameter of type 'number'
    this.callback?.('123')
  }
})

5. ref の型は初期化時の値に応じて推定され、手動で型を渡すこともできます。

<template>
  <h1 ref="title">
    {
   
   { msg }}
  </h1>
  <HelloWorld
    ref="hellowWorld"
    msg="Hello Vue 3 + TypeScript + Vite"
  />
</template>

<script lang="ts">
import {
      
       defineComponent, onMounted, ref } from 'vue'
import HelloWorld from '../components/HelloWorld.vue'

export default defineComponent({
      
      
  components: {
      
       HelloWorld },
  setup () {
      
      
    // 自动推断
    const msg = ref('Hello H1')

    // 指定 HTML 元素类型
    const title = ref<HTMLHeadElement>()

    // 指定实例类型
    const hellowWorld = ref<InstanceType<typeof HelloWorld>>()

    onMounted(() => {
      
      
      console.log(title.value?.innerHTML)
      console.log(hellowWorld.value?.$props.msg)
    })

    return {
      
      
      msg,
      title,
      hellowWorld
    }
  }
})
</script>

6. Reactive は ref と同じで、計算されたプロパティは自動的に型を推測します。

7. ネイティブ DOM イベント処理関数は、イベントに型アノテーションを追加することを推奨します。

<script setup lang="ts">
function handleChange(event: Event) {
      
      
  console.log((event.target as HTMLInputElement).value)
}
</script>

<template>
  <input type="text" @change="handleChange" />
</template>

Vue 3 の<script setup>構文

Vue 3 は、コンポーネントのロジックを記述する 3 つの方法をサポートしています。

オプションのAPI

オプションの API は Vue2 で採用されているスタイルです

<template>
  <h1>{
   
   { msg }}</h1>
  <button
    type="button"
    @click="increment"
  >
    count is: {
   
   { count }}
  </button>
</template>

<script lang="ts">
import {
      
       defineComponent } from 'vue'

export default defineComponent({
      
      
  name: 'HelloWorld',
  props: {
      
      
    msg: {
      
      
      type: String,
      default: ''
    }
  },
  data () {
      
      
    return {
      
      
      count: 0
    }
  },
  mounted () {
      
      
    console.log('Mounted')
  },
  methods: {
      
      
    increment () {
      
      
      this.count++
    }
  }
})
</script>

複合API

合成 API は、関連するロジックを一緒にカプセル化し、別個のモジュールとして抽出できます。

<script lang="ts">
import {
      
       defineComponent, ref } from 'vue'

export default defineComponent({
      
      
  name: 'HelloWorld',
  props: {
      
      
    msg: {
      
      
      type: String,
      default: ''
    }
  },
  setup () {
      
      
    const count = ref(0)
    const increment = () => {
      
      
      count.value++
    }

    return {
      
      
      count,
      increment
    }
  }
})
</script>

<script setup>

setup()複合 API を使用して作成されるビジネスの数が増えると、関数に大量のコードが集中し、一部の単純なビジネスではより多くのコードを記述する必要があることがわかります。このため、Vue 3 では後に<script setup>次の構文が導入されました。結合された API の糖衣構文。

<!--
  1. 可以认为 <script setup> 中的代码都会包裹在 setup() 函数中
  2. 并且只能使用组合式 API
  3. 不需要 export 导出对象
  4. 声明的变量和 props 会自动暴露出来,不需要 return
-->
<script setup lang="ts">
import {
      
       ref } from 'vue'

/* 定义 props */
const props = defineProps({
      
      
  msg: {
      
      
    type: String,
    default: ''
  }
})
console.log(props.msg)
// 模板中也可以通过 props.msg 访问
// 建议:变量取名 props,模板中使用 props 访问,便于阅读

/* 定义对外发布的自定义事件 */
const emit = defineEmits(['increment'])

/* 定义 data 和 methods */
const count = ref(0)
const increment = () => {
      
      
  count.value++

  // 对外发布事件
  emit('increment')
}

</script>

インポートされたコンポーネントは直接使用でき、コンポーネントの名前は自動的に推測されます。

<script setup>
import MyComponent from './MyComponent.vue'
import Foo from './Bar.vue'
</script>

<template>
  <MyComponent />
  <Foo />
</template>

トップレベルをサポートしますawait:

<script setup>
const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>

<script>で使用できます。<script setup>のコンテンツはexport default {}コードに変換され、<script>のコードとマージされます。

<script>
// 代码会追加到 <script setup> 生成的 export default {} 代码前
runSideEffectOnce()

// 如果也导出了对象,则会和 <script setup> 生成的 export default {} 导出的对象合并在一起
export default {
      
      
  inheritAttrs: false,
  customOptions: {
      
      }
}
</script>

<script setup>
// ...
</script>

詳細については、公式ドキュメントを参照してください。

<スクリプトセットアップ>でマクロをコンパイルします

<script setup>構文シュガー および ) で使用されるdefineProps() およびdefineEmits() はdefineExpose()単独で使用するwithDefaults()必要はありませんimport(および でのみ使用できます<script setup>)。

これらは実際にはコンパイルされたマクロとして定義されており、組み込み API として理解できます。

単一ファイルのコンポーネントは<script setup>コンパイル時に自動的に処理され、対応するコードに置き換えられます。

ESLint はデフォルトではこれらを認識しません。globalsこれらをグローバル API として認識するように ESLint を設定できます (前の「マクロのコンパイルと、defineProps、defineEmits、no-undef ルールの警告」を参照してください)。

変換 JSX および TSX の構成

公式ドキュメント:レンダリング関数と JSX | Vue.js (vuejs.org)

Vue3 は、公式プラグイン@vue/babel-plugin-jsxを通じてJSX サポートを提供できます。詳細な使用法についてはドキュメントを参照してください。

Vite によって作成されたプロジェクトはデフォルトでは JSX をサポートしていないため、個別に設定する必要があります。

Vite は公式に@vitejs/plugin-vue-jsxプラグイン構成 JSX サポートを提供します。これは実際に内部で使用されます@vue/babel-plugin-jsx

# 安装插件
npm i -D @vitejs/plugin-vue-jsx

プラグインを設定します。

// vite.config.ts
import {
    
     defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'
import vueJsx from '@vitejs/plugin-vue-jsx'

// https://vitejs.dev/config/
export default defineConfig({
    
    
  plugins: [
    vue(),
    eslintPlugin({
    
    
      /* 配置选项 */
      // 禁用 eslint 缓存
      cache: false
    }),
    vueJsx({
    
    
      /* 配置选项 */
    })
  ]
})

テスト:

<!-- src\components\HelloWorld.vue -->
<template>
  <comp />
</template>

<script setup lang="tsx">
const comp = <h1>Hello World</h1>
</script>

// src\components\Foo.tsx
// 选项式 API
import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    msg: {
      type: String,
      required: true
    }
  },
  render () {
    return <h2>{this.msg}</h2>
  }
})

// src\components\Bar.tsx
// 组合式 API
import { defineComponent } from 'vue'

interface PropsType {
  msg: string
}

export default defineComponent({
  props: {
    msg: {
      type: String,
      required: true
    }
  },
  setup() {
    // 官方还没有未这种方式的 props 参数添加类型推断
    // 需要手动声明 TS 类型
    return (props: PropsType) => <h2>{props.msg}</h2>
  }
})

<!-- src\App.vue -->
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
import Foo from './components/Foo'
import Bar from './components/Bar'
</script>

<template>
  <HelloWorld />
  <Foo msg="Hello Foo" />
  <Bar msg="Hello Bar" />
</template>

Vite でエイリアスを構成する

@Vite によって作成されたプロジェクトにはデフォルトでエイリアスが設定されていないため、手動で設定する必要があります。

// vite.config.ts
...
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
    
    
  ...
  resolve: {
    
    
    // https://vitejs.dev/config/#resolve-alias
    alias: [
      {
    
    
        find: '@',
        replacement: path.join(__dirname, 'src')
      }
    ]
  }
})

このとき、次のようimport path from 'path'なエラーが報告される場合があります。

ここに画像の説明を挿入

これは、 path が CommonJS 仕様に従っている Node.js モジュールであり、デフォルトではエクスポートされないためですexport default。実際、Babel は変換中にこのタイプのモジュールを自動的に追加しmodule.exports.default、IDE は型チェックでそれが認識されないことを示すプロンプトを表示します。

プロンプトに従って、このタイプのモジュール インポート操作を認識するようにTypeScriptallowSyntheticDefaultImportsを構成できます。true

vite.config.tsの TypeScript 設定は次の場所にあることに注意してくださいtsconfig.node.json

// tsconfig.node.json
{
    
    
  "compilerOptions": {
    
    
    "composite": true,
    "module": "esnext",
    "moduleResolution": "node",
    // 允许处理默认 import
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts"]
}

PS: をインストールすることでも識別できます@types/node

ファイルは次のようにインポートできるようになりました.vue

// JS 中使用
import HelloWorld from '@/components/HelloWorld.vue'

// HTML 中使用
<img src="@/assets/logo.png">
    
// css 中使用
background: url(@/assets/logo.png);

ただし.tsx、ファイルをインポートすると、TypeScript はエラーを報告します。

// 找不到模块“@/components/Foo”或其相应的类型声明。
import Foo from '@/components/Foo' // 省略了 .tsx 后缀

// 导入路径不能以“.tsx”扩展名结束。考虑改为导入“@/components/Bar.js”。
import Bar from '@/components/Bar.tsx'

baseUrlしたがって、TypeScript のインポート マッピング (と)も設定する必要がありますpaths

// tsconfig.json
{
    
    
  "compilerOptions": {
    
    
    ...

    // https://www.typescriptlang.org/tsconfig#paths
    // 必须定义 baseUrl
    "baseUrl": ".",
    // paths 设置相对于 baseUrl 的一系列映射路径
    "paths": {
    
    
      "@/*": ["src/*"]
    }
  },
  ...
}

エラーを報告するために明示的な拡張機能を使用する問題に関しては.tsx、拡張機能を使用しなくても十分です。

Viteで.vueインポートしたコンポーネントにサフィックスが必要な問題について

Vite はデフォルトでは拡張子を無視しません.vue。設定によって無視することもできますが、**「IDE とタイプのサポートに影響する」**ため、そうすることはお勧めできません。resolve.extensionsを参照してください。

また、You Da は Vite Issue #178で、インポート.vueファイルで **「意図的なデザイン」** というサフィックスを省略することはできず、次のメジャー バージョンでは、Vue CLI での拡張子なしの Vue インポートのサポートを停止すると述べました。

ここに画像の説明を挿入

.vueしたがって、拡張機能を使用して Vue コンポーネントをインポートすることをお勧めします。

おすすめ

転載: blog.csdn.net/u012961419/article/details/124299803