Vue3+Vite+Ts Project Combat 01 Vite Create Project, configuración de ESLint+TS+GitCommit, introducción de nuevas características de Vue3

declaración hacia adelante:

  • Vue3 y Vite todavía se están actualizando y la documentación en chino aún no está completa. El contenido de esta nota puede quedar obsoleto en el futuro. Se recomienda consultar la documentación en inglés y utilizar la última versión.
  • El servicio de API de back-end utilizado en este caso se basa en Express y utiliza archivos json para administrar datos, almacenes Git y documentos de uso .
  • Este caso tiene como objetivo aprender Vite y Vue3 para construir aplicaciones de configuración y no desarrolla funciones comerciales completas.

Inicialización del proyecto

Crear un proyecto con Vite

Documentación oficial en chino de Vite (vitejs.dev)

Declaración oficial: Vite requiere una versión de Node.js >= 12.0.0. Sin embargo, algunas plantillas requieren una versión superior de Node para funcionar correctamente. Cuando su administrador de paquetes le avise, actualice su versión de Node.

En este ejemplo, la versión de Node.js 12 ejecuta el comando de compilación e informa de un error, por lo que en su lugar se utiliza la versión de Node.js 16. Recuerde cambiar de versión npm installpara evitar dependencias que no se han actualizado.

# 创建
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

accesohttp://localhost:3000/

Descripción de la estructura de directorio inicial

├─ 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"
  },
}

Acerca del motivo del error de compilación

Al escribir esta nota, la ejecución npm run buildreportará muchos errores:

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

La razón es que Vite recomienda oficialmente configurar la opción del compilador TypeScript: isolatedModules en 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" }]
}

Debido al error de compilación ocasionado por esto, el Problema no ha sido resuelto, por el momento solo se puede configurar falseo eliminar esta opción.

Agregar una estructura de directorio personalizada

srcAgregue algunas carpetas en el directorio :

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

Estándares de código y ESLint

ESLint no está integrado de forma predeterminada en los proyectos creados por Vite, y actualmente no hay contenido oficial relacionado con ESLint, por lo que se requiere la integración y configuración manual de ESLint.

Configuracion basica

# 安装 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
# ...

Archivo de configuración de eslint generado:

// .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: {
    
    
  }
}

Basado en mis hábitos personales, modifiqué dos reglas:

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

package.jsonAgregue un script de validación en:

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

npm run lintEjecute la validación de eslint:

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

Esta regla se aplica a Vue 2, Vue 3 no tiene esta limitación. Vea los complementos utilizados en el archivo de configuración de eslint plugin:vue/assential, desde eslint-plugin-vueel paquete, vea eslint-plugin-vue\libel directorio ( introducción oficial ):

├─ 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

Configure eslint como la regla de validación para Vue 3 (este artículo usa la más estricta):

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

Compila macros y defineProps, defineEmits, advertencias de reglas sin definición

correr de nuevo npm run lint:

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

definePropsy son macros de compilador ( compiler macros ) defineEmitsdefinidas por Vue3 , que solo se pueden usar en (la capa más externa), no es necesario importarlas y se compilarán cuando se procesen.<script setup><script setup>

Sin embargo, cuando eslint verifica, se trata como una variable indefinida y se informa un error, que se puede mostrar e importar en el archivo:

import {
    
     defineProps, defineEmits } from 'vue'

O declararlos como variables globales cuando eslint comprueba:

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

También puede usar la solución oficial eslint-plugin-vue (el código fuente es el mismo que la configuración de la variable global anterior):

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

Si vscode informa un error Environment key "vue/setup-compiler-macros" is unknown, verifique eslint-plugin-vuesi existe esta regla; de lo contrario, la versión puede ser demasiado antigua, puede actualizar la versión (la versión instalada en este artículo es 8.5.0).

Ejecutar de nuevo npm run lint, no se reporta ningún error.

Integración del editor

La integración del editor implementa principalmente dos funciones:

  1. Cómo ver el mensaje de error que no cumple con la especificación
  2. Cómo formatear de acuerdo con los requisitos de las reglas ESLint en el proyecto

Pasos de implementación:

1. Desinstalar/deshabilitar el complemento vetur (complemento Vue2)

2. Instale el complemento volar (Vue Language Features, equivalente a vetur que admite Vue3 y admite solicitudes de TypeScript)

3. Instale el complemento ESLint

Siempre que este complemento esté instalado y habilitado, encontrará automáticamente la especificación de configuración de eslint en el proyecto y le dará un mensaje de verificación.

Al mismo tiempo, el complemento ESLint proporciona una herramienta de formato, pero debe configurarse manualmente. Abra la configuración de preferencias de archivo (tecla de acceso directo Ctrl+,), busque la extensión-ESLint, verifíquela Format: Enabley habilite la herramienta de formato ESLint :

inserte la descripción de la imagen aquí

También puede modificar directamente vscode settings.json, agregar "eslint.format.enable": true.

Luego, continúe configurando eslint.validatelas opciones para especificar los tipos de archivo que eslint puede verificar (por defecto, solo cheques .jsy .jsxarchivos):

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

A continuación, seleccione la herramienta de formateo de archivos como ESLint, abra el archivo que desea formatear, haga clic con el botón derecho en la vista de código, use... formatee el documento, configure el formateador predeterminado... y seleccione ESLint.

Una vez completada la configuración, puede utilizar Alt+Shift+Fpara formatear el documento.

PD: Al instalar y habilitar el complemento ESLint, la modificación del archivo de configuración volverá a registrarse en el IDE, lo que puede provocar un retraso o incluso que no se visualice. Lo mejor es volver a cargar después de la modificación: , Ctrl+Pescriba>reload

Configurar gancho de confirmación previa de git

Configure el enlace de confirmación previa, agregue el comando lint al proceso de desarrollo y compilación, y realice una verificación de lint antes del envío de git para evitar que se envíe código no compatible al repositorio de git.

Herramientas utilizadas: okonet/lint-staged

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

Una vez completada la ejecución, se modificará package.json:

1. Instalé dos paquetes npm

  • husky: proporciona la funcionalidad de git hook
  • lint-staged: obtenga el código en el área de preparación de git para la verificación de pelusa

2. Agrega un guión

Después de instalar las dependencias, ejecute prepare, ejecute el comando huskey e instale el enlace para asegurarse de que cada persona que clone el proyecto inicialice el enlace husky en el local una vez que se instale la dependencia, para que todos puedan realizar la verificación de lint antes de enviar git .

npx mrm@2 lint-stagedTambién se ejecutará después de que se complete la ejecución husky install, por lo que debe .gitejecutarse en el directorio donde se encuentra, de lo contrario, informará de un error y no podrá encontrarlo .git.

husky installGancho que inicializará husky:

  1. Modifique el directorio de ganchos configurando .git/configen hooksPath(predeterminado .git/hooks)
  2. Cree una carpeta en el directorio raíz del proyecto .huskypara almacenar archivos de ejecución de ganchos personalizados
"scripts": {
    
    
  ...
  "prepare": "husky install"
},

3. Configuración por etapas de pelusa agregada

Puedes modificar y personalizar tu propio comando lint sobre esta base:

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

cambie a:

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

Ahora, cuando se ejecuta el comando git commit, primero se ejecutará lint para verificar el código en el área de almacenamiento temporal, y si algún código no cumple con la especificación, no se ejecutará git commit.

Nota: Los requisitos previos para garantizar que el equipo ejecutará el gancho de confirmación previa son:

  1. Ejecute la carpeta husky installde inicialización .huskyy configure la dirección del directorio de git hooks
  2. El proyecto contiene .husky/pre-commitel archivo de ejecución del enlace, así que asegúrese de que este archivo se envíe al repositorio de git

Verificación de la especificación del código durante el desarrollo y la construcción

De hecho, ESLint está integrado en el proceso de compilación y construcción desarrollado por vite para proporcionar verificación de ESLint en tiempo real.

Actualmente, Vite no proporciona complementos relacionados con ESLint. Puede desarrollar un complemento usted mismo o usar el de otra persona.

Enlaces de navegación del sitio web oficial: Awesome Vite enumera algunos recursos de alta calidad relacionados con Vite. Se recomienda usar gxmari007/vite-plugin-eslint

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

Cargue el complemento en el archivo de configuración de 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
    })
  ]
})

cacheSe recomienda desactivar la función de almacenamiento en caché, porque a veces eslint aún puede leer los resultados en el caché después de reparar el código que falla en la verificación, y eslint solo verificará el archivo modificado actualmente, no todos los archivos, por lo que no usar el caché tiene poco impacto

reiniciar npm run dev_

Ahora, al compilar y crear el código en la fase de desarrollo, tanto la herramienta de línea de comandos como la página verificarán y mostrarán un mensaje de error. Y se verificará al construir el entorno de producción ( npm run build).

Especificación de confirmación de Git

Introducción a las especificaciones de presentación

Referencia: Guía de escritura de mensajes de confirmación y registro de cambios - Ruan Yifeng

Cada vez que Git envía código, debe escribir un mensaje de confirmación para explicar el significado específico de este envío.

git commit -m 'hello world'

Git en sí mismo no requiere el formato del mensaje de Confirmación. Si lo escribe de manera casual, será muy problemático cuando necesite recuperar un registro de confirmación en el historial a través del mensaje de Confirmación en el historial.

Unifique el estándar de mensajes Git Commit del equipo, que es conveniente para la revisión posterior del código, el lanzamiento de la versión y la generación automática de registros, etc. Para obtener más información, consulte el artículo de Ruan Yifeng.

Actualmente, la más popular es la especificación de confirmación angular.

Herramientas relacionadas:

  1. Herramienta de redacción ( commitizen ): ayuda a redactar mensajes de confirmación que se ajusten a la especificación. (Cuando te acostumbres a las especificaciones, no necesitarás esta herramienta)
  2. Herramienta de verificación ( commitlint ): configure ganchos de git, use la herramienta para verificar si el mensaje de confirmación cumple con la especificación antes de confirmar
  3. Herramienta de generación de registros ( registro de cambios convencional ): genere registros a través de metadatos de git, generalmente utilizados por proyectos de código abierto

Configurar la herramienta de validación de 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"'

Si ./husky/commit-msgel archivo no se puede crear con el comando, se puede crear manualmente y completar con lo siguiente:

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

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

Ejecute la prueba de comando de envío:

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

Fallo en la verificación:

inserte la descripción de la imagen aquí

mensaje de especificación:

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

Autenticación exitosa:

inserte la descripción de la imagen aquí

Descripción del entorno TS en Vite

Vite ya configuró el entorno TypeScript al crear el proyecto, consulte la documentación oficial para obtener más detalles .

A continuación se enumeran algunos puntos a tener en cuenta.

Comprobación de tipos de TypeScript

Vite solo realiza .tsla traducción del archivo y no realiza ninguna verificación de tipo.

let count: number = 100
count = 200
// 不会报错
count = 'hello'
  • devDurante la fase de desarrollo, Vite asume que el IDE está configurado con verificación de tipo y Vite no es responsable de esta tarea.
  • buildvue-tsc --noEmitDurante la fase de construcción, la verificación de tipo se realizará a través del comando

Dado que el vue-tsc oficial (que usa esbuild para traducir TypeScript a JavaScript) no es compatible con la función de monitoreo, no hay un buen soporte de complemento para la verificación de tipo en tiempo real durante la etapa de desarrollo.

declaración de tipo

Cuando Vite crea un proyecto, generará un src/env.d.tsarchivo de declaración de tipo (la versión anterior tenía dos archivos shimes-vue.d.tsy vite-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
}

La primera línea se usa para agregar la declaración de tipo en el entorno del código del cliente. Para estar seguro, se recomienda seguir las instrucciones oficiales y agregarlo vite/clientdebajo tsconfigde compilerOptions.types:

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

El siguiente contenido es para .vueagregar una declaración de tipo para el archivo de recursos, ya que TypeScript no reconoce .vueel archivo de manera predeterminada, por lo que al importar componentes de Vue en un proyecto que usa TypeScript, .vuese debe agregar el sufijo.

Compatibilidad con TS en Vue 3

El documento oficial de Vue "Uso de Vue con TypeScript" presenta cómo integrar TypeScript en el proyecto, la configuración recomendada y algún otro contenido que Vite completó al crear el proyecto. Aquí hay algunas partes sobre el uso de TS.

1. Para usar TypeScript en un componente de un solo archivo, debe <script>agregar lang="ts"el atributo a la etiqueta. Agregado si se usa JSX lang="tsx".

2. Para que TypeScript deduzca correctamente los tipos en las opciones de componentes, debemos defineComponent()definir los componentes a través de esta API global.

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. Cuando <script setup>la API de composición no se combina, también admite la derivación de la prop defineComponent()pasada asetup()

import {
    
     defineComponent } from 'vue'

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

4. Vue3 proporciona PropTypeherramientas auxiliares para marcar tipos de accesorios más complejos

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. El tipo de ref se deducirá de acuerdo con el valor en el momento de la inicialización, y el tipo también se puede pasar manualmente.

<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. Reactivo es lo mismo que ref, y la propiedad calculada inferirá automáticamente el tipo.

7. La función de procesamiento de eventos del DOM nativo recomienda agregar anotaciones de tipo al evento.

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

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

<script setup>Sintaxis en Vue 3

Vue 3 admite tres formas de escribir la lógica de los componentes:

API opcional

API opcional es el estilo adoptado por 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 compuesta

Las API de composición pueden encapsular la lógica relacionada para su extracción como módulos separados

<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>

Cuando aumenta la cantidad de empresas escritas con la API combinada, encontrará que una gran cantidad de código se concentra en setup()la función y algunas empresas simples necesitan escribir más código. Por esta razón, Vue 3 introdujo más tarde <script setup>la sintaxis, que es el azúcar sintáctico de la API combinada.

<!--
  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>

Los componentes importados se pueden usar directamente y el nombre del componente se deducirá automáticamente:

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

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

Admite nivel superior await:

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

Se puede <script>usar con , <script setup>el contenido de se convertirá en export default {}código y <script>se fusionará con el código de .

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

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

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

Para obtener más información, consulte la documentación oficial.

compilar macros en <configuración de script>

<script setup>Los defineProps() y defineEmits() usados ​​en azúcar sintáctico , y defineExpose()y withDefaults()) no necesitan importusarse solos (y solo pueden <script setup>usarse en ).

En realidad, se definen como macros compiladas , que pueden entenderse como API integradas.

Los componentes de un solo archivo <script setup>se procesan automáticamente en tiempo de compilación, reemplazándolos con el código correspondiente.

ESLint no los reconoce de forma predeterminada, y puede configurar ESLint globalspara que los reconozca como API globales (consulte las "advertencias de compilación de macros y defineProps, defineEmits, no-undef" anteriores).

Configurar Transformar JSX y TSX

Documentación oficial: funciones de procesamiento y JSX | Vue.js (vuejs.org)

Vue3 puede proporcionar compatibilidad con JSX a través del complemento oficial @vue/babel-plugin-jsx , consulte la documentación para obtener información detallada sobre el uso.

Los proyectos creados por Vite no son compatibles con JSX de forma predeterminada y deben configurarse por separado.

Vite proporciona oficialmente soporte JSX de configuración del complemento @vitejs/plugin-vue-jsx , que en realidad se usa internamente @vue/babel-plugin-jsx

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

Configurar el complemento:

// 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({
    
    
      /* 配置选项 */
    })
  ]
})

prueba:

<!-- 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>

Configurar alias en Vite

El proyecto creado por Vite no tiene @un alias configurado por defecto y debe configurarse manualmente.

// 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')
      }
    ]
  }
})

En este momento, import path from 'path'se puede informar un error:

inserte la descripción de la imagen aquí

Esto se debe a que path es un módulo node.js que sigue la especificación CommonJS y no se exporta de manera predeterminada export defaultDe hecho, Babel agrega automáticamente este tipo de módulo durante la conversión module.exports.defaulty el IDE indica que la verificación de tipo no lo reconoce.

allowSyntheticDefaultImportsDe acuerdo con el mensaje, puede configurar TypeScript truepara reconocer este tipo de operación de importación de módulos.

Tenga en cuenta vite.config.tsque la configuración de TypeScript para está en tsconfig.node.json:

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

PD: También se puede @types/nodeidentificar instalando .

El archivo ahora se puede importar así .vue:

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

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

Pero al importar .tsxel archivo, TypeScript informará un error:

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

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

Por lo tanto, también debe configurar la asignación de importación de TypeScript ( baseUrly paths):

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

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

En cuanto al problema de usar .tsxextensiones explícitas para reportar errores, es suficiente no usar extensiones.

.vueRespecto al tema de que los componentes importados deben tener sufijos en Vite

Vite no ignora .vuela extensión de forma predeterminada. Aunque puede ignorarse mediante la configuración, no se recomienda hacerlo porque **"afectará a IDE y admitirá tipos"**, consulte resolve.extensions

You Da también declaró en Vite Issue #178 que el .vuearchivo de importación no puede omitir el sufijo, que es **"diseño intencional"**, y en la próxima versión principal, dejará de admitir la importación de Vue sin extensión en Vue CLI.

inserte la descripción de la imagen aquí

Por lo tanto, se recomienda importar componentes de Vue con .vuela extensión.

Supongo que te gusta

Origin blog.csdn.net/u012961419/article/details/124299803
Recomendado
Clasificación