Configurar el enrutador Vue
El proyecto creado por Vite no integra Vue Router, y la integración debe instalarse manualmente.
Vue 3 utiliza la última versión de Vue Router v4.x.
# 安装
npm install vue-router@4
Cree un archivo de configuración de enrutamiento:
<!-- src\views\home\index.vue -->
<template>
<div>
首页
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
<!-- src\views\login\index.vue -->
<template>
<div>
登录
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
<!-- src\App.vue -->
<template>
<router-view />
</template>
<script setup lang="ts">
</script>
// src\router\index.ts
import {
createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes:RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: () => import('@/views/home/index.vue')
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login/index.vue')
}
]
const router = createRouter({
// history: createWebHashHistory(), // hash 路由模式
history: createWebHistory(), // history 路由模式
routes // 路由规则
})
export default router
// src\main.ts
import {
createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App)
.use(router)
.mount('#app')
Configurar administrador de estado Pinia
Introducción
Los proyectos creados por Vite no tienen una herramienta de gestión de estado integrada de forma predeterminada.
Antes de Vue 3, éramos más Vuex. La última versión de Vuex es la versión x4.x compatible con Vue2 y Vue3, pero la biblioteca de gestión estatal oficial de Vue3 se ha cambiado a Pinia (mantenida por el equipo central de Vue), y la El sitio web oficial de Vuex también emitió una declaración.
La razón de esto es que la API de Pinia es casi idéntica a lo que se describe en Vuex 5 RFC y lo hace mejor:
De hecho, Pinia es un producto originalmente destinado a explorar la próxima versión de Vuex, incorporando muchas de las ideas del equipo central para Vuex 5. Finalmente, nos dimos cuenta de que Pinia ya implementó la mayor parte de lo que queríamos ofrecer en Vuex 5 y decidimos convertirlo en nuestra nueva recomendación oficial.
En comparación con Vuex, Pinia proporciona una API más concisa y directa, y proporciona una API de estilo combinado y, lo que es más importante, proporciona una muy buena deducción de tipos cuando se usa TypeScript.
Pinia integrada
Instalar y registrar Pinia
npm install pinia
Cree la tienda raíz y pásela a la aplicación (tenga en cuenta que Pinia no define el contenido de inicialización al crear la instancia de la tienda):
// src\main.ts
import {
createApp } from 'vue'
import App from './App.vue'
import router from './router'
import {
createPinia } from 'pinia'
createApp(App)
.use(router)
.use(createPinia())
.mount('#app')
Definir tienda
Pinia defineStore()
define las tiendas usando , que devuelve una función para crear instancias de tiendas:
defineStore()
Requiere un úniconame
(también conocido comoid
) pasado como primer parámetro (obligatorio)defineStore()
Convención para usaruse...
como nombre de función (por ejemplouseCartStore
, )- La tienda definida por
defineStore()
es equivalente al Módulo en Vuex.
// src\store\index.ts
import {
defineStore } from 'pinia'
const useStore = defineStore('main', {
state: () => ({
count: 0
}),
getters: {
doubleCount(state) {
return state.count * 2
}
},
actions: {
increment() {
this.count++
}
}
})
export default useStore
usar
Una vez que se crea una instancia de la tienda, se puede acceder a ella directamente state
, getters
y actions
.
Pinia no tiene Mutaciones de Vuex y puede usar directamente métodos sincrónicos y asincrónicos en Acciones.
<!-- src\views\home\index.vue -->
<template>
<div>
首页
<button @click="store.increment">
{
{ store.count }} => {
{ store.doubleCount }}
</button>
</div>
</template>
<script setup lang="ts">
import useStore from '@/store'
const store = useStore()
</script>
usar sintaxis de desestructuración
Tenga en cuenta que store
es un reactive
objeto envuelto con , lo que significa que no necesita escribir al acceder state
y , al igual que en , no podemos desestructurarlo directamente:getters
.value
setup
props
<!-- src\views\home\index.vue -->
<template>
<div>
首页
<button @click="store.increment">
{
{ store.count }} => {
{ store.doubleCount }}
</button>
<div>count 永远是 0:{
{ count }}</div>
<div>doubleCount 永远是 0:{
{ doubleCount }}</div>
</div>
</template>
<script setup lang="ts">
import useStore from '@/store'
const store = useStore()
const {
count, doubleCount } = store
// 在 script-setup 中使用解构赋值要通过 defineExpose 暴漏出去
defineExpose({
count
})
</script>
Si desea utilizar la desestructuración y retener la reactividad, debe utilizar sotreToRefs()
el método:
<!-- src\views\home\index.vue -->
<template>
<div>
首页
<button @click="store.increment">
{
{ store.count }} => {
{ store.doubleCount }}
</button>
<div>count 将会同步更新:{
{ count }}</div>
<div>doubleCount 将会同步更新:{
{ doubleCount }}</div>
</div>
</template>
<script setup lang="ts">
import useStore from '@/store'
import {
storeToRefs } from 'pinia'
const store = useStore()
const {
count, doubleCount } = storeToRefs(store)
defineExpose({
count,
doubleCount
})
</script>
Nota: se pueden desestructurar directamente store
desde actions
, ya que están vinculados a store
sí mismos ( this
apuntan internamente a store
).
Una breve introducción a Pinia
Nota sobre la inferencia de tipo TS en Pinia
Pinia proporciona una buena compatibilidad con TypeScript de forma predeterminada, pero para obtener una inferencia de tipo completa, debe seguir algunas sugerencias de uso:
1. Declaración state
Se recomienda utilizar la función flecha, que inferirá automáticamente el tipo de atributo
Si usa una función que no sea de flecha, getters
use el parámetro para state
acceder a la propiedad que TypeScript no reconoce
const useStore = defineStore('main', {
// 使用非箭头函数定义
state() {
return {
count: 0
}
},
getters: {
// 使用 state 访问状态
doubleCount(state) {
// IDE 提示:类型“{} & {}”上不存在属性“count”。ts(2339)
return state.count * 2
}
},
actions: {
increment() {
// IDE 提示:类型“{} & {}”上不存在属性“count”。ts(2339)
this.count++
}
}
})
2. Para declarar la propiedad Getters, se recomienda usar state
parámetros para acceder al estado (función flecha o función no flecha). Aunque se pueden usar funciones no flecha this
, el tipo no se inferirá automáticamente (cuando no state
se definan parámetros formales). declarado, o el estado se define usando una función sin flecha)
- Para evitar el uso
this
, la recomendación oficial es usar funciones de flecha. store
Se recomienda usar solo cuando necesita obtener el valor completothis
, pero debe definir explícitamente el tipo de retorno de la función, TypeScript no inferirá automáticamente- Se recomienda no declarar parámetros formales
this
al utilizarstate
const useStore = defineStore('main', {
state: () => ({
count: 0
}),
getters: {
// 没有声明 `state` 形参
// IDE 提示:由于“doubleCount'”不具有返回类型批注并且在它的一个返回表达式中得到直接或间接引用,因此它隐式具有返回类型 "any"。ts(7023)
doubleCount() {
// IDE 提示:类型“{ doubleCount(): any; }”上不存在属性“count”。ts(2339)
return this.count * 2
},
// 解决办法1
doubleCount2(state) {
return this.count * 2
},
// 解决办法2
doubleCount3():number {
return this.count * 2
}
},
actions: {
increment() {
this.count++
}
}
})
Características básicas de Pinia
- Estado
- De forma predeterminada, a través
store
del acceso a la instanciastate
, puede leer y escribir directamente, como@click="store.count++"
store.$reset()
El método se puede utilizar parastate
restablecer el valor inicial.- Además de
store
la modificación directa,state
también se pueden enviarstore.$patch()
múltiples cambios a través del método, la principal diferencia es que se pueden agrupar múltiples cambios en una entrada en devtools y se admite el viaje en el tiempo. - Puede
store.$subscribe()
suscribirse a los cambios en el estado, y la suscripción solo se activará una vez que se modifiquen los parches. De forma predeterminada, las suscripciones están vinculadas al componente que lo agregó, se eliminan automáticamente cuando se desmonta el componente o se pueden configurar para conservarlas.
- De forma predeterminada, a través
- captadores
- El valor de la propiedad Getters es una función que acepta
state
como primer argumento, para fomentar el uso de funciones de flecha - Las funciones que no son de flecha estarán vinculadas
this
y se recomienda usarlas solo enstore
escenarios en los que se deba obtener la instancia completa y el tipo de retorno de la función se deba definir explícitamente.
- El valor de la propiedad Getters es una función que acepta
- Comportamiento
- Al igual que Gettes, se puede acceder
this
a toda lastore
instancia a través de - Las acciones pueden ser asíncronas o síncronas, de cualquier manera se devuelve una Promesa
- Las acciones pueden establecer parámetros libremente y devolver contenido, todo se inferirá automáticamente, sin necesidad de definir el tipo TS (¡guapo!)
- Al igual que Estado, puede
store.$onAction()
suscribirse a Acciones a través de , la devolución de llamada se activará antes de la ejecución, y puede pasar los parámetrosafter()
yonError()
permitir que la función se ejecute después de la resolución y el rechazo de la Acción. De manera similar, la suscripción está vinculada al componente actual.
- Al igual que Gettes, se puede acceder
Gestión de estilo CSS
Función - CSS | Vite Documentación oficial en chino
- Vite proporciona una versión mejorada
@import
que permite el uso de alias de Vite - Vite tiene PostCSS incorporado, si necesita una configuración adicional, solo proporcione
postcss.config.js
el archivo - Cualquier archivo CSS
.module.css
con un sufijo se considera un archivo de módulos CSS . La importación de dicho archivo devuelve un objeto de módulo correspondiente. - Vite proporciona soporte integrado para
.scss
,.sass
, y archivos. No es necesario instalar complementos de Vite específicos para ellos, pero sí deben instalarse las dependencias de preprocesador correspondientes..less
.styl
.stylus
Instale Sass e inicialice la estructura de directorios
Este ejemplo usa Sass:
npm i -D sass
Cree la estructura de directorios de estilo:
styles
├─ index.scss # 统一导出
├─ common.scss # 全局公共样式
├─ mixin.scss # 全局 mixin
├─ transition.scss # 全局过渡动画样式
└─ variables.scss # 全局 Sass 变量
// src\styles\variables.scss
$red: red;
$pink: pink;
// src\styles\common.scss
body {
background-color: $pink;
}
// src\styles\index.scss
@import './variables.scss';
@import './mixin.scss';
@import './transition.scss';
@import './common.scss';
Uso de variables de estilo global en componentes de un solo archivo
Las variables globales no se pueden usar directamente en componentes de un solo archivo y los archivos deben importarse manualmente:
<style lang="scss" scoped>
@import '@/styles/variables.scss';
div {
color: $red;
}
</style>
Es demasiado engorroso importar manualmente cada archivo. Puede usar la herramienta de compilación Vite para inyectar automáticamente variables globales en los módulos de estilo de los componentes de un solo archivo.
El elemento de configuración de Vite css.preprocessorOptions se usa para especificar las opciones que se pasan al preprocesador de CSS.
// vite.config.ts
...
export default defineConfig({
...
css: {
preprocessorOptions: {
// 给 sass-loader 传递选项
scss: {
// additionalData 的值就是要注入的字符串
additionalData: '@import "@/styles/variables.scss";'
}
}
}
})
Ahora el componente de un solo archivo se puede cambiar a:
<style lang="scss" scoped>
div {
color: $red;
}
</style>
Usando variables de estilo en Vue3
<style>
Vue 3 admite el enlace dinámico de variables de estilo en componentes de un solo archivo .
Variables que se pueden exponer a través de v-bind
componentes vinculantes, el principio es que cuando el compilador SFC detecta tales variables CSS, v-bind
las reescribirá como nativas con nombres de variables Hash var()
.
La definición de las variables de estilo css nativo se insertará en style
las propiedades de cada elemento DOM de nivel superior del componente.
<template>
<h1 class="title">Hello World</h1>
<p class="content">The content color is red</p>
</template>
<script setup lang="ts">
const theme = {
color: 'red',
fontSize: '30px'
}
</script>
<style>
.title {
color: v-bind('theme.color');
}
.content {
font-size: v-bind('theme.fontSize');
}
</style>
El DOM renderizado final del ejemplo anterior es el siguiente:
<h1 class="title" style="--5954443c-theme_color:red; --5954443c-theme_fontSize:30px;"> Hello World </h1>
<p class="content" style="--5954443c-theme_color:red; --5954443c-theme_fontSize:30px;"> The content color is red </p>
<style>
.title {
color: var(--5954443c-theme_color);
}
.content {
font-size: var(--5954443c-theme_fontSize);
}
</style>
No hay una introducción oficial a esta función, consulte rfcs/0043-sfc-style-variables para obtener más detalles.