学习:Vue (1)

Vue3 创建项目

复制代码
npm create vite@latest

安装依赖,并启动应用:

复制代码
npm install
npm run dev

项目结构

一个 Vue 3 项目通常包含以下文件和文件夹:

javascript 复制代码
my-vue-app/
├── node_modules/       # 项目依赖的第三方库
├── public/             # 静态资源文件夹
│     └── ...             # 其他静态资源(如图片、字体等)
├── src/                # 项目源代码
│   ├── assets/         # 静态资源(如图片、字体等)
│   ├── components/     # 可复用的 Vue 组件
│   ├── views/          # 页面级组件
│   ├── App.vue         # 根组件
│   ├── main.js         # 项目入口文件
│   ├── router/index.js     # 路由配置 
│   ├── store/index.js     # Vuex 状态管理配置
│   └── ...             # 其他配置和资源
├── index.html          # 应用的 HTML 模板
├── package.json        # 项目配置和依赖管理
├── package-lock.json   # 依赖的精确版本锁定文件
└── README.md           # 项目说明文档

index.html

Vue 应用的 HTML 模板文件。

Vue 会将应用挂载到 <div id="app"></div> 中。

html 复制代码
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Vue</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

src\main.js

Vue 应用的入口文件。

src/main.js 负责创建 Vue 应用实例,并将根组件(通常是 App.vue)挂载到 index.html 中的 div#app 中。

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)//定义一个常量app
app.mount('#app')

src\components

包含可复用的 Vue 组件

src\views

包含页面级组件,通常与路由配置一起使用

src\router\index.js

Vue Router 的配置文件,用于定义路由。

javascript 复制代码
import { createRouter,createWebHistory } from "vue-router"

	const routes = [
	    {
	        path: "/", // http://localhost:5174
            // alias:"/home", //定义别名 http://localhost:5174/home
            alias:["/home","/index"],
             // component: () => import("../views/index.vue")
	        component: () => import("@/views/index.vue")
	    },
     ]

	const router = createRouter({
	    //使用url的#符号之后的部分模拟url路径的变化,因为不会触发页面刷新,所以不需要服务端支持
	    //history: createWebHashHistory(), 
	    history: createWebHistory(),
	    routes
	})

	export default router

src\store\index.js

Vuex 状态管理的配置文件(如果使用 Vuex)

javascript 复制代码
import { createStore } from 'vuex';

export default createStore({
  state: {
    message: 'Hello, Vuex!',
  },
  mutations: {
    setMessage(state, newMessage) {
      state.message = newMessage;
    },
  },
  actions: {
    updateMessage({ commit }, newMessage) {
      commit('setMessage', newMessage);
    },
  },
});

(如果使用 pinia)

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

/*
  定义一个基于 Pinia 的 Store
  第1个参数 web 是 useWebStore 在应用中的唯一标识符(ID)
  第2个参数是 Setup函数 或 Option对象
*/
export const useWebStore = defineStore('web', () => {
  //定义一个响应式对象,存储网站信息
  const web = reactive({
    title: "bilibili",
    url: "bilibili.com"
  })

  //定义一个响应式引用,存储用户数
  const users = ref(1000)
  
  //定义方法
  const userAdd = () => {
    users.value++
  }

  return {
    web,
    users,
    userAdd
  }
},
  {
    //持久化存储到 lonpmcalStorage 中
  persist: true
  }
)

package.json

项目的配置文件,包含项目的元数据、依赖和脚本。

javascript 复制代码
{
  "name": "demo1",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "element-plus": "^2.9.11",
    "pinia": "^3.0.2",
    "pinia-plugin-persistedstate": "^4.3.0",
    "vue": "^3.5.13",
    "vue-router": "^4.5.1"
  },
  "devDependencies": {
    "@iconify-json/ep": "^1.2.2",
    "@vitejs/plugin-vue": "^5.2.3",
    "unplugin-auto-import": "^19.3.0",
    "unplugin-icons": "^22.1.0",
    "unplugin-vue-components": "^28.7.0",
    "vite": "^6.3.5"
  }
}

Vue 组件的基本结构

Vue 3 Snippets

这个插件包含了所有的 Vue.js 2 和 Vue.js 3 的 api 对应的代码片段。

生成vue基本模板代码

快速生成Vue.js相关代码

Vue VSCode Snippets(常用

自定义模板:

C:\Users\用户名\.vscode\extensions\sdras.vue-vscode-snippets-3.2.0\snippets\vue.json

Vite 教程

创建 Vite 项目

Vite 提供了多种方式来创建新项目,最简单的方式是使用命令行工具。

打开终端或命令行工具,运行以下命令来创建一个新的 Vite 项目:

javascript 复制代码
npm create vite@latest

按照提示输入项目名称并选择模板。

Vite 提供了多种模板,包括:

  • vanilla: 纯 JavaScript 项目

  • vue: Vue.js 项目

  • react: React 项目

  • preact: Preact 项目

  • lit: Lit 项目

  • svelte: Svelte 项目

  • **solid:**Solid 项目

  • **qwik :**Qwik 组件与 React 组件非常相似

  • **angular:**angular项目

  • **marko:**Marko项目

选择一个变体:

启用 rolldown-vite(实验性):No

Install with npm and start now? Yes

Vite 常用功能

Vite 提供了丰富的功能,可以帮助你更高效地开发前端应用。

1. 使用 CSS 预处理器

Vite 支持使用 Sass、Less、Stylus 等 CSS 预处理器。

要使用这些预处理器,你需要先安装相应的依赖:

Sass:

javascript 复制代码
npm install -D sass

Less:

javascript 复制代码
npm install -D less

Stylus:

javascript 复制代码
npm install -D stylus

2.使用静态资源

Vite 支持使用图片、字体等静态资源。

可以将这些资源放在public目录下,或者使用 import 语句导入资源。

1.引入 public 中的资源永远应该使用根绝对路径,例如:public/icon.png 应该在源码中被引用为 /icon.png。

2.public 中的资源不应该被 JavaScript 文件引用。

3.使用 import 语句

javascript 复制代码
<script setup>
	  //导入子组件
	  import Header from "@/components/header.vue"
	  import Footer from "@/components/footer.vue"
	</script>

	<template>
	    <!-- 共享的Header组件 -->
	    <Header/>

	    <!-- 根据不同的子路由加载不同子页面 -->
	    <router-view />

	    <!-- 共享的Footer组件 -->
	    <Footer/>
	</template>

	<style scoped>

	</style>

4.使用环境变量

Vite 支持使用环境变量来配置不同的环境。

javascript 复制代码
# 页面标题
VITE_APP_TITLE =

# 开发环境配置
VITE_APP_ENV = 

# 开发环境
VITE_APP_BASE_API = 

# 应用访问路径 例如使用前缀 /admin/
VITE_APP_CONTEXT_PATH = '/'

5.使用插件

安装插件:

在 vite.config.js 文件中配置插件:

配置说明:

javascript 复制代码
// 导入 defineConfig 函数,用于定义 Vite 配置
import { defineConfig } from 'vite';
// 导入 Vue 插件,用于支持 Vue 项目
import vue from '@vitejs/plugin-vue';
// 导入 path 模块,用于处理路径
import path from 'path';

// 使用 defineConfig 定义 Vite 配置
export default defineConfig({
  // 项目根目录,默认为当前工作目录
  root: path.resolve(__dirname, './src'),

  // 基础路径,用于部署在子路径时使用
  base: '/my-app/',

  // 开发服务器配置
  server: {
    // 指定开发服务器端口
    port: 3000,
    // 是否自动打开浏览器
    open: true,
    // 配置代理服务器,用于解决跨域问题
    proxy: {
      '/api': {
        target: 'http://localhost:8080', // 目标服务器地址
        changeOrigin: true, // 是否改变请求源
        rewrite: (path) => path.replace(/^\/api/, ''), // 重写请求路径
      },
    },
  },

  // 构建配置
  build: {
    // 指定输出目录
    outDir: path.resolve(__dirname, '../dist'),
    // 指定静态资源目录
    assetsDir: 'static',
    // 是否生成 sourcemap 文件
    sourcemap: true,
    // 是否压缩代码
    minify: 'terser', // 使用 terser 进行代码压缩
    // 配置 Rollup 选项
    rollupOptions: {
      // 配置外部依赖
      external: ['lodash'],
      // 配置输出格式
      output: {
        manualChunks: {
          // 将 lodash 单独打包
          lodash: ['lodash'],
        },
      },
    },
  },

  // 插件配置
  plugins: [
    // 使用 Vue 插件
    vue(),
  ],

  // 模块解析配置
  resolve: {
    // 配置路径别名
    alias: {
      '@': path.resolve(__dirname, './src'), // 将 @ 映射到 src 目录
    },
  },

  // CSS 配置
  css: {
    // 配置 CSS 预处理器选项
    preprocessorOptions: {
      scss: {
        // 全局注入 SCSS 变量
        additionalData: `@import "@/styles/variables.scss";`,
      },
    },
  },

  // 环境变量配置
  envPrefix: 'VITE_', // 环境变量前缀,默认为 VITE_
});

例子:

javascript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path' //导入 node.js path

//unplugin
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Icons from 'unplugin-icons/vite' //图标
import IconsResolver from 'unplugin-icons/resolver'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue(),
  AutoImport({
    // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
    imports: ['vue'],

    resolvers: [
      ElementPlusResolver(),
      // 自动导入图标组件
      IconsResolver(),
    ],
  }),
  Components({
    resolvers: [
      ElementPlusResolver(),
      // 自动注册图标组件
      IconsResolver({
        enabledCollections: ['ep'],
      }),
    ],
  }),
  Icons({
    autoInstall: true,
  }),
],
  resolve: {
    alias: { //配置路径别名
      '@': path.resolve(__dirname, 'src')
    }
  }
})

Vue3 目录结构

Vue3 目录结构 | 菜鸟教程

Vue3 起步

Vue3 起步 | 菜鸟教程

Vue3 基础语法

Vue3 基础语法 | 菜鸟教程

Vue3 声明式渲染

Vue3 声明式渲染 | 菜鸟教程

Vue3 指令

Vue3 指令 | 菜鸟教程

Vue3 模板语法

Vue3 模板语法 | 菜鸟教程

Vue3 条件语句

Vue3 条件语句 | 菜鸟教程

特性 v-if v-show
实现方式 条件性地渲染元素 通过 CSS display 属性控制显示/隐藏
DOM 存在 不满足条件时不存在于 DOM 中 始终存在于 DOM 中
初始渲染开销 较小(条件为假时不渲染) 较大(总是渲染)
切换开销 较大(涉及添加/删除 DOM) 较小(仅改变 CSS 属性)
生命周期 完整的生命周期钩子 不会触发生命周期钩子
编译时 编译为条件分支 编译为指令

Vue.js 循环语句

Vue3 循环语句 | 菜鸟教程

Vue3 组件

Vue3 组件 | 菜鸟教程

Vue3 计算属性

Vue3 计算属性 | 菜鸟教程

Vue3 监听属性

Vue3 监听属性 | 菜鸟教程

Vue 3 还提供了 watchEffect API,它比 watch 更加简洁,可以自动地跟踪响应式数据的变化,而不需要指定具体的数据源。

特性 watch watchEffect
依赖追踪 显式指定监听源 自动收集依赖
执行时机 默认惰性,依赖变化后执行 立即执行,依赖变化后重新执行
旧值访问 提供新旧值 不提供新旧值
使用方式 需要明确指定监听的数据 直接在回调中使用响应式数据
适用场景 需要获取旧值或特定数据变化 副作用函数,自动依赖收集

Vue3 样式绑定

Vue3 样式绑定 | 菜鸟教程

Class 绑定要点

  1. 对象语法{ class: condition } - 适用于条件类名
  2. 数组语法[class1, class2] - 适用于多个类名组合
  3. 计算属性:适用于复杂类名逻辑
  4. 组件绑定:类名会自动应用到组件根元素

Style 绑定要点

  1. 对象语法{ property: value } - 适用于动态样式
  2. 数组语法[styleObject1, styleObject2] - 适用于多个样式对象
  3. 自动前缀:Vue 自动处理浏览器前缀
  4. 多值处理 :提供兼容性数组 [value1, value2]

Vue3 事件处理

Vue3 事件处理 | 菜鸟教程

Vue.js 通过由点 . 表示的指令后缀来调用修饰符。

  • .stop - 阻止冒泡
  • .prevent - 阻止默认事件
  • .capture - 阻止捕获
  • .self - 只监听触发该元素的事件
  • .once - 只触发一次
  • .left - 左键事件
  • .right - 右键事件
  • .middle - 中间滚轮事件

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获 "删除" 和 "退格" 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统修饰键:

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠标按钮修饰符:

  • .left
  • .right
  • .middle

Vue3 表单

Vue3 表单 | 菜鸟教程

Vue3 自定义指令

Vue3 自定义指令 | 菜鸟教程

Vue3 路由(Vue Router)

Vue3 路由(Vue Router) | 菜鸟教程

Vue 路由允许我们通过不同的 URL 访问不同的内容。

npm 安装

复制代码
npm install vue-router@4

基本应用

1、创建路由表

javascript 复制代码
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'

const routes = [
  { path: '/', component: Home },
]

export default createRouter({
  history: createWebHistory(),
  routes
})

2、在应用中挂载

javascript 复制代码
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

3、页面出口

src\App.vue

html 复制代码
<router-view/>

4、跳转

html 复制代码
    <router-link to="/user/profile">
             个人中心
    </router-link>

使用一个自定义组件 router-link 来创建链接

属性详解

属性名 类型 默认值 说明
to string | Location - 目标路由的路径或路由对象
replace boolean false 设置后,导航时不会向history添加新记录
append boolean false 设置后,当前路径被附加到目标路径
tag string a 指定渲染的HTML标签
active-class string router-link-active 指定链接激活时的CSS类名
exact-active-class string router-link-exact-active 指定链接精确匹配时的CSS类名
exact boolean false 设置后,只有在完全匹配时才激活
event string | Array click 指定触发导航的事件
aria-current-value string page 指定aria-current属性的值

Vue3 混入

Vue3 混入 | 菜鸟教程

注意事项

在Vue3中,混入仍然支持,但官方推荐使用组合式API(Composition API)来实现代码复用,因为组合式API提供了更清晰、更灵活的代码组织方式。

混入与组合式API的比较

特性 混入 (Mixins) 组合式API
代码组织 按选项类型组织 按逻辑功能组织
命名冲突 可能发生,组件优先 避免了命名冲突
类型推导 较差 更好的TypeScript支持
数据来源 难以追踪 清晰的来源追踪
依赖关系 隐式依赖 显式依赖
复用方式 选项合并 函数调用
性能 全部混入,即使部分不用 按需使用

Vue3 Ajax(axios)

安装Axios

使用npm安装

复制代码
npm install axios

src\utils\request.js or src\utils\axios.js

文件整体结构

javascript 复制代码
// 1. 导入依赖
import axios from "axios";
import { getToken } from '@/composables/auth';  // 获取 token
import { toast } from '@/composables/util';     // 提示工具
import store from './store';                    // Vuex 状态管理

// 2. 创建 Axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,  // 基础路径(从环境变量读取)
});

// 3. 请求拦截器
service.interceptors.request.use(...);

// 4. 响应拦截器
service.interceptors.response.use(...);

// 5. 导出实例
export default service;

使用

注册为全局属性

main.js

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import axiosInstance from './utils/axios'

const app = createApp(App)

// 将axios实例添加为全局属性
app.config.globalProperties.$axios = axiosInstance

app.use(router)
app.mount('#app')

提供API服务

Vue3 组合式 API

Vue3引入的组合式API(Composition API)是一套低侵入性的、函数式的API,使得我们能够更灵活地组织组件逻辑。

setup函数

setup函数是组合式API的入口点。它在组件创建之前执行,是所有组合式API函数的调用场所。

响应式基础

组合式API提供了两个主要的API来创建响应式状态:ref和reactive。

ref

ref接受一个内部值并返回一个响应式且可变的ref对象。ref对象只有一个指向内部值的属性.value。

reactive

reactive返回一个对象的响应式代理。它将对象的所有嵌套属性都转换为响应式。

ref与reactive的区别

特性 ref reactive
适用类型 基本类型(字符串、数字等)和对象 对象和数组
访问方式 通过.value属性访问 直接访问属性
模板中访问 自动解包,不需要.value 直接访问属性
替换整个值 可以直接替换整个值 不能直接替换整个值
解构 解构会失去响应性,需要使用toRefs 解构会失去响应性,需要使用toRefs

toRefs与toRef

toRefs可以将reactive对象转换为普通对象,其中结果对象的每个属性都是指向原始对象相应属性的ref。

计算属性

计算属性是基于响应式依赖进行缓存的值,只有当相关依赖发生改变时才会重新计算。在组合式API中,使用computed函数创建计算属性。

计算属性的缓存

计算属性基于它们的响应式依赖进行缓存。只有在相关响应式依赖改变时它们才会重新计算。

侦听器

侦听器用于观察和响应Vue实例上的数据变动。在组合式API中,使用watch和watchEffect函数创建侦听器。

watch

watch用于侦听特定的数据源,并在数据源变化时执行回调。

watchEffect

watchEffect会立即执行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新运行该函数。

watch vs watchEffect

特性 watch watchEffect
执行时机 默认不立即执行,需要配置 立即执行一次
依赖追踪 显式指定要侦听的数据源 自动追踪回调函数内的响应式依赖
获取旧值 可以获取变化前后的值 无法获取旧值
使用场景 需要在数据变化时执行特定逻辑 需要根据响应式状态自动更新某些值

watch的配置选项

javascript 复制代码
// 立即执行一次
watch(count, (newValue, oldValue) => {
  console.log(`计数从 ${oldValue} 变为 ${newValue}`)
}, { immediate: true })

// 深度侦听
watch(
  () => deepObject.nested.value,
  (newValue, oldValue) => {
    console.log(`嵌套值从 ${oldValue} 变为 ${newValue}`)
  },
  { deep: true }
)

停止侦听器

watch和watchEffect都返回一个停止函数,调用它可以停止侦听器。

javascript 复制代码
const stopWatch = watch(ref(0), () => {
  console.log('侦听器被调用')
})

// 在某些条件下停止侦听
stopWatch()

生命周期钩子

在组合式API中,可以使用onX系列函数来注册生命周期钩子。这些函数在setup()中调用。

生命周期钩子列表

选项式API 组合式API 说明
beforeCreate setup() 实例初始化后,数据观测和事件配置前
created setup() 实例创建完成
beforeMount onBeforeMount 挂载开始前
mounted onMounted 挂载完成后
beforeUpdate onBeforeUpdate 数据更新前
updated onUpdated 数据更新后
beforeUnmount onBeforeUnmount 卸载前
unmounted onUnmounted 卸载后
errorCaptured onErrorCaptured 捕获后代组件错误

API 手册

API对应关系

选项式API 组合式API
data ref() / reactive()
computed computed()
methods 函数声明
watch watch() / watchEffect()
beforeCreate / created setup()
beforeMount / mounted onBeforeMount() / onMounted()
beforeUpdate / updated onBeforeUpdate() / onUpdated()
beforeUnmount / unmounted onBeforeUnmount() / onUnmounted()
emits context.emit
props setup第一个参数
attrs / slots context.attrs / context.slots
相关推荐
一只小风华~5 小时前
Vue.js 核心知识点全面解析
前端·javascript·vue.js
2022.11.7始学前端5 小时前
n8n第七节 只提醒重要的待办
前端·javascript·ui·n8n
徐小夕5 小时前
知识库创业复盘:从闭源到开源,这3个教训价值百万
前端·javascript·github
xhxxx6 小时前
函数执行完就销毁?那闭包里的变量凭什么活下来!—— 深入 JS 内存模型
前端·javascript·ecmascript 6
瑶光守护者6 小时前
【学习笔记】5G RedCap:智能回落5G NR驻留的接入策略
笔记·学习·5g
你想知道什么?6 小时前
Python基础篇(上) 学习笔记
笔记·python·学习
L、2186 小时前
统一日志与埋点系统:在 Flutter + OpenHarmony 混合架构中实现全链路可观测性
javascript·华为·智能手机·electron·harmonyos
SHOJYS6 小时前
学习离线处理 [CSP-J 2022 山东] 部署
数据结构·c++·学习·算法
VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue音乐管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
十一.3666 小时前
103-105 添加删除记录
前端·javascript·html