前端全栈修炼手册:从 Vue3 到工程化的进阶之路

本文将全方位覆盖前端开发的核心知识,从 Vue3 框架的基础语法到复杂的工程化实践,从包管理工具的使用到模块规范的深入理解,带你踏上从入门到精通的进阶之路。

Vue3 框架:新时代前端开发的基石

Vue3 核心语法探秘

Vue3 作为目前最流行的前端框架之一,带来了诸多令人兴奋的新特性和语法改进。其中,组合式 API(Composition API)的引入堪称革命性的变化,它让代码组织更加灵活,逻辑复用更加便捷。

setup函数作为组合式 API 的入口点,替代了 Vue2 中的data、methods等选项。在script setup语法糖的加持下,我们的代码变得更加简洁高效。

javascript 复制代码
<template>

<div class="user-card">

<h2>{{ userInfo.name }}</h2>

<p>年龄:{{ userInfo.age }}</p>

<button @click="incrementAge">增长年龄</button>

</div>

</template>

<script setup>

import { reactive } from 'vue'

// 响应式对象

const userInfo = reactive({

name: 'Allen',

age: 28

})

// 方法定义

const incrementAge = () => {

userInfo.age++

}

</script>

在响应式系统方面,Vue3 摒弃了 Vue2 中使用的Object.defineProperty,转而采用Proxy实现响应式。这一改变带来了诸多优势,比如能够检测对象的新增和删除属性,支持数组索引修改和length变化,以及兼容 Map、Set 等复杂数据结构。

Vue3 提供了ref和reactive两种创建响应式数据的方式。ref适用于基础数据类型,而reactive则更适合对象类型。通过toRefs函数,我们可以将reactive创建的响应式对象解构为多个响应式的ref,方便在模板中使用。

javascript 复制代码
import { ref, reactive, toRefs } from 'vue'

// 基础类型响应式

const count = ref(0)

console.log(count.value) // 访问值需使用.value

// 对象类型响应式

const user = reactive({

name: 'Allen',

age: 28

})

// 解构响应式对象

const { name, age } = toRefs(user)

Vue3 生命周期详解

生命周期是 Vue 组件从创建到销毁的整个过程,理解生命周期对于正确管理组件状态和资源至关重要。Vue3 的生命周期钩子函数与 Vue2 相比有所变化,并且需要从vue包中导入使用。

|-----------------|---------------|-----------------------|--------------------|
| 组合式 API 钩子 | 对应 Vue2 选项式钩子 | 执行时机 | 主要用途 |
| onBeforeMount | beforeMount | 组件挂载到 DOM 前 | 可进行挂载前的最后准备工作 |
| onMounted | mounted | 组件挂载到 DOM 后 | 执行 DOM 操作、初始化第三方库等 |
| onBeforeUpdate | beforeUpdate | 数据更新,DOM 重新渲染前 | 获取更新前的 DOM 状态 |
| onUpdated | updated | DOM 重新渲染后 | 处理更新后的 DOM 操作 |
| onBeforeUnmount | beforeDestroy | 组件卸载前 | 清理定时器、事件监听等资源 |
| onUnmounted | destroyed | 组件卸载后 | 完成最终清理工作 |
| onErrorCaptured | - | 捕获子组件错误时 | 错误处理和日志记录 |
| onActivated | - | 组件被激活时(配合 KeepAlive) | 恢复组件状态 |
| onDeactivated | - | 组件被停用时代(配合 KeepAlive) | 保存组件状态 |

下面是一个使用生命周期钩子的示例:

javascript 复制代码
import { onMounted, onUnmounted } from 'vue'

onMounted(() => {

// 组件挂载后初始化定时器

const timer = setInterval(() => {

console.log('定时器执行中...')

}, 1000)

// 在组件卸载前清理定时器

onUnmounted(() => {

clearInterval(timer)

})

})

组件通信方式全解析

在 Vue3 中,组件通信方式更加丰富和灵活,满足不同场景下的需求。

  1. 父子组件通信:使用defineProps和defineEmits

    javascript 复制代码
    <!-- 子组件 Child.vue -->
    
    <template>
    
    <div>
    
    <p>{{ message }}</p>
    
    <button @click="handleClick">点击传递事件</button>
    
    </div>
    
    </template>
    
    <script setup>
    
    // 定义接收的props
    
    const props = defineProps({
    
    message: String
    
    })
    
    // 定义发出的事件
    
    const emit = defineEmits(['update:message'])
    
    const handleClick = () => {
    
    emit('update:message', '来自子组件的消息')
    
    }
    
    </script>
  2. 跨层级通信:使用provide和inject

    javascript 复制代码
    <!-- 祖先组件 Ancestor.vue -->
    
    <script setup>
    
    import { provide } from 'vue'
    
    // 提供数据
    
    provide('theme', 'dark')
    
    // 提供方法
    
    provide('changeTheme', (newTheme) => {
    
    console.log('主题已切换为:', newTheme)
    
    })
    
    </script>
    
    <!-- 深层子组件 DeepChild.vue -->
    
    <script setup>
    
    import { inject } from 'vue'
    
    // 注入数据
    
    const theme = inject('theme', 'light') // 第二个参数为默认值
    
    // 注入方法
    
    const changeTheme = inject('changeTheme')
    
    </script>
  3. 兄弟组件通信:可以通过共同的父组件中转,或使用状态管理工具

  4. 全局状态管理:使用 Pinia(Vue3 推荐的状态管理库)

构建工具:前端工程化的核心引擎

Vue CLI:快速搭建 Vue 项目

Vue CLI 是 Vue 官方提供的脚手架工具,基于 Webpack 构建,能够快速搭建 Vue 项目骨架。

bash 复制代码
# 安装Vue CLI

npm install -g @vue/cli

# 创建新项目

vue create my-vue-project

# 启动开发服务器

cd my-vue-project

npm run serve

Vue CLI 提供了丰富的配置选项和插件生态,支持各种开发需求,但随着 Vite 的崛起,它在新建项目中的使用率有所下降。

Vite:极速开发体验的代名词

Vite 是新一代前端构建工具,由 Vue 作者尤雨溪开发,旨在提供极速的开发体验。

bash 复制代码
# 创建Vite项目

npm create vite@latest my-vite-project -- --template vue

# 进入项目目录

cd my-vite-project

# 安装依赖

npm install

# 启动开发服务器

npm run dev

Vite 的核心优势在于:

  1. 开发环境无需打包,基于原生 ES 模块提供服务
  1. 极速的热模块替换(HMR),修改代码即时生效
  1. 生产环境使用 Rollup 打包,构建产物体积更小
  1. 内置对 TypeScript、JSX、CSS 预处理器的支持

Vite 配置文件(vite.config.js)示例:

javascript 复制代码
import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'

export default defineConfig({

plugins: [vue()],

server: {

port: 3000,

proxy: {

'/api': {

target: 'http://localhost:8080',

changeOrigin: true,

rewrite: (path) => path.replace(/^\/api/, '')

}

}

},

build: {

outDir: 'dist',

assetsDir: 'assets'

}

})

Webpack:功能强大的模块打包器

Webpack 是目前使用最广泛的前端打包工具,虽然配置相对复杂,但功能极其强大,适用于各种复杂项目。

Webpack 核心配置(webpack.config.js)示例:

javascript 复制代码
const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const { VueLoaderPlugin } = require('vue-loader')

module.exports = {

entry: './src/main.js',

output: {

path: path.resolve(__dirname, 'dist'),

filename: 'js/[name].[contenthash].js',

clean: true

},

module: {

rules: [

{

test: /\.vue$/,

use: 'vue-loader'

},

{

test: /\.js$/,

exclude: /node_modules/,

use: {

loader: 'babel-loader',

options: {

presets: ['@babel/preset-env']

}

}

},

{

test: /\.css$/,

use: ['style-loader', 'css-loader', 'postcss-loader']

},

{

test: /\.(png|jpe?g|gif|svg)$/,

type: 'asset/resource',

generator: {

filename: 'images/[name].[hash:8][ext]'

}

}

]

},

plugins: [

new HtmlWebpackPlugin({

template: './public/index.html',

filename: 'index.html'

}),

new VueLoaderPlugin()

],

optimization: {

splitChunks: {

chunks: 'all',

cacheGroups: {

vendor: {

test: /[\\/]node_modules[\\/]/,

name: 'vendors',

chunks: 'all'

}

}

}

},

devServer: {

port: 8080,

hot: true,

open: true

}

}

Webpack 的主要概念包括入口(entry)、输出(output)、加载器(loader)、插件(plugin)和模式(mode)等,掌握这些概念对于配置和优化 Webpack 至关重要。

包管理工具:项目依赖的管家

npm:前端包管理的基石

npm(Node Package Manager)是 Node.js 默认的包管理工具,也是目前世界上最大的软件注册表。

常用 npm 命令:

bash 复制代码
# 初始化项目

npm init -y

# 安装依赖包(生产环境)

npm install package-name

# 安装依赖包(开发环境)

npm install package-name --save-dev

# 全局安装

npm install -g package-name

# 卸载依赖

npm uninstall package-name

# 更新依赖

npm update package-name

# 运行脚本

npm run script-name

# 查看依赖树

npm ls

npm 通过package.json文件管理项目依赖和脚本,package-lock.json文件则用于锁定依赖版本,确保在不同环境下安装的依赖版本一致。

pnpm:高性能的包管理器

pnpm 是新一代的包管理工具,相比 npm 和 yarn,具有更快的安装速度和更高效的磁盘利用。

pnpm 的核心优势:

  1. 采用内容寻址存储,相同版本的包只存储一次
  2. 使用硬链接和符号链接实现依赖共享,节省磁盘空间
  3. 支持 monorepo 项目结构,便于管理多包项目
  4. 严格的依赖隔离,避免版本冲突

常用 pnpm 命令:

bash 复制代码
# 安装pnpm

npm install -g pnpm

# 初始化项目

pnpm init

# 安装依赖

pnpm add package-name

# 安装开发依赖

pnpm add -D package-name

# 全局安装

pnpm add -g package-name

# 卸载依赖

pnpm remove package-name

# 更新依赖

pnpm update package-name

# 运行脚本

pnpm run script-name

对于 monorepo 项目,pnpm 通过pnpm-workspace.yaml文件进行配置:

bash 复制代码
# pnpm-workspace.yaml

packages:

- 'packages/*'

- 'apps/*'

- 'components/*'

YAML:简洁高效的配置文件格式

YAML 是一种直观的数据序列化格式,常用于配置文件,相比 JSON 更加简洁易读。

YAML 的基本语法规则:

  1. 使用缩进表示层级关系
  2. 使用key: value格式表示键值对
  3. 字符串可以不加引号
  4. 使用#表示注释
  5. 数组使用-开头

示例(docker-compose.yml):

bash 复制代码
version: '3'

services:

web:

build: .

ports:

- "8080:80"

volumes:

- ./src:/app/src

environment:

- NODE_ENV=development

depends_on:

- api

api:

image: node:16

command: npm run dev

volumes:

- ./api:/app

在前端项目中,YAML 常用于 CI/CD 配置、Docker 配置、服务编排等场景。

模块规范:CommonJS 与 ES Modules

CommonJS(CJS):Node.js 的模块规范

CommonJS 是 Node.js 采用的模块规范,主要用于服务器端 JavaScript。

CJS 模块导出:

javascript 复制代码
// math.js

const add = (a, b) => a + b

const subtract = (a, b) => a - b

// 导出方式1

module.exports = {

add,

subtract

}

// 导出方式2

exports.add = add

exports.subtract = subtract

CJS 模块导入:

javascript 复制代码
// app.js

// 导入整个模块

const math = require('./math.js')

console.log(math.add(2, 3)) // 5

// 解构导入

const { subtract } = require('./math.js')

console.log(subtract(5, 2)) // 3

// 导入内置模块或第三方模块

const fs = require('fs')

const lodash = require('lodash')

CJS 的特性:

  1. 运行时加载:模块在代码执行到require语句时才加载
  2. 同步加载:require是同步操作,会阻塞后续代码执行
  3. 模块缓存:模块第一次加载后会被缓存,再次加载直接使用缓存
  4. 值拷贝:对于基本类型是值的拷贝,对于对象是引用

ES Modules(ESM):浏览器和现代 JS 的模块规范

ES Modules 是 ECMAScript 标准的模块规范,现已被大多数浏览器和 Node.js 支持。

ESM 模块导出:

javascript 复制代码
// math.js

// 命名导出

export const add = (a, b) => a + b

export const subtract = (a, b) => a - b

// 默认导出

export default {

multiply: (a, b) => a * b,

divide: (a, b) => a / b

}

ESM 模块导入:

javascript 复制代码
// app.js

// 导入命名导出

import { add, subtract } from './math.js'

console.log(add(2, 3)) // 5

// 导入默认导出

import calculator from './math.js'

console.log(calculator.multiply(2, 3)) // 6

// 重命名导入

import { add as sum } from './math.js'

// 导入所有命名导出

import * as math from './math.js'

// 动态导入

import('./math.js').then(math => {

console.log(math.subtract(5, 2)) // 3

})

在 HTML 中使用 ESM:

html 复制代码
<script type="module" src="./app.js"></script>

ESM 的特性:

  1. 静态分析:导入导出在编译时确定,支持 Tree-shaking
  2. 异步加载:模块加载不会阻塞 HTML 解析
  3. 动态绑定:导入的模块内容与导出模块保持动态关联
  4. 严格模式:默认运行在严格模式下

CJS 与 ESM 的主要区别

|---------|--------------------------|----------------|
| 特性 | CommonJS | ES Modules |
| 语法 | require()/module.exports | import/export |
| 加载时机 | 运行时动态加载 | 编译时静态分析 |
| 加载方式 | 同步加载 | 异步加载 |
| 模块输出 | 值的拷贝 / 引用 | 动态绑定的引用 |
| 适用环境 | Node.js | 浏览器和现代 Node.js |
| 顶层 this | 指向module.exports | 指向undefined |
| 循环依赖 | 基于缓存的部分加载 | 基于引用的实时绑定 |

在实际开发中,我们可以通过 Babel、Webpack、Vite 等工具实现两种模块规范的互操作和转换。

常用前端工具库:提升开发效率的利器

Axios:强大的 HTTP 客户端

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 中发送 HTTP 请求。

基本使用:

javascript 复制代码
import axios from 'axios'

// 基本GET请求

axios.get('/api/users')

.then(response => {

console.log(response.data)

})

.catch(error => {

console.error(error)

})

// POST请求

axios.post('/api/users', {

name: 'Allen',

age: 28

})

.then(response => {

console.log('用户创建成功')

})

.catch(error => {

console.error('创建失败', error)

})

创建实例并配置拦截器:

javascript 复制代码
import axios from 'axios'

// 创建实例

const api = axios.create({

baseURL: 'https://api.example.com',

timeout: 5000,

headers: {

'Content-Type': 'application/json'

}

})

// 请求拦截器

api.interceptors.request.use(

config => {

// 添加认证token

const token = localStorage.getItem('token')

if (token) {

config.headers.Authorization = `Bearer ${token}`

}

return config

},

error => {

return Promise.reject(error)

}

)

// 响应拦截器

api.interceptors.response.use(

response => {

return response.data

},

error => {

// 处理错误

if (error.response && error.response.status === 401) {

// 未授权,跳转到登录页

location.href = '/login'

}

return Promise.reject(error)

}

)

// 使用实例

api.get('/users')

.then(data => {

console.log(data)

})

Lodash:实用的 JavaScript 工具库

Lodash 提供了大量实用的函数,简化了数组、对象、字符串等数据类型的操作。

常用功能示例:

javascript 复制代码
import { debounce, throttle, cloneDeep, get, set } from 'lodash'

// 防抖:频繁触发后,只执行最后一次

const handleSearch = debounce((keyword) => {

console.log('搜索:', keyword)

}, 300)

// 节流:指定时间内只执行一次

const handleScroll = throttle(() => {

console.log('滚动事件')

}, 100)

// 深拷贝

const obj = { a: 1, b: { c: 2 } }

const objCopy = cloneDeep(obj)

// 安全获取对象属性

const user = { info: { name: 'Allen' } }

const userName = get(user, 'info.name', 'Guest') // 'Allen'

const age = get(user, 'info.age', 0) // 0

// 设置对象属性

set(user, 'info.age', 28)

console.log(user.info.age) // 28

Date-fns:现代 JavaScript 日期工具库

Date-fns 是一个轻量级的日期处理库,提供了大量处理日期的函数。

常用功能示例:

javascript 复制代码
import { format, addDays, differenceInDays, parseISO } from 'date-fns'

// 格式化日期

const today = new Date()

console.log(format(today, 'yyyy-MM-dd')) // 2023-10-15

console.log(format(today, 'MMMM do, yyyy')) // October 15th, 2023

// 日期计算

const tomorrow = addDays(today, 1)

console.log(format(tomorrow, 'yyyy-MM-dd')) // 2023-10-16

// 日期差计算

const nextWeek = addDays(today, 7)

console.log(differenceInDays(nextWeek, today)) // 7

// 解析ISO格式日期

const isoDate = '2023-12-25T08:00:00Z'

const date = parseISO(isoDate)

console.log(format(date, 'yyyy年MM月dd日')) // 2023年12月25日

核心概念:前端开发的基石

Cookie:客户端存储的基础

Cookie 是存储在客户端的小型文本数据,常用于身份认证、会话管理等。

操作 Cookie 的工具函数:

javascript 复制代码
// 设置Cookie

function setCookie(name, value, days = 7, path = '/') {

const date = new Date()

date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000))

const expires = `expires=${date.toUTCString()}`

document.cookie = `${name}=${encodeURIComponent(value)}; ${expires}; path=${path}; SameSite=Lax`

}

// 获取Cookie

function getCookie(name) {

const nameEQ = `${name}=`

const cookies = document.cookie.split(';')

for (let i = 0; i < cookies.length; i++) {

let cookie = cookies[i].trim()

if (cookie.indexOf(nameEQ) === 0) {

return decodeURIComponent(cookie.substring(nameEQ.length))

}

}

return null

}

// 删除Cookie

function deleteCookie(name, path = '/') {

setCookie(name, '', -1, path)

}

// 使用示例

setCookie('token', 'jwt-token-here', 7)

const token = getCookie('token')

// 删除Cookie

// deleteCookie('token')

Cookie 的特性:

  1. 大小限制:通常为 4KB 左右
  2. 过期时间:可以设置过期时间,否则为会话 Cookie
  3. 域名限制:Cookie 仅发送到设置它的域名
  4. 路径限制:可以限制 Cookie 仅在特定路径下有效
  5. 随请求发送:每次请求都会自动携带 Cookie
  6. 安全性选项:Secure(仅 HTTPS 传输)、HttpOnly(禁止 JS 访问)、SameSite(防止 CSRF 攻击)

递归:解决复杂问题的利器

递归是指函数调用自身的编程技巧,常用于解决树形结构、排列组合等问题。

  1. 深度递归遍历树形结构:

    javascript 复制代码
    // 树形数据
    
    const tree = [
    
    {
    
    id: 1,
    
    name: '节点1',
    
    children: [
    
    {
    
    id: 11,
    
    name: '节点1-1',
    
    children: [
    
    { id: 111, name: '节点1-1-1' },
    
    { id: 112, name: '节点1-1-2' }
    
    ]
    
    },
    
    { id: 12, name: '节点1-2' }
    
    ]
    
    },
    
    { id: 2, name: '节点2' }
    
    ]
    
    // 深度递归遍历
    
    function deepTraverse(node, level = 0) {
    
    if (!node) return
    
    // 处理当前节点
    
    console.log(`${' '.repeat(level)}${node.name}`)
    
    // 递归处理子节点
    
    if (node.children && node.children.length) {
    
    node.children.forEach(child => {
    
    deepTraverse(child, level + 1)
    
    })
    
    }
    
    }
    
    // 遍历整个树
    
    tree.forEach(rootNode => {
    
    deepTraverse(rootNode)
    
    })
  2. 广度递归遍历树形结构:

    javascript 复制代码
    // 广度遍历
    
    function breadthTraverse(tree) {
    
    if (!tree || !tree.length) return
    
    // 使用队列存储节点
    
    const queue = [...tree]
    
    let level = 0
    
    while (queue.length > 0) {
    
    // 获取当前层级的节点数量
    
    const levelSize = queue.length
    
    console.log(`层级 ${level}:`)
    
    // 处理当前层级的所有节点
    
    for (let i = 0; i < levelSize; i++) {
    
    const node = queue.shift()
    
    console.log(` ${node.name}`)
    
    // 将子节点加入队列
    
    if (node.children && node.children.length) {
    
    queue.push(...node.children)
    
    }
    
    }
    
    level++
    
    }
    
    }
    
    // 使用示例
    
    breadthTraverse(tree)
  3. 多维数组遍历:

    javascript 复制代码
    // 多维数组
    
    const multiArray = [
    
    1,
    
    [2, 3],
    
    [4, [5, 6], 7],
    
    [8, [9, [10, 11], 12]]
    
    ]
    
    // 递归扁平化多维数组
    
    function flattenArray(arr) {
    
    let result = []
    
    arr.forEach(item => {
    
    if (Array.isArray(item)) {
    
    // 递归处理子数组
    
    result = result.concat(flattenArray(item))
    
    } else {
    
    result.push(item)
    
    }
    
    })
    
    return result
    
    }
    
    // 使用示例
    
    const flatArray = flattenArray(multiArray)
    
    console.log(flatArray) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

闭包:JavaScript 的高级特性

闭包是指函数能够访问其词法作用域之外的变量,即使函数在其词法作用域之外执行。

闭包的常见应用:

  1. 创建私有变量和方法:

    javascript 复制代码
    function createCounter() {
    
    // 私有变量
    
    let count = 0
    
    // 返回闭包函数
    
    return {
    
    increment: () => {
    
    count++
    
    return count
    
    },
    
    decrement: () => {
    
    count--
    
    return count
    
    },
    
    getCount: () => count,
    
    reset: () => {
    
    count = 0
    
    return count
    
    }
    
    }
    
    }
    
    // 使用示例
    
    const counter = createCounter()
    
    console.log(counter.increment()) // 1
    
    console.log(counter.increment()) // 2
    
    console.log(counter.decrement()) // 1
    
    console.log(counter.getCount()) // 1
    
    console.log(counter.reset()) // 0
  2. 函数工厂:

    javascript 复制代码
    // 创建打招呼函数的工厂
    
    function createGreeter(greeting) {
    
    // greeting 被闭包捕获
    
    return function(name) {
    
    return `${greeting}, ${name}!`
    
    }
    
    }
    
    // 创建不同的打招呼函数
    
    const sayHello = createGreeter('Hello')
    
    const sayHi = createGreeter('Hi')
    
    const sayBonjour = createGreeter('Bonjour')
    
    console.log(sayHello('Allen')) // Hello, Allen!
    
    console.log(sayHi('World')) // Hi, World!
    
    console.log(sayBonjour('Alice')) // Bonjour, Alice!
  3. 缓存计算结果:

    javascript 复制代码
    function createCacheFunction(calculator) {
    
    const cache = new Map()
    
    return function(arg) {
    
    // 检查缓存
    
    if (cache.has(arg)) {
    
    console.log('使用缓存结果')
    
    return cache.get(arg)
    
    }
    
    // 计算并缓存结果
    
    const result = calculator(arg)
    
    cache.set(arg, result)
    
    return result
    
    }
    
    }
    
    // 复杂计算函数
    
    function expensiveCalculation(n) {
    
    console.log('执行复杂计算')
    
    let result = 0
    
    for (let i = 0; i <= n; i++) {
    
    result += i
    
    }
    
    return result
    
    }
    
    // 创建带缓存的计算函数
    
    const cachedCalculation = createCacheFunction(expensiveCalculation)
    
    console.log(cachedCalculation(1000)) // 执行复杂计算,返回结果
    
    console.log(cachedCalculation(1000)) // 使用缓存结果,返回结果
    
    console.log(cachedCalculation(2000)) // 执行复杂计算,返回结果
    
    console.log(cachedCalculation(2000)) // 使用缓存结果,返回结果

前端工程化进阶:提升项目质量与效率

TypeScript:增强 JavaScript 的类型系统(具体可前往:TypeScript:融合 JS、ES6 与 Vue3 的前端开发新范式-CSDN博客)

TypeScript 是 JavaScript 的超集,添加了静态类型系统,提供更好的代码提示和类型检查。

在 Vue3 中使用 TypeScript:

TypeScript 复制代码
<!-- UserComponent.vue -->

<template>

<div>

<h2>{{ user.name }}</h2>

<p>年龄:{{ user.age }}</p>

<p>邮箱:{{ user.email }}</p>

</div>

</template>

<script setup lang="ts">

import { ref } from 'vue'

// 定义接口

interface User {

id: number

name: string

age: number

email?: string // 可选属性

}

// 定义变量并指定类型

const user: User = {

id: 1,

name: 'Allen',

age: 28,

email: 'allen@example.com'

}

// 定义函数类型

type GreetFunction = (name: string) => string

const greet: GreetFunction = (name) => {

return `Hello, ${name}!`

}

console.log(greet(user.name))

</script>

ESLint 与 Prettier:代码质量与格式化

ESLint 用于代码质量检查,Prettier 用于代码格式化,两者结合可以有效提升代码质量和一致性。

ESLint 配置(.eslintrc.js):

javascript 复制代码
module.exports = {

root: true,

env: {

browser: true,

es2021: true,

node: true

},

extends: [

'eslint:recommended',

'plugin:vue/vue3-recommended',

'plugin:@typescript-eslint/recommended',

'prettier'

],

parser: 'vue-eslint-parser',

parserOptions: {

ecmaVersion: 'latest',

parser: '@typescript-eslint/parser',

sourceType: 'module'

},

plugins: [

'vue',

'@typescript-eslint'

],

rules: {

'vue/multi-word-component-names': 'off',

'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',

'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',

'@typescript-eslint/explicit-module-boundary-types': 'off'

}

}

Prettier 配置(.prettierrc):

javascript 复制代码
{

"singleQuote": true,

"semi": true,

"tabWidth": 2,

"trailingComma": "es5",

"printWidth": 100,

"arrowParens": "always"

}

前端性能优化:提升用户体验

前端性能优化是提升用户体验的关键,主要包括以下几个方面:

1.加载优化:

    • 代码分割(Code Splitting)
    • 懒加载(路由懒加载、图片懒加载)
    • 资源压缩与混淆
    • 使用 CDN 加速

2.渲染优化:

    • 减少 DOM 操作
    • 使用虚拟列表处理大数据渲染
    • 避免重排重绘
    • 使用 CSS 硬件加速

3.缓存策略:

    • HTTP 缓存(强缓存、协商缓存)
    • Service Worker 缓存
    • 本地存储合理使用

4.Vue3 性能优化(善用v- ,具体可前往vue官网查看手册):

    • 使用v-memo缓存组件
    • 合理使用setup缓存计算结果
    • 避免不必要的响应式数据
    • 使用teleport优化模态框性能

结语

前端开发领域广阔且不断发展,从 Vue3 框架到工程化工具,从基础语法到高级概念,每一个知识点都值得深入学习和实践。本文涵盖了前端开发的核心知识,但学习之路永无止境。希望本文能成为你前端进阶之路上的良师益友,帮助你构建完整的知识体系,在前端开发的道路上不断进步,创造出更加优秀的 web 应用。记住,持续学习和实践是成为优秀前端工程师的关键,祝你在前端的世界里不断探索,收获成长!