脚手架脚手架搭建项目框架
一. create-vite
npm create vite@latest(yarn create vite)安装脚手架命令
二. vue-cli
npm i -g @vue-cli安装脚手架命令
vue create project1创建项目
三. create-vue(vue官方的项目脚手架工具,内置了vite构建工具)项目开发中使用的脚手架
1.技术栈:
Create-vue脚手架 + Vite构建工具 + vue3组合式API (vue3选项式API)+ typescript + vue-router + pinia状态管理 (vuex状态管理)+ axios网络库 + vant3 UI组件库(element-plus UI组件库) + eslint + pretter + sass
2.脚手架搭建项目框架步骤:
1) npm init vue@latest 安装脚手架命令。
根据预设生成相应的配置文件(选择ts、vue-router、pinia、eslint、pretter)。

2) pinia配置:
npm i pinia-plugin-persist -S 安装pinia持久化存储插件。
创建stores文件夹→index.ts(创建pinia根存储,集成插件)
javascript
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'//引入pinia持久化存储插件
const storeRoot = createPinia()
storeRoot.use(piniaPluginPersist)//集成插件
export default storeRoot
main.js入口文件(集成pinia)
javascript
import { createApp } from "vue";
import router from "./router";
import store from "./store";
import App from "./App.vue";
import 'normalize.css' // 重置样式
const app = createApp(App)
app.use(router);
app.use(store);
app.mount("#app");
stores文件夹→user.ts(定义store存储对象,持久化存储增加persist选项)
javascript
import {defineStore} from 'pinia'
/**
* 定义名为useUserStore的存储对象
* defineStore方法
* 第一个参数: 模块名称是唯一的
* 第二个参数: 选项对象 state, actions, getters
* data methods computed
*/
export const useUserStore = defineStore('user',{
state(){
return {
account:null // 账户数据 {name,nick,password}
}
},
actions:{
// 具体业务逻辑,可以是同步或异步操作
saveAccount(account){
this.account = account
}
},
getters:{
//getters中定义的方法名/计算属性名不能与state相同
// userAccount:state => {
// return state.account
// }//定义方式1
userAccount(){
return this.account
}//定义方式2
},
persist: {//持久化存储
enabled: true,
strategies: [
{
key: user,
storage: localStorage,
paths: ['account'],
},
],
},
})
3)Sass、axios网络库、UI组件库需手动安装集成。状态管理vuex也需要手动安装集成。
npm i normalize.css -S 安装样式重置库(兼容浏览器)。main.ts中引入import'normalize.css'
npm i sass -d 安装sass(css预处理器,开发环境用)。
npm install axios -s 安装网络库axios(前后端数据交互)。
创建utils文件夹→request.ts中配置(创建axios实例,封装请求/响应拦截器)
go
import axios from 'axios'
import { Toast } from 'vant';
// 服务根地址
// export const baseURL = 'http://10.7.163.165:8089' // 开发环境
/**
* 创建axios实例
* 封装baseURL
*/
const axiosInstance = axios.create({
baseURL, // 服务根地址
timeout: 3000, // 超时时间
})
/**
* 请求拦截器
*/
axiosInstance.interceptors.request.use(
config => {
const token = localStorage.getItem('TOKEN')
if(token){
config.headers['Authorization'] = token
}
return config
},
error => {
return Promise.reject(error)
}
)
/**
* 响应拦截器
*/
axiosInstance.interceptors.response.use(
response => {
return response.data
},
error => {
const { response } = error
if (response) {
const status = response.status
switch (status) {
case 404:
Toast('资源不存在 404')
break
case 401:
Toast('Unauthorized 身份验证凭证缺失!')
break
case 403:
Toast('403 Forbidden - 拒绝访问!')
break
case 500:
Toast('服务器出错')
break
default:
Toast('出现异想不到的错误!')
break
}
}else {
// 说明服务器连结果都没有返回,可能的原因有两种:
/**
* 1. 服务器崩掉了
* 2. 前端客户端断网状态
*/
if (!window.navigator.onLine) {
// 判断为断网,可以跳转到断网页面
Toast('网络不可用,请检查您的网络连接!')
return
} else {
Toast('连接服务端出错!' + error?.message)
return Promise.reject(error)
}
}
return Promise.reject(error)
}
)
export default axiosInstance
vant组件库安装与配置
- npm i vant@latest-v3 安装vant组件库
- npm i unplugin-vue-components -D 安装vant按需引入插件。vite.config.ts中引入集成
- npm i postcss-pxtorem -D安装移动端适配插件,将px单位转化为rem单位。vite.config.ts中引入集成
- npm i amfe-flexible -D安装移动端适配插件,适配不同屏幕尺寸。main.ts中引入
vite.config.ts
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'//引入按需引入插件
import { VantResolver } from 'unplugin-vue-components/resolvers'//引入按需引入插件
import postCssPxToRem from 'postcss-pxtorem'//引入移动端适配插件
import { viteMockServe } from 'vite-plugin-mock'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [VantResolver()],//集成按需引入插件
}),
viteMockServe({//集成mock模拟接口数据插件
// 更多配置见最下方
supportTs: true,
logger: false,
mockPath: './mock/', // 文件位置
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css:{
postcss:{
plugins:[
postCssPxToRem({//自适应,px转rem
rootValue:75,//换算的基数(设计图750的根字体为75)
propList:['*']//需要转换的属性,*代表全部
})
]
}
},
server:{//代理服务器
proxy: {
'/api': {
target: 'http://124.71.63.13:8088/',
changeOrigin: true,
// rewrite: path => path.replace(/^\/api/, '')
}
}
},
})
main.ts
javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './stores'
import 'normalize.css' // 重置样式
// 导入vant函数组件样式
import 'vant/es/toast/style'
import 'vant/es/dialog/style'
import 'vant/es/notify/style'
import 'vant/es/image-preview/style'
//引入amfe-flexible屏幕适配插件
import 'amfe-flexible'
const app = createApp(App)
app.use(store)
app.use(router)
app.mount('#app')
elementplus组件库安装与配置
- npm install element-plus --save安装elementplus组件库
- npm install -d unplugin-vue-components unplugin-auto-import安装两个插件自动按需引入
vite.config.js集成插件
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'//引入插件
import Components from 'unplugin-vue-components/vite'//引入插件
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'//引入插件
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({//集成插件
resolvers: [ElementPlusResolver()],
}),
Components({//集成插件
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
})
main.js引入elementplus样式,否则可能出现使用组件没效果。
javascript
import { createApp } from "vue";
import router from "./router";
import store from "./store";
import 'element-plus/dist/index.css';//引入elementplus样式
import App from "./App.vue";
import ElementPlus from 'element-plus';//完整引入elementplus,文件大小会很大。可以考虑按需引入
const app = createApp(App);
app.use(router);
app.use(store);
app.use(ElementPlus);//完整引入elementplus,文件大小会很大。可以考虑按需引入
app.mount("#app");
状态管理vuex安装与配置
- npm install vuex@next(4.0.2) --save安装vuex插件
- npm i vuex-persistedstate -s安装vuex持久化存储插件
main.js引入集成到vue
javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')
创建story文件夹→index.js文件集成持久化存储插件
javascript
import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
const store = createStore({
// 集成持久化存储插件
plugins:[createPersistedState({
storage:sessionStorage,
key:'storekey'
})]
state: {//状态数据
count: 0
},
mutations: {//操作state状态。第一个参数:state对象,第二个参数:外部传入参数
PLUS(state) {//方法
// state.count = num
state.count++
},
},
/**
* 定义操作mutations方法的方法
* 供外部组件调用
* $store.dispatch('')
* 1. 单向数流操作方式,保存状态数据以预期方式改变
* 2. actions 异步操作
* mutations 同步操作
*/
actions: {//操作mutations中的方法
// plus(context) {//方法
// context.commit('PLUS')
// }
plus({ commit }) {//解构
commit('PLUS')
},
chs({ commit },num) {//传参
commit('CHS',num)
}
},
getters: {//获取值,类似计算属性
num: (state) => { return state.count }
// num: state => state.count
}
})
export default store
3.解决引入vue组件ts报错(因为ts不识别.vue文件,需在env.d.ts中声明)
env.d.ts
typescript
// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
4.目录结构介绍

- npm install(npm i)下载依赖
- npm run dev运行
5.打包
- 将vue文件编译成浏览器能识别的js/html/css文件、ts编译成js文件、scss编译成css文件,压缩处理。
- 编译后的文件存放在dist目录下(与src同级),都是html/css/js文件,将其部署到服务器上用户就可以用了。
接口环境配置: 开发环境(测试数据)/生产环境(用户使用的数据)
创建utils文件夹→request.ts中配置(创建axios实例,封装请求/响应拦截器,配置接口环境)
解决跨域问题走代理服务器:baseUrl地址为当前客户端地址,vite.config.ts配置代理服务器,代理服务器地址为目标地址(一般指测试地址/线上服务器地址)。
javascript
import axios from 'axios'
import { Toast } from 'vant'
// 服务根地址
// export const baseURL = 'http://10.7.163.165:8089' // 开发环境
// 生产环境 如果服务端没做跨域处理,使用代理服务器
// 走代理服务器,baseURL 地址配置为与当前客户端地址相同
export let baseURL = 'http://10.7.163.165:8089' // 开发环境
/**
* process.env.NODE_ENV
* production 生产环境
* npm run build
* development 开发环境
* npm run dev
*/
switch (process.env.NODE_ENV) {
case 'production':
baseURL = 'http://124.71.63.13' // 生产环境
break
case 'development':
baseURL = 'http://10.7.163.165:8089' // 开发环境
break
}
/**
* 创建axios实例
* 封装baseURL
*/
const axiosInstance = axios.create({
baseURL, // 服务根地址
timeout: 3000, // 超时时间
})
/**
* 请求拦截器
*/
axiosInstance.interceptors.request.use(
config => {
const token = localStorage.getItem('TOKEN')
if (token) {
config.headers['Authorization'] = token
}
return config
},
error => {
return Promise.reject(error)
}
)
/**
* 响应拦截器
*/
axiosInstance.interceptors.response.use(
response => {
return response.data
},
error => {
const { response } = error
if (response) {
const status = response.status
switch (status) {
case 404:
Toast('资源不存在 404')
break
case 401:
Toast('Unauthorized 身份验证凭证缺失!')
break
case 403:
Toast('403 Forbidden - 拒绝访问!')
break
case 500:
Toast('服务器出错')
break
default:
Toast('出现异想不到的错误!')
break
}
} else {
// 说明服务器连结果都没有返回,可能的原因有两种:
/**
* 1. 服务器崩掉了
* 2. 前端客户端断网状态
*/
if (!window.navigator.onLine) {
// 判断为断网,可以跳转到断网页面
Toast('网络不可用,请检查您的网络连接!')
return
} else {
Toast('连接服务端出错!' + error?.message)
return Promise.reject(error)
}
}
return Promise.reject(error)
}
)
export default axiosInstance
tsconfig.json(解决request.ts中环境配置时process报错)
perl
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
// 解决process.env.NODE_ENV报错,
// 1.安装npm i @types/node -S
// 配置"types": ["node"]
"types": ["node"]
},
"references": [
{
"path": "./tsconfig.config.json"
}
]
}
vite.config.ts配置代理服务器
javascript
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'//引入按需引入插件
import { VantResolver } from 'unplugin-vue-components/resolvers'//引入按需引入插件
import postCssPxToRem from 'postcss-pxtorem'//引入移动端适配插件
import { viteMockServe } from 'vite-plugin-mock'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [VantResolver()],//集成按需引入插件
}),
viteMockServe({//集成mock模拟接口数据插件
// 更多配置见最下方
supportTs: true,
logger: false,
mockPath: './mock/', // 文件位置
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css:{
postcss:{
plugins:[
postCssPxToRem({//自适应,px转rem
rootValue:75,//换算的基数(设计图750的根字体为75)
propList:['*']//需要转换的属性,*代表全部
})
]
}
},
server:{//代理服务器
proxy: {
'/api': {
target: 'http://124.71.63.13:8088/',//目标地址
changeOrigin: true,//是否跨域
//这里理解成用'/api'代替target里面的地址,比如我要调用'http://40.00.100.100:3002/user/add',直接写'/api/user/add'即可
rewrite: (path) => path.replace(/^**\/** api/, ''),
}
}
},
})
npm run build打包
四. quasar-cli项目开发中使用的脚手架
关于quasar要求:
- Node 12+用于Quasar CLI与Webpack,Node 14+用于Quasar CLI与Vite。
- Yarn v1(强烈推荐),PNPM,或NPM。
npm i -g @quasar/cli 安装脚手架命令
npm init quasar 初始化quasar根据预设生成相应的配置文件

此时回车,会生成项目文件和目录

提示安装项目依赖,选择yes回车

quasar dev(npm run dev)运行