vue3项目创建与基本配置
一、使用vue3
首先确保电脑安装有nodejs
且版本在16以上。可通过cmd
打开命令窗口,通过node -v
查看node版本。需要的可自行到官网下载->Node.js
-
安装
npm init vue@latest
-
按照如图选取(全都是默认,之后按需导入)
-
分别运行
cd vue3-project
,npm install
,npm run dev
。运行完后点击运行网址(http://localhost:5173/),若出现vue3初始页面,则vue3项目创建成功,接下来进行一些简单的配置。
二、目录调整
- 删除
components
下面自动生成的内容 - 新建目录
api、utils、views
- 删除
app.vu
e中自定生成的内容
三、axios请求
-
安装
npm install axios
-
配置
request.js
在src/utils/request.js
中配置//导入axios npm install axios import axios from 'axios'; //定义一个变量,记录公共的前缀 , baseURL const baseURL = '/api'; const instance = axios.create({baseURL}) //添加响应拦截器 instance.interceptors.response.use( result=>{ return result.data; }, err=>{ alert('服务异常'); return Promise.reject(err);//异步的状态转化成失败的状态 } ) export default instance;
-
处理跨域
在vie.config.js
中配置import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, //配置代理 server: { proxy: { '/api': { target: 'http://localhost:8080', // 后端服务器地址 changeOrigin: true, // 是否改变请求域名 rewrite: (path) => path.replace(/^\/api/, '')//将原有请求路径中的api替换为'' } } } })
-
优化axios响应拦截器
//添加响应拦截器 instance.interceptors.response.use( result => { //如果业务状态码为0,代表本次操作成功 if (result.data.code == 0) { return result.data; } //代码走到这里,代表业务状态码不是0,本次操作失败 alert(result.data.message || '服务异常'); return Promise.reject(result.data);//异步的状态转化成失败的状态 }, err => { alert('服务异常'); return Promise.reject(err);//异步的状态转化成失败的状态 } )
四、element-plus组件库
-
安装
npm install element-plus --save
-
完整导入
import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' app.use(ElementPlus)
五、sass
npm install sass -D
六、router路由管理
-
安装
npm install vue-router@4
-
创建路由器
在src
目录下创建router
文件夹,在router
中创建index.js
文件import {createRouter, createWebHistory} from 'vue-router' //导入组件 import LoginVue from '@/views/Login.vue' import LayoutVue from "@/views/Layout.vue"; import ArticleCategoryVue from '@/views/article/ArticleCategory.vue' import ArticleManageVue from '@/views/article/ArticleManage.vue' //定义路由关系 const routes = [ { path: '/login', component: LoginVue }, { path: '/', component: LayoutVue, redirect: '/article/manage', // 重定向 children: [ //子路由 {path: '/article/category', component: ArticleCategoryVue}, {path: '/article/manage', component: ArticleManageVue}, ] } ] //创建路由器 const router = createRouter({ history: createWebHistory(), routes: routes }) //导出路由 export default router
-
使用router
在main.js
中导入创建应用实力的js文件,并调用实例的use方法使用路由器import router from '@/router' app.use(router)
-
在
App.vue
中使用<template> <router-view></router-view> </template>
-
在相应文件中使用二级路由
<el-main> <router-view></router-view> </el-main>
-
添加路由路径
<el-menu-item index="/article/category"> <el-icon> <Management /> </el-icon> <span>文章分类</span> </el-menu-item>
-
路由使用
import { useRouter } from 'vue-router' const router = useRouter(); router.push('/')
七、pinia状态管理库
Pinia是Vue的专属状态管理库,它允许你跨组件或页面共享状态
-
安装
npm install pinia
-
使用pinia
在main.js
中,引入pinia,创建pinia实例,并调用vue应用实例的use方法使用piniaimport { createPinia } from 'pinia' const pinia = createPinia() app.use(pinia)
-
定义store
在src
中创建stores
文件夹,在src/stores目录下定义token.jsimport {defineStore} from "pinia"; import {ref} from 'vue'; /** defineStore参数描述: 第一个参数:给状态起名,具有唯一性 第二个参数:函数,可以把定义该状态中拥有的内容 defineStore返回值描述: 返回的是一个函数,将来可以调用该函数,得到第二个参数中返回的内容 */ export const useTokenStore = defineStore('token', () => { //1.定义描述token const token = ref('') //2.定义修改token的方法 const setToken = (newToken) => { token.value = newToken } //3.定义移除token的方法 const removeToken = () => { token.value = '' } return { token, setToken, removeToken } } )
-
使用store
在需要使用状态的地方,导入@/stores/*.js , 使用即可,在Login.vue中导入@/stores/token.js, 并且当用户登录成功后,将token保存pinia中//导入token状态 import { useTokenStore } from '@/stores/token.js' //调用useTokenStore得到状态 const tokenStore = useTokenStore(); //用于登录的事件函数 const login = async () => { let result = await loginService(registerData.value) //保存token tokenStore.setToken(result.data) ElMessage.success('登录成功!') router.push('/') }
-
设置请求头
//导入@/stores/token.js import { useTokenStore } from '../stores/token' //文章分类列表查询 export const articleCategoryListService = () => { //获取token状态 const tokenStore = useTokenStore() //通过请求头Authorization携带token return request.get('/category', { headers: { 'Authorization': tokenStore.token } }) }
-
axios请求拦截
在 src/util/request.js中//导入token状态 import { useTokenStore } from '@/stores/token.js'; //添加请求拦截器 instance.interceptors.request.use( (config)=>{ //在发送请求之前做什么 let tokenStore = useTokenStore() //如果token中有值,在携带 if(tokenStore.token){ config.headers.Authorization=tokenStore.token } return config }, (err)=>{ //如果请求错误做什么 Promise.reject(err) } )
八、Pinia持久化插件
-
安装
npm install pinia-persistedstate-plugin
-
pinia中使用persist插件
在main.js中//导入持久化插件 import {createPersistedState} from'pinia-persistedstate-plugin' const pinia = createPinia() const persist = createPersistedState() //pinia使用持久化插件 pinia.use(persist)
-
在创建定义状态是配置持久化
在src/stores/token.js中export const useTokenStore = defineStore('token', () => { //1.定义描述token const token = ref('') //2.定义修改token的方法 const setToken = (newToken) => { token.value = newToken } //3.定义移除token的方法 const removeToken = () => { token.value = '' } return { token, setToken, removeToken } } , //参数持久化 { persist: true } )
九、axios请求优化配置
//定制请求的实例
//导入axios npm install axios
import axios from 'axios';
import {ElMessage} from 'element-plus'
//定义一个变量,记录公共的前缀 , baseURL
// const baseURL = 'http://localhost:8080';
const baseURL = '/api';
const timeout = 50000;
const instance = axios.create({baseURL, timeout})
//导入token状态
import {useTokenStore} from '@/stores/token.js';
//添加请求拦截器
instance.interceptors.request.use(
(config) => {
//在发送请求之前做什么
let tokenStore = useTokenStore()
//如果token中有值,在携带
if (tokenStore.token) {
config.headers.Authorization = tokenStore.token
}
return config
},
(err) => {
//如果请求错误做什么
return Promise.reject(err)
}
)
import router from "@/router/index.js";
//添加响应拦截器
instance.interceptors.response.use(
result => {
// 判断业务状态码
if (result.data.code === 0) {
return result.data;
}
// 操作失败
ElMessage.error(result.data.msg ? result.data.msg : '服务异常')
return Promise.reject(result.data);
},
err => {
//如果响应状态码时401,代表未登录,给出对应的提示,并跳转到登录页
if (err.response.status === 401) {
router.push('/login').then(r => {
ElMessage.error('请先登录!')
})
} else {
ElMessage.error('服务异常');
}
return Promise.reject(err);//异步的状态转化成失败的状态
}
)
export default instance;
十、最终文件内容
- main.js
import { createApp } from 'vue' import App from './App.vue' // router 路由管理 import router from '@/router' // pinia 状态管理库 import {createPinia} from "pinia" // pinia 持久化插件 import {createPersistedState} from'pinia-persistedstate-plugin' // element-plus 组件库 import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' const app = createApp(App) const pinia = createPinia() const persist = createPersistedState() pinia.use(persist) app.use(router) app.use(pinia) app.use(ElementPlus) app.mount('#app')
- src/router/index.js
import {createRouter, createWebHistory} from 'vue-router' //导入组件 import LoginVue from '@/views/Login.vue' import LayoutVue from "@/views/Layout.vue"; import ArticleCategoryVue from '@/views/article/ArticleCategory.vue' import ArticleManageVue from '@/views/article/ArticleManage.vue' //定义路由关系 const routes = [ { path: '/login', component: LoginVue }, { path: '/', component: LayoutVue, redirect: '/article/manage', children: [ {path: '/article/category', component: ArticleCategoryVue}, {path: '/article/manage', component: ArticleManageVue}, ] } ] //创建路由器 const router = createRouter({ history: createWebHistory(), routes: routes }) //导出路由 export default router
- src/stores/index.js
import {defineStore} from "pinia"; import {ref} from 'vue'; /** defineStore参数描述: 第一个参数:给状态起名,具有唯一性 第二个参数:函数,可以把定义该状态中拥有的内容 defineStore返回值描述: 返回的是一个函数,将来可以调用该函数,得到第二个参数中返回的内容 */ export const useTokenStore = defineStore('token', () => { //1.定义描述token const token = ref('') //2.定义修改token的方法 const setToken = (newToken) => { token.value = newToken } //3.定义移除token的方法 const removeToken = () => { token.value = '' } return { token, setToken, removeToken } }, { persist: true // 持久化存储 } )
- src/utils/request.js
import axios from 'axios'; import {ElMessage} from 'element-plus' //定义一个变量,记录公共的前缀 , baseURL // const baseURL = 'http://localhost:8080'; const baseURL = '/api'; const timeout = 50000; const instance = axios.create({baseURL, timeout}) //导入token状态 import {useTokenStore} from '@/stores/token.js'; //添加请求拦截器 instance.interceptors.request.use( (config) => { //在发送请求之前做什么 let tokenStore = useTokenStore() //如果token中有值,在携带 if (tokenStore.token) { config.headers.Authorization = tokenStore.token } return config }, (err) => { //如果请求错误做什么 return Promise.reject(err) } ) import router from "@/router/index.js"; //添加响应拦截器 instance.interceptors.response.use( result => { // 判断业务状态码 if (result.data.code === 0) { return result.data; } // 操作失败 ElMessage.error(result.data.msg ? result.data.msg : '服务异常') return Promise.reject(result.data); }, err => { //如果响应状态码时401,代表未登录,给出对应的提示,并跳转到登录页 if (err.response.status === 401) { router.push('/login').then(r => { ElMessage.error('请先登录!') }) } else { ElMessage.error('服务异常'); } return Promise.reject(err);//异步的状态转化成失败的状态 } ) export default instance;