从0到1,搭建vue3项目

一 Vite创建Vue3项目

1.1.创建Vue3项目

1.1.1.运行创建项目命令

# 使用 npm

npm create vite@latest

1.1.2、填写项目名称

1.1.3、选择前端框架

1.1.4、选择语法类型

1.1.5、按提示运行代码

1.1.6浏览器问 localhost:5173 预览

1.2项目结构

1.2.1vite.config.ts

1.2.2 package.json

二 src 路径别名配置

相对路径别名配置,使用 @ 代替 src

Vite 配置

javascript 复制代码
import { defineConfig } from "vite"; // Vite 配置方法
import vue from "@vitejs/plugin-vue"; // Vite 官方的 Vue 插件

import { fileURLToPath, URL } from "node:url";

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    // Vue.js 插件
    vue(),
  ],
  // 模块解析配置
  resolve: {
    alias: {
      // 将 '@' 别名映射到 'src' 目录,简化导入路径
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
});
javascript 复制代码
npm install -D @types/node

三unplugin 自动导入

Element Plus 官方文档中推荐 按需自动导入 的方式,而此需要使用额外的插件 **unplugin-auto-importunplugin-vue-components**来导入要使用的组件。所以在整合 Element Plus 之前先了解下自动导入的概念和作用

概念

为了避免在多个页面重复引入 API组件,由此而产生的自动导入插件来节省重复代码和提高开发效率。

3.1安装插件依赖

javascript 复制代码
npm install -D unplugin-auto-import unplugin-vue-components 

3.2vite.config.ts - 自动导入配置

先创建好 /src/types 目录用于存放自动导入函数和组件的TS类型声明文件,再进行自动导入配置

javascript 复制代码
// vite.config.ts
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";

import path from "path";

const pathSrc = path.resolve(__dirname, "src");

plugins: [
  AutoImport({
    // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
    imports: ["vue"],
    eslintrc: {
      enabled: true, // 是否自动生成 eslint 规则,建议生成之后设置 false 
      filepath: "./.eslintrc-auto-import.json", // 指定自动导入函数 eslint 规则的文件
    },
    dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // 指定自动导入函数TS类型声明文件路径
  }),
  Components({
    dts: path.resolve(pathSrc, "types", "components.d.ts"), // 指定自动导入组件TS类型声明文件路径
  }),
]

项目中:

四整合 Element Plus

参考: element plus 按需自动导入

需要完成上面一节的 自动导入 的安装和配置

4.1安装 Element Plus

javascript 复制代码
npm install element-plus

4.2配置:

javascript 复制代码
import { defineConfig } from "vite"; // Vite 配置方法
import vue from "@vitejs/plugin-vue"; // Vite 官方的 Vue 插件

import { fileURLToPath, URL } from "node:url";

import Components from "unplugin-vue-components/vite"; // 自动导入 Vue 组件
import AutoImport from "unplugin-auto-import/vite"; // 自动导入 Vue 相关 API
import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; // Element Plus 组件解析器

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    // Vue.js 插件
    vue(),
    // 自动导入常用的 Vue API,比如 'ref' 和 'vue-router'
    AutoImport({
      imports: ["vue", "vue-router"], // 自动导入 Vue 和 Vue Router 的 API
      resolvers: [ElementPlusResolver()], // 自动导入 Element Plus 的 API
      eslintrc: {
        enabled: true, // 启用 ESLint 配置生成
        filepath: "./.eslintrc-auto-import.json", // 指定一个生成的 ESLint 配置文件路径
      },
    }),
    // 自动导入组件(如 Element Plus 组件)
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
  // 模块解析配置
  resolve: {
    alias: {
      // 将 '@' 别名映射到 'src' 目录,简化导入路径
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
});

4.3测试:

javascript 复制代码
<div>
    <el-button type="success">Success</el-button>
    <el-button type="info">nfo</el-button>
    <el-button type="warning">Warning</el-button>
    <el-button type="danger">Danger</el-button>
  </div>

五Element Plus主题色定制(通过scss变量替换方案)

一款CSS预处理语言,SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。

如果通过scss变量替换方案来定制Element Plus主题色,按照如下步骤:

  • 安装sass:使用命令npm install sass -D
  • 准备定制样式文件:在项目下面新增文件styles/themeVar.scss
  • 对Element Plus样式进行覆盖:通知Element Plus采用scss语言,再导入定制的scss文件覆盖

5.1安装依赖

javascript 复制代码
npm i -D sass 

5.2新建文件/src/styles/themeVar.scss,并定义scss变量

javascript 复制代码
/* 自定义 element-plus 主题 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  $colors: (
    'white': #ffffff,
    'black': #000000,
    'primary': (
      'base': #69642c,
    ),
    'success': (
      'base': #0e4600,
    ),
    'warning': (
      'base': #e7c79f,
    ),
    'danger': (
      'base': #fd0000,
    ),
    'error': (
      'base': #440303,
    ),
    'info': (
      'base': #3aa176,
    )
  ),
);

5.3vite.config.js

1自动导入配置

配置Element Plus采用saas配色系统

将vite.config.js文件中的Components修改为如下形式:

javascript 复制代码
 Components({
      resolvers: [
        // 配置Element Plus采用saas样式配色系统
        ElementPlusResolver({ importStyle: 'sass' }),
      ],
    })

2自动导入定制化样式文件进行样式覆盖

javascript 复制代码
export default defineConfig(({ command, mode }) => {
  // ...
  return {
    //...
   css: {
    preprocessorOptions: {
      scss: {
        // 按需导入自定义主题
        additionalData: `@use "@/styles/themeVar.scss" as *;`
      }
    }
  },
  }
})

5.4 测试

修改配置后,执行npm run dev重启,info按钮的主题色修改为绿色了:

六reset.scss 整合到vue3中

测试:

reset.scss

javascript 复制代码
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  font-weight: normal;
}

html {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  line-height: 1.5;
  tab-size: 4;
  text-size-adjust: 100%;
}

body {
  width: 100%;
  height: 100%;
  margin: 0;
  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
  "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
  line-height: inherit;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizelegibility;
}

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font: inherit;
  vertical-align: baseline;
  box-sizing: border-box; /* Ensure padding and borders are included in element sizes */
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
/* 使表格兼容safari,不错位 */
.el-table__body {
  width: 100%;
  table-layout: fixed;
}

七 整合svg

通过 vite-plugin-svg-icons 插件整合 Iconfont 第三方图标库实现本地图标

八整合 Pinia

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

参考:Pinia 官方文档

8.1安装依赖

javascript 复制代码
npm install pinia
npm install pinia-plugin-persistedstate // 持久化插件

8.2 数据持久化

javascript 复制代码
import { createPinia } from "pinia"
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) // 数据持久化

export default pinia

8.3main.ts 引入 pinia

javascript 复制代码
// src/main.ts
import { createPinia } from "pinia";
import App from "./App.vue";

createApp(App).use(createPinia()).mount("#app");

8.3定义 Store

根据 Pinia 官方文档-核心概念 描述 ,Store 定义分为选项式组合式 , 先比较下两种写法的区别:

选项式 Option Store 组合式 Setup Store

至于如何选择,官方给出的建议 :选择你觉得最舒服的那一个就好

这里选择组合式,新建文件 src/store/counter.ts

javascript 复制代码
// src/store/counter.ts
import { defineStore } from "pinia"

export const useCounterStore = defineStore(
  "counter",
  () => {
    const count = ref(0)
    const doubleCount = computed(() => count.value * 2)
    function increment() {
      count.value++
    }

    function decrement() {
      count.value--
    }

    return {
      count,
      doubleCount,
      increment,
      decrement
    }
  },
  {
    persist: {
      // 不需要持久化,配置项 persist: false
      enabled: false,
      storage: sessionStorage, // 可以是 localStorage, sessionStorage 或 window.localStorage
      key: "counter_key" // 状态的键名
    }
  }
)

父组件

javascript 复制代码
<!-- src/App.vue -->
<script setup lang="ts">
import HelloWorld from "@/components/HelloWorld.vue";

import { useCounterStore } from "@/stores/counter.ts";
const counterStore = useCounterStore();
</script>

<template>
  <h1 class="text-3xl">vue3-element-admin-父组件</h1>
  <el-button type="primary" @click="counterStore.increment">count++</el-button>
  <HelloWorld />
</template>

子组件

javascript 复制代码
<!-- src/components/HelloWorld.vue -->
<script setup lang="ts">
import { useCounterStore } from "@/stores/counter.ts";
const counterStore = useCounterStore();
</script>

<template>
  <el-card  class="text-left text-white border-white border-1 border-solid mt-10 bg-[#242424]" >
    <template #header> 子组件 HelloWorld.vue</template>
    <el-form>
      <el-form-item label="数字:"> {{ counterStore.count }}</el-form-item>
      <el-form-item label="加倍:"> {{ counterStore.double }}</el-form-item>
    </el-form>
  </el-card>
</template>

效果预览

九环境变量

Vite 环境变量主要是为了区分开发、测试、生产等环境的变量

参考: Vite 环境变量配置官方文档

env配置文件

项目根目录新建 .env.development.env.production

  • 开发环境变量配置:.env.development
javascript 复制代码
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
VITE_APP_TITLE = 'vue3-element-admin'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/dev-api'
  • 生产环境变量配置:.env.production
javascript 复制代码
VITE_APP_TITLE = 'vue3-element-admin'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/prod-api'

十反向代理解决跨域

跨域原理

浏览器同源策略: 协议、域名和端口都相同是同源,浏览器会限制非同源请求读取响应结果。

本地开发环境通过 Vite 配置反向代理解决浏览器跨域问题,生产环境则是通过 nginx 配置反向代理 。

vite.config.ts 配置代理

表面肉眼看到的请求地址: http://localhost:3000/dev-api/api/v1/users/me

真实访问的代理目标地址: http://vapi.youlai.tech/api/v1/users/me

十一 vue-router 静态路由

11.1安装 vue-router

javascript 复制代码
npm install vue-router@next

11.2全局注册路由实例

javascript 复制代码
// main.ts
import router from "@/router";

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

11.3路由实例

  • views中创建 DemoView.vue。Home

  • 创建路由实例

javascript 复制代码
import { createRouter, createWebHistory } from "vue-router"
import HomeView from "@/views/HomeView.vue"

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/",
      name: "home",
      component: HomeView
    },
    {
      path: "/demo",
      name: "demo",
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import("../views/DemoView.vue")
    }
  ]
})

export default router

11.4测试

src/App.vue

javascript 复制代码
<script setup lang="ts">
onMounted(() => {
  console.log("hello world1");
});
</script>

<template>
  <el-config-provider :locale="zhCn">
    <header>
      <div class="wrapper">
        <nav>
          <RouterLink to="/">Home</RouterLink> <span>|</span>
          <RouterLink to="/demo">demo</RouterLink>
        </nav>
      </div>
    </header>

    <RouterView />
  </el-config-provider>
</template>

<style scoped></style>
相关推荐
学传打活2 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
fangzhanpeng1689 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心12 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u01030552718 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u01030552718 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝19 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552720 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552720 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552722 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552723 天前
Java I/O核心操作实战
人工智能·1024程序员节