一、先看下我的前一篇vue+pinaia .代码都在文里了。Pinia,Vue生态里Vuex的代替者_东宇科技的博客-CSDN博客我们通过创建一个简单的demo,来认识下pinia .....安装创建项目npm init vite@latestnpm install pinia....引用storeimport { createPinia } from 'pinia' const pinia = createPinia()const app =createApp(App) app.use(pinia)app.mount('#app')....创建stroeimport { defineStore} fromhttps://blog.csdn.net/ldy889/article/details/123481222
二、第二篇整合了vue-routes. https://blog.csdn.net/ldy889/article/details/123527485https://blog.csdn.net/ldy889/article/details/123527485
三、本文在上面的基础上,增加登录页面,登录后后台会返回token,然后跳转到后台首页。验证是否有权限,如直接访问后台的路由地址,路由守卫会返回到login页面登录, 前面2节可以跳着看,本节会贴出完整的代码。
1、npm init vite@latest 我们会得到一个helloWorld的项目。
2、npm i 安装依赖,npm run dev测试看下结果
3、安装 npm install pinia ,element-plus, vue-router, sass, sass-loader
npm i vite-plugin-svg-icons -D 最终选用这个来使用svg-icon:参考:https://github.com/JetBrains/svg-sprite-loader/issues/434https://github.com/JetBrains/svg-sprite-loader/issues/434
4、修改main.ts文件。
import { createApp } from 'vue'
import App from './App.vue'
//引入 pinia store
import { createPinia } from 'pinia'
//引入 element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import Router from './router'
//引入 vite-plugin-svg-icons
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon/index.vue'// svg component
const pinia = createPinia()
const app =createApp(App)
app.component('svg-icon', SvgIcon)
app.use(pinia)
app.use(ElementPlus)
app.use(Router)
app.mount('#app')
5、修改src/App.vue 这个就是添加个路由槽
6、添加 src/router/index.ts , 这里用到扫描import ,vite的功能,取代原来webpack下的插件。不知道的看下我上面第二个文章。或者去vite官方文档里看下懒加载。
import { createRouter, createWebHashHistory } from "vue-router";
const modules = import.meta.glob("../views/*/*.vue");
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod);
});
}
const Router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/",
component: modules["../views/login/index.vue"],
}
],
});
export default Router;
7、添加src/views/login/index.vue页面,写了一个按钮
Hello
8、运行 npm run dev : 结果:
9、添加src/store/index.ts
import { defineStore} from 'pinia'
export const mainStore = defineStore('main',{
state:()=>{
return {
helloWorld:'Hello World',
count:0
}
},
getters:{},
actions:{
changeState(){
this.count++
this.helloWorld='haha'
}
}
})
10、修改src/views/login/index.vue页面
Hello
11、运行结果测试可以取到store里的值。到这里基本跑通了。下面开始写后台了。
12、修改src/views/login/index.vue页面 让他显示该有的样子。
Login Form
Login
username: admin
password: any
13、接下来是一键3连的广告时间。然后详细解读下login.vue.
--------广告位置------
--------广告位置------
14、第一是,图标显示不了了。 关于svg图标的使用,vite里无法使用webpack的svg-sprite-loader插件,而vue-svgicon又只支持vue2,vue3该如何使用svgicon呢。【2022-3-18】
安装: npm i vite-plugin-svg-icons -D
修改vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import {resolve} from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [resolve(process.cwd(), 'src/icons/svg')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
/**
* custom dom id
* @default: __svg__icons__dom__
*/
customDomId: '__svg__icons__dom__',
}),],
resolve: {
// 配置别名
alias: {
'@': resolve(__dirname, './src')
}
}
})
修改main.ts
import { createApp } from 'vue'
import App from './App.vue'
//引入 pinia store
import { createPinia } from 'pinia'
//引入 element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import Router from './router'
//引入 vite-plugin-svg-icons
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon/index.vue'// svg component
const pinia = createPinia()
const app =createApp(App)
app.component('svg-icon', SvgIcon)
app.use(pinia)
app.use(ElementPlus)
app.use(Router)
app.mount('#app')
创建:src/components/SvgIcon/index.vue
更新 src/utils/validate.ts
export const validUsername = (str: string) => ['admin', 'editor'].indexOf(str.trim()) >= 0
export const isExternal = (path: string) => /^(https?:|mailto:|tel:)/.test(path)
export const isArray = (arg: any) => {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]'
}
return Array.isArray(arg)
}
export const isValidURL = (url: string) => {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
}
添加一些svg文件到 src/icons/svg/...
运行结果:
当然点击登录会有问题。
接下来要用pinia了。先安装 vue-request,axios, nprogress进度条。
npm install vue-request
npm install axios
npm i --save-dev @types/nprogress
创建 service/http.ts
//http.ts
import axios, { AxiosRequestConfig } from 'axios'
import NProgress from 'nprogress'
// 设置请求头和请求路径
axios.defaults.baseURL = '/api'
axios.defaults.timeout = 10000
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
axios.interceptors.request.use(
(config): AxiosRequestConfig => {
const token = window.sessionStorage.getItem('token')
if (token) {
//@ts-ignore
config.headers.token = token
}
return config
},
(error) => {
return error
}
)
// 响应拦截
axios.interceptors.response.use((res) => {
if (res.data.code === 111) {
sessionStorage.setItem('token', '')
// token过期操作
}
return res
})
interface ResType {
code: number
data?: T
msg: string
err?: string
}
interface Http {
get(url: string, params?: unknown): Promise>
post(url: string, params?: unknown): Promise>
upload(url: string, params: unknown): Promise>
download(url: string): void
}
const http: Http = {
get(url, params) {
return new Promise((resolve, reject) => {
NProgress.start()
axios
.get(url, { params })
.then((res) => {
NProgress.done()
resolve(res.data)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
},
post(url, params) {
return new Promise((resolve, reject) => {
NProgress.start()
axios
.post(url, JSON.stringify(params))
.then((res) => {
NProgress.done()
resolve(res.data)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
},
upload(url, file) {
return new Promise((resolve, reject) => {
NProgress.start()
axios
.post(url, file, {
headers: { 'Content-Type': 'multipart/form-data' },
})
.then((res) => {
NProgress.done()
resolve(res.data)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
},
download(url) {
const iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.src = url
iframe.onload = function () {
document.body.removeChild(iframe)
}
document.body.appendChild(iframe)
},
}
export default http
创建src/store/login.ts
import { defineStore } from "pinia";
import http from "@/service/http";
import loginApi from "@/service/api/login"
import { ILoginParams } from "@/service/api/types";
export interface IUserState {
token?: string;
name?: string;
avatar?: string;
introduction?: string;
roles?: string[];
email?: string;
}
export const useUserStore = defineStore("user", {
state: () => {
return {
userState: {},
};
},
getters: {
getUserState: (state) => state.userState ,
},
actions: {
async Login(params: ILoginParams) {
// const { data, error } = useRequest(http.post("/", { a: "" }));
this.userState = await loginApi.login(params).catch((error)=>{
return {error:"发送请求失败:Login"};
})
},
},
});
.添加src/api/login.ts
import http from '@/service/http'
import * as T from './types'
const loginApi: T.ILoginApi = {
login(params){
return http.post('/login', params)
}
}
export default loginApi
添加src/api/types.ts
export interface ILoginParams {
userName: string
passWord: string | number
}
export interface ILoginApi {
login: (params: ILoginParams)=> Promise
}
.
好了到这里我们可以登录并跳转到另外一个页面了。
祝你成功。
代码下载:vite-vue-admin-elui-demo-Typescript文档类资源-CSDN下载Vue3+TypeScript+Vite+pinia+element-plus+更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/ldy889/85001855
Vben Admin
一个admin后台。技术栈参考他的。
好的,目前我们能登录了。检查有token和用户信息后,跳转到dashboard页面“/”。所以我们的路由应该看起来是这样的。
import { createRouter, createWebHashHistory } from "vue-router";
const modules = import.meta.glob("../views/*/*.vue");
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod);
});
}
const Router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/login",
component: modules["../views/login/index.vue"],
},
{
path: "/",
component: modules["../views/dashboard/index.vue"],
},
],
});
export default Router;
添加 src/views/dashboard/index.vue
dashborad