从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>
相关推荐
就爱敲代码13 分钟前
怎么理解ES6 Proxy
1024程序员节
憧憬一下14 分钟前
input子系统的框架和重要数据结构详解
arm开发·嵌入式·c/c++·1024程序员节·linux驱动开发
三日看尽长安花23 分钟前
【Tableau】
1024程序员节
sswithyou43 分钟前
Linux的调度算法
1024程序员节
武子康1 小时前
大数据-187 Elasticsearch - ELK 家族 Logstash Filter 插件 使用详解
大数据·数据结构·elk·elasticsearch·搜索引擎·全文检索·1024程序员节
互联网杂货铺1 小时前
Python测试框架—pytest详解
自动化测试·软件测试·python·测试工具·测试用例·pytest·1024程序员节
GDAL2 小时前
JavaScript正则表达式利器:exec()方法深度解析与应用实例
正则表达式·1024程序员节
2401_857610032 小时前
植物健康,Spring Boot来助力
1024程序员节
阿乾之铭2 小时前
Spring Boot框架中的IO
java·spring boot·log4j·1024程序员节
百流2 小时前
Pyspark中pyspark.sql.functions常用方法(4)
1024程序员节