首先需要明确,要搭建一个Vite+Vue3+TS+Vue-router+axios+pinia+scss的项目,需要考虑以下步骤:
一、安装Node.js和npm
如果你的电脑上没有安装NodeJS和npm,请先到Node.js官网(nodejs.org/en/)下载安装后,打开cmd或者终端,输入node -v和npm -v,查看是否安装成功。
二、初始化项目
创建一个新的项目文件夹,打开命令行,使用以下命令初始化一个新的npm项目。这里,我们以myproject
为例。
npm init
在npm init命令执行后,根据提示填写各项基本信息,然后按Enter键即可。
初始化完成后会自动在项目根目录下生成一个package.json文件。
三、安装vite
进入项目根目录,运行以下命令来安装vite。
npm install vite --save-dev
安装完成后,项目根目录下会有 'node_moduces'目录'package.json','package-lock.json'两个依赖包记录文件
注意: 我们都知道package.json除了配置快捷的node script脚本
, 最主要的作用还是: 用于记录下当前项目所应用到的依赖包, 但是既然都已经有了package.json文件了, 那么为什么项目中还需要一个package-lock.json呢?
package-lock.json的作用
作用: 锁定安装时的包的版本号及包的依赖的版本号, 以保证其他所有人人在使用 npm install
时下载的依赖包都是一致的,
问题及解决:packag.json只单纯记录本项目的依赖, 而没有记录下依赖的依赖, 并且依赖之间的版本号又没有明确固定, 导致无法保证依赖环境一致,而package-lock.json的出现就是解决上述问题,
1.在根目录下创建 index.html文件,输入以下代码
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>vite</div>
</body>
</html>
最简单的vite项目就完成了
2.命令行输入 vite 启动项目 ,浏览器访问,就可以看到index.html里的内容了
四、安装VUE3
运行一下命令来安装Vue3
npm install vue@next --save-dev
五、(如果用JS无需安装这一步)安装TypeScript
运行一下命令来安装TypeScript
npm install typescript --save-dev
六、配置Vite
1.安装依赖插件
npm install @vitejs/plugin-vue -D
2.配置Vite:在项目根目录下新建一个vite.config.js文件,输入以下代码。
javascript
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
});
3.创建所需要的目录文件
在根目录下创建src目录,然后在src目录下创建App.vue 和 main.ts文件
七、安装常用模块(Vue-router+axios+pinia+scss+element-plus)
<1>vue-router安装
1.安装 vue-router依赖包
npm install vue-router@next --save
2.配置router文件
创建src/router/index.ts
文件,使用路由懒加载,优化访问性能。
javascript
import { createRouter, createWebHistory } from "vue-router";
const routes = [
{
path: "/",
name: "Home",
component: () => import("@/views/home.vue"), // 建议进行路由懒加载,优化访问性能
},
{
path: "/about",
name: "About",
component: () => import("@/views/about.vue"),
},
];
const router = createRouter({
history: createWebHistory(), // 使用history模式
// history: createWebHashHistory(), // 使用hash模式
routes,
});
export default router;
3.main.js里面引入router
javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
createApp(App).use(router).mount('#app')
4.使用router
在App.vue
文件中使用router-view
组件,路由匹配到组件会通过router-view
组件进行渲染。
html
<template>
<div id="nav">
<router-link to="/">Home</router-link> | <router-link to="/about">About</router-link>
</div>
<router-view />
<template>
<2>安装axios,二次请求分装
npm install axios --save
在src下创建两个目录
fetch.js文件代码 (请求响应拦截)
lua
import router from "@/router/index"; // 引入路由,token过期时返回登录页
// import Cookies from "js-cookie"; // 引入Cookies插件,用来存储token ,未下载 需要下载 npm install js-cookie
import axios from "axios";
axios.defaults.headers["Content-Type"] = "application/json;charset=UTF-8"; //设置请求头信息
const fetch = axios.create({
baseURL: import.meta.env.VITE_BASE_API,
timeout: 60 * 1000, // 设置超时时间
});
// 请求拦截器-效验token
fetch.interceptors.request.use(
(config) => {
console.log('config',config);
if(config.url=='/auth/login'){
console.log('login');
return config;
}else if(config.url=='/auth/getMachineCode'){
console.log('getMachineCode');
return config;
}else{
// const token = Cookies.get("token") || ""; // 设置token,从localStorage里读出来
const token=window.localStorage.getItem('token')
// console.log('token',token);
if(!token){
• router.push("/login");
• ElNotification({
• title: 'Token',
• message: 'token失效,请重新登录',
• type: 'info',
• })
}else{
config.headers["Authorization"] = token;
return config;
}
}
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
fetch.interceptors.response.use(
(res) => {
success(res)
return res
},
(error) => {
console.log(error);
fail(error)
}
);
function success(res) {
ElMessage({
message: res.data.msg,
type: "success",
});
}
function fail(error) {
ElMessage({
message: error.data.msg,
type: "fail",
});
}
export default fetch;
request.js文件(封装请求类型)
php
import fetch from "./fetch";
function request(url, method, data) {
switch (method) {
case "get":
return fetch({
• method: "get",
• url:url,
• params: data,
});
case "post":
return fetch({
• method: "post",
• url:url,
• data,
});
case "download":
return fetch({
• method: "get",
• url: url,
• params: data,
• // responseType: "blob",
});
case 'upload':
return fetch({
• method: 'post',
• headers: { 'Content-Type': 'multipart/form-data' },
• url:url,
• data
})
default:
return fetch;
}
}
export default request;
// 注:download、upload 并非请求类型,只是为了方便下载、上传文件添加的,修改使用
api/index.js(封装请求的接口)举例子login接口
bash
// 封装接口
import request from "@/utils/request";
// 登录
export function login(data) {
return request("/auth/login", "post", data);
}xxxxxxxxxx pnpm i pinia -S // 封装接口import request from "@/utils/request";// 登录export function login(data) { return request("/auth/login", "post", data);}
封装.evn环境配置文件
跟目录下新建 .env.development(开发环境) .env.production(生产环境)两个文件
代码如下:
ini
.env.development文件
VITE_NODE_ENV = development
VITE_NAME ='开发环境'
VITE_BASE_API = '/api/v1'
VITE_BASE_URL = "http://xxx.xxx.xxx:3000/api/v1" //后端接口地址
.env.production文件
ini
VITE_NODE_ENV = production
VITE_NAME ='生产环境'
VITE_BASE_API = 'http://xxx.xxx.xxx:3000/api/v1'
修改pages.json中
bash
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"dev": "vite --mode development",
"build": "vite build --mode production",
"start": "vite --mode production",
"build:env": "vite build --mode development"
},
将.env中的变量,分别用在fatch.js 和vite.config.js中
<3>安装element-plus
npm install element-plus --save
在main.js中引入
javascript
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from '@/App.vue'
import router from '@/router/index'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(router)
app.use(ElementPlus)
app.mount('#app')
引入后在页面中直接可以用
<4>pinia安装
css
npm i pinia -S
在main.js引入
javascript
import { createPinia } from 'pinia'
app.use(createPinia())
在src目录下创建store/index.js
javascript
import { defineStore } from "pinia";
// 第一个参数 storeId 是仓库的key 必须独一无二
export const useStore = defineStore("storeId", {
state: () => {
return { count: 0, name: "张三" };
},
getters: {},
actions: {},
});
在组件中就可以使用,store/index.js文件 state中的数据
xml
<template>
<div>
<h1>about页面</h1>
{{ name }}
</div>
</template>
<script setup>
import { useStore } from '@/store/index'
const store = useStore();
const { name } = store;
</script>
<style lang="scss" scoped></style>