javaweb-Day03-vue3&Element-plus

TJCcc 发布于 22 天前 18 次阅读


一、JavaScript、npm 与 Vue 框架的关系

  • JavaScript 是前端编程语言,浏览器原生支持。Vue 本身是用 JavaScript 编写的,它提供了一套声明式、组件化的开发模式。
  • npm(Node Package Manager)是 JavaScript 的包管理工具,相当于“应用商店”。通过 npm 可以安装、更新、管理项目依赖,比如 Vue、Element Plus、路由等。
  • 关系:JavaScript 是语言基础 → Vue 是基于 JavaScript 构建的框架 → npm 是安装和管理 Vue 及其生态的工具。
    实际开发中,我们通过 npm install vue 下载 Vue 框架,然后在项目中使用 JavaScript 语法编写 Vue 组件。

二、Vue 与 Vue 脚手架(CLI / create-vue)的区别和关系

  • Vue 核心库
  • 提供响应式数据绑定、组件系统、模板编译等核心功能。
  • 可以独立使用,比如通过 CDN 直接在 HTML 中引入 <script> 标签使用。
  • Vue 脚手架(如 Vue CLI 或官方推荐的 create-vue):
  • 是一个项目生成工具,用于快速搭建工程化的 Vue 项目。
  • 自动配置构建工具(Vite/Webpack)、开发服务器、热更新、路由、状态管理等最佳实践。
  • 关系
  • Vue 是“发动机”,脚手架是“整车生产线”。脚手架依赖 Vue,在生成的项目中会自动将 Vue 作为核心依赖。
  • 脚手架不是必须的,但实际企业级项目中几乎都会使用,以提升开发效率和代码可维护性。

三、Vue 2 与 Vue 3 的核心区别

特性Vue 2Vue 3
API 风格选项式 API(Options API)为主组合式 API(Composition API) + 选项式 API 并存
响应式原理Object.defineProperty 拦截Proxy 代理,性能更好,支持 Map/Set
TypeScript 支持有限,需额外装饰器原生支持,类型推导更完善
生命周期钩子beforeDestroy / destroyedbeforeUnmount / unmounted
模板根节点必须有单一根元素支持多个根节点(Fragment)
全局 APIVue.component / Vue.useapp.component / app.use(应用实例)
性能良好更快(更小体积、更优 diff 算法)

总结:Vue 3 带来了组合式 API 让逻辑复用更优雅,Proxy 重写响应式系统,性能更强。新项目强烈推荐 Vue 3。


四、Vue 3 核心基础(组合式 API 风格)

1. 创建项目(使用 create-vue 脚手架)

npm create vue@latest my-app
cd my-app
npm install
npm run dev

2. 组合式 API 核心:setup 与响应式

  • 推荐使用 <script setup> 语法糖。
  • 响应式数据:
  • ref:用于基本类型或对象,访问时需 .value,模板中自动解包。
  • reactive:用于对象或数组,直接属性访问,无需 .value
  • 计算属性:computed
  • 方法:普通函数
  • 生命周期:onMountedonUpdated

示例代码:

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'

const count = ref(0)
const user = reactive({ name: '张三', age: 25 })
const doubleCount = computed(() => count.value * 2)

function increment() {
  count.value++
}

onMounted(() => {
  console.log('组件已挂载')
})
</script>

<template>
  <div>
    <p>计数: {{ count }}</p>
    <p>两倍: {{ doubleCount }}</p>
    <p>用户: {{ user.name }},{{ user.age }} 岁</p>
    <button @click="increment">加一</button>
  </div>
</template>

3. 关键点

  • 组合式 API 按功能组织代码,而非按 data、methods 等选项拆分,更利于复用和维护。

五、Element Plus 基础使用

Element Plus 是基于 Vue 3 的桌面端 UI 组件库,提供按钮、表格、表单、弹窗等丰富组件。

1. 安装

npm install element-plus

2. 全局引入(或在 main.js 中按需引入)

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

3. 常用组件示例

按钮(Button)

<template>
  <el-button type="primary" @click="handleClick">主要按钮</el-button>
  <el-button type="success" plain>成功按钮</el-button>
</template>

<script setup>
import { ElMessage } from 'element-plus'
function handleClick() {
  ElMessage.success('点击成功')
}
</script>

表格(Table)+ 分页(Pagination)

<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column prop="date" label="日期" />
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="address" label="地址" />
  </el-table>
  <el-pagination v-model:page-size="pageSize" :total="50" layout="prev, pager, next" />
</template>

<script setup>
import { ref } from 'vue'
const tableData = ref([
  { date: '2026-08-01', name: '张三', address: '广州市天河区' },
  { date: '2026-08-02', name: '李四', address: '深圳市南山区' }
])
const pageSize = ref(10)
</script>

表单(Form)+ 校验

<template>
  <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
    <el-form-item label="用户名" prop="username">
      <el-input v-model="form.username" />
    </el-form-item>
    <el-form-item label="密码" prop="password">
      <el-input v-model="form.password" type="password" />
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm">提交</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'

const form = reactive({ username: '', password: '' })
const rules = {
  username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
const formRef = ref()

function submitForm() {
  formRef.value.validate((valid) => {
    if (valid) ElMessage.success('提交成功')
    else ElMessage.error('请完善表单信息')
  })
}
</script>

4. 使用技巧

  • 所有组件以 el- 开头,支持组合式 API,在 <script setup> 中直接使用。
  • 按需引入可减小打包体积(参考官方文档配置)。

六、三个核心问题 · 速查总结

  1. Vue 和 Vue 脚手架的区别和关系?
    Vue 是核心框架(响应式、组件),脚手架是项目生成工具(工程化配置)。脚手架依赖 Vue,但 Vue 可独立使用。
  2. Vue 2 和 Vue 3 的区别是什么?
    Vue 3 使用 Proxy 代替 defineProperty,支持组合式 API,原生 TypeScript,性能更优,生命周期命名改变,支持多根节点等。
  3. JavaScript、npm 和 Vue 框架的关系?
    JavaScript 是语言,Vue 是基于 JS 的框架,npm 是 JS 的包管理器,用于安装 Vue 及其生态依赖。

七、学习建议

  • 先掌握 Vue 3 组合式 API 核心:refreactivecomputedwatch、生命周期。
  • 熟悉 Element Plus 常用组件:布局、表单、表格、弹窗、消息提示。
  • 动手做一个小型后台管理页面(用户增删改查),巩固知识。
  • 官方文档是最权威的学习资源:Vue 3 官网、Element Plus 官网。

八、Vue 3 项目目录结构详解(以 create-vue 脚手架为例)

使用 npm create vue@latest 创建的项目通常采用 Vite 作为构建工具,目录结构清晰且规范。下面是核心文件夹和文件的解释:

  • node_modules/:项目所有的依赖包存放位置(通过 npm install 安装),一般不需要手动修改,也不建议上传到 Git。
  • public/:公共静态资源目录,存放 favicon.ico 等不会被构建工具处理的文件。此目录下的文件会直接复制到打包输出目录。
  • index.html:项目的入口 HTML 文件。Vue 应用会挂载到该文件中的 <div id="app"> 节点上。
  • package.json:项目的配置文件,记录了项目名称、版本、脚本命令(dev / build / preview)以及所有生产环境和开发环境的依赖列表。
  • vite.config.js:Vite 构建工具的配置文件,可以在这里配置代理、别名(@)、插件等。
  • src/核心源代码目录,我们绝大部分开发工作都在这里进行。
    • main.js:项目的 JavaScript 入口文件。负责创建 Vue 应用实例,并挂载全局插件(如 Element Plus、Vue Router、Pinia 等)。
    • App.vue:根组件,所有页面级组件都将通过 <router-view> 在此处渲染。
    • assets/:存放需要经过构建工具处理的静态资源,如图片、CSS 或 SCSS 全局样式文件。
    • components/:存放可复用的公共 UI 组件(如 Header.vue、Footer.vue、弹窗组件等)。
    • views/pages/:存放页面级组件(即路由对应的组件)。比如 HomeView.vue、UserListView.vue。
    • router/:存放 Vue Router 的路由配置文件(通常是 index.js),定义路径与组件的映射关系。
    • stores/(如果使用 Pinia):存放全局状态管理模块,按功能模块拆分(如 userStore.js)。

九、Vue 路由(Vue Router)如何实现

Vue Router 是 Vue 官方的路由管理器,用于构建单页面应用(SPA)。它通过监听 URL 的变化,动态渲染对应的组件,而无需刷新整个页面。

实现步骤与原理:

  1. 安装依赖
    在项目根目录执行 npm install vue-router
  2. 创建路由配置文件(通常在 src/router/index.js
  • 引入 createRoutercreateWebHistory(或 createWebHashHistory)。
  • 定义 routes 数组,每个路由对象包含 path(URL 路径)和 component(对应的组件)。
  • 创建 router 实例并导出。
  1. main.js 中挂载路由
    通过 app.use(router) 将路由实例注入到整个 Vue 应用中。
  2. 在模板中放置路由出口
    在根组件 App.vue 中使用 <router-view> 标签,该标签是路由组件的占位符,路由匹配到的组件将在此处渲染。
  3. 页面跳转的两种方式
  • 声明式导航:使用 <router-link to="/home"> 标签,类似于 HTML 中的 <a> 标签,但不会触发页面刷新。
  • 编程式导航:在 <script setup> 中引入 useRouter,调用 router.push('/home')router.replace('/home') 进行跳转。
  1. 获取路由参数
    使用 useRoute() 获取当前路由对象,通过 route.params.id 获取动态路径参数,或 route.query.page 获取 ?page=1 类型的查询参数。
  2. 路由模式
  • History 模式createWebHistory):URL 像正常的网页路径(如 /user/123),需要后端配合做重定向处理。
  • Hash 模式createWebHashHistory):URL 带 # 符号(如 /#/user/123),无需后端额外配置,兼容性更好。

十、Axios 异步请求与生命周期钩子的配合实现

Axios 是一个基于 Promise 的 HTTP 请求库,用于与后端接口进行数据交互。在 Vue 3 组合式 API 中,我们通常将 Axios 请求封装成函数,并在特定的生命周期钩子中触发调用。

安装与引入
npm install axios,然后在组件中 import axios from 'axios'

不同场景下触发的钩子函数实现:

  1. 页面初始化时请求数据(最常见)—— 在 onMounted 中触发
  • 当组件挂载到 DOM 后,立即发起异步请求获取初始数据(如列表、详情)。
  • 配合 refreactive 管理 loading 状态和数据状态。
  1. 路由参数变化时重新请求(如从 /user/1 切换到 /user/2)
  • 不能只依赖 onMounted,因为路由变化时组件可能被复用,不会重新挂载。
  • 解决办法:使用 watch 监听路由参数。引入 useRoute,监听 route.params.id 的变化,当变化时重新调用 Axios 请求函数。
  1. 在路由守卫中触发(进入页面前请求数据)
  • 使用 onBeforeRouteEnteronBeforeRouteUpdate(Vue Router 提供的组合式 API)。
  • 注意:onBeforeRouteEnter 中不能直接访问 this 或组件实例,但可以通过 next 回调获取。更常用的做法是在 onBeforeRouteUpdate 中处理参数变化刷新数据。

实战示例(组合式 API 标准写法)

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import axios from 'axios'

const route = useRoute()
const userInfo = ref(null)
const loading = ref(false)

// 封装请求函数
const fetchUserData = async (id) => {
  loading.value = true
  try {
    const response = await axios.get(`/api/user/${id}`)
    userInfo.value = response.data
  } catch (error) {
    console.error('请求失败', error)
  } finally {
    loading.value = false
  }
}

// 场景1:组件挂载时触发(首次进入页面)
onMounted(() => {
  fetchUserData(route.params.id)
})

// 场景2:路由参数变化时触发(同组件复用,如从详情1跳转到详情2)
watch(() => route.params.id, (newId) => {
  if (newId) {
    fetchUserData(newId)
  }
})
</script>

补充说明

  • 如果需要在组件销毁前取消未完成的请求,可以在 onBeforeUnmount 中使用 AbortController 取消 Axios 请求,避免内存泄漏。
  • 对于非路由相关的响应式数据变化(如搜索关键词),同样可以使用 watch 监听该响应式变量,并在回调中触发 Axios 请求,实现自动刷新数据的效果。

唯有极致沉淀,才能造就辉煌。
最后更新于 2026-08-01