vuex切换成pinia

This commit is contained in:
D 2023-12-12 13:49:31 +08:00
parent 2456256f3a
commit 01a159d4a7
11 changed files with 281 additions and 321 deletions

View File

@ -63,7 +63,7 @@
"uview-plus": "^3.1.36", "uview-plus": "^3.1.36",
"vue": "^3.2.47", "vue": "^3.2.47",
"vue-i18n": "^9.2.2", "vue-i18n": "^9.2.2",
"vuex": "^4.1.0" "pinia": "2.0.22"
}, },
"devDependencies": { "devDependencies": {
"@dcloudio/types": "^3.3.3", "@dcloudio/types": "^3.3.3",

View File

@ -59,6 +59,9 @@ dependencies:
dayjs: dayjs:
specifier: ^1.11.9 specifier: ^1.11.9
version: 1.11.9 version: 1.11.9
pinia:
specifier: 2.0.22
version: 2.0.22(typescript@4.9.5)(vue@3.2.47)
tslib: tslib:
specifier: ^2.6.2 specifier: ^2.6.2
version: 2.6.2 version: 2.6.2
@ -71,9 +74,6 @@ dependencies:
vue-i18n: vue-i18n:
specifier: ^9.2.2 specifier: ^9.2.2
version: 9.2.2(vue@3.2.47) version: 9.2.2(vue@3.2.47)
vuex:
specifier: ^4.1.0
version: 4.1.0(vue@3.2.47)
devDependencies: devDependencies:
'@dcloudio/types': '@dcloudio/types':
@ -3412,6 +3412,7 @@ packages:
/abab@2.0.6: /abab@2.0.6:
resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
deprecated: Use your platform's native atob() and btoa() methods instead
dev: true dev: true
/accepts@1.3.8: /accepts@1.3.8:
@ -4116,6 +4117,7 @@ packages:
/domexception@2.0.1: /domexception@2.0.1:
resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
engines: {node: '>=8'} engines: {node: '>=8'}
deprecated: Use your platform's native DOMException instead
dependencies: dependencies:
webidl-conversions: 5.0.0 webidl-conversions: 5.0.0
dev: true dev: true
@ -5864,6 +5866,24 @@ packages:
requiresBuild: true requiresBuild: true
optional: true optional: true
/pinia@2.0.22(typescript@4.9.5)(vue@3.2.47):
resolution: {integrity: sha512-u+b8/BC+tmvo3ACbYO2w5NfxHWFOjvvw9DQnyT0dW8aUMCPRQT5QnfZ5R5W2MzZBMTeZRMQI7V/QFbafmM9QHw==}
peerDependencies:
'@vue/composition-api': ^1.4.0
typescript: '>=4.4.4'
vue: ^2.6.14 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
typescript:
optional: true
dependencies:
'@vue/devtools-api': 6.5.0
typescript: 4.9.5
vue: 3.2.47
vue-demi: 0.14.6(vue@3.2.47)
dev: false
/pirates@4.0.6: /pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -6610,7 +6630,6 @@ packages:
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true
dev: true
/unicode-canonical-property-names-ecmascript@2.0.0: /unicode-canonical-property-names-ecmascript@2.0.0:
resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
@ -6747,6 +6766,21 @@ packages:
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
/vue-demi@0.14.6(vue@3.2.47):
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
dependencies:
vue: 3.2.47
dev: false
/vue-i18n@9.2.2(vue@3.2.47): /vue-i18n@9.2.2(vue@3.2.47):
resolution: {integrity: sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==} resolution: {integrity: sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
@ -6797,15 +6831,6 @@ packages:
'@vue/server-renderer': 3.2.47(vue@3.2.47) '@vue/server-renderer': 3.2.47(vue@3.2.47)
'@vue/shared': 3.2.47 '@vue/shared': 3.2.47
/vuex@4.1.0(vue@3.2.47):
resolution: {integrity: sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==}
peerDependencies:
vue: ^3.2.0
dependencies:
'@vue/devtools-api': 6.5.0
vue: 3.2.47
dev: false
/w3c-hr-time@1.0.2: /w3c-hr-time@1.0.2:
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
deprecated: Use your platform's native performance.now() and performance.timeOrigin. deprecated: Use your platform's native performance.now() and performance.timeOrigin.

View File

@ -1,5 +1,6 @@
import App from './App.vue' import App from './App.vue'
import plugins from './plugins' import plugins from './plugins'
import store from './store'
import uviewPlus from 'uview-plus' import uviewPlus from 'uview-plus'
@ -14,6 +15,7 @@ export function createApp() {
const app = createSSRApp(App) const app = createSSRApp(App)
app.use(uviewPlus) app.use(uviewPlus)
app.use(plugins) app.use(plugins)
app.use(store)
// 全局方法挂载 // 全局方法挂载
app.config.globalProperties.useDict = useDict app.config.globalProperties.useDict = useDict

View File

@ -39,7 +39,7 @@ import modal from '@/plugins/modal'
import { getCodeImg } from '@/api/login' import { getCodeImg } from '@/api/login'
import { ref } from "vue"; import { ref } from "vue";
import config from '@/config.js' import config from '@/config.js'
import store from '@/store' import useUserStore from '@/store/modules/user'
const codeUrl = ref(""); const codeUrl = ref("");
const captchaEnabled = ref(true); const captchaEnabled = ref(true);
const globalConfig = ref(config); const globalConfig = ref(config);
@ -49,6 +49,7 @@ const loginForm = ref({
code: "", code: "",
uuid: '' uuid: ''
}); });
const userStore = useUserStore()
// //
function getCode() { function getCode() {
@ -75,7 +76,7 @@ async function handleLogin() {
}; };
// //
async function pwdLogin() { async function pwdLogin() {
store.dispatch('Login', loginForm.value).then(() => { userStore.login(loginForm.value).then(() => {
modal.closeLoading() modal.closeLoading()
loginSuccess() loginSuccess()
}).catch(() => { }).catch(() => {
@ -88,8 +89,7 @@ async function pwdLogin() {
function loginSuccess(result) { function loginSuccess(result) {
// //
store.dispatch('GetInfo').then(res => { userStore.getInfo().then(res => {
uni.switchTab({ uni.switchTab({
url: '/pages/index' url: '/pages/index'
}); });

View File

@ -1,5 +1,5 @@
<template> <template>
<view class="mine-container" :style="{height: `${windowHeight}px`}"> <view class="mine-container" :style="{ height: `${windowHeight}px` }">
<!--顶部个人信息栏--> <!--顶部个人信息栏-->
<view class="header-section"> <view class="header-section">
<view class="flex padding justify-between"> <view class="flex padding justify-between">
@ -86,151 +86,152 @@
</template> </template>
<script setup> <script setup>
import storage from '@/utils/storage' import { ref } from "vue";
import store from '@/store' import config from '@/config.js'
import { ref } from "vue"; import useUserStore from '@/store/modules/user'
import config from '@/config.js' const userStore = useUserStore()
const name=store.state.user.name; const name = userStore.name;
const version= config.appInfo.version; const version = config.appInfo.version;
const avatar=ref(store.state.user.avatar);
const windowHeight=ref(uni.getSystemInfoSync().windowHeight - 50);
const popup = ref(null);
uni.$on('refresh', () => { const avatar = ref(userStore.avatar);
avatar.value=store.state.user.avatar; const windowHeight = ref(uni.getSystemInfoSync().windowHeight - 50);
const popup = ref(null);
uni.$on('refresh', () => {
avatar.value = userStore.avatar;
})
console.log(avatar.value)
function handleToInfo() {
uni.navigateTo({
url: '/pages_mine/pages/info/index'
});
};
function handleToEditInfo() {
uni.navigateTo({
url: '/pages_mine/pages/info/edit'
});
};
function handleToSetting() {
uni.navigateTo({
url: '/pages_mine/pages/setting/index'
});
};
function handleToLogin() {
uni.reLaunch({
url: '/pages/login'
});
};
function handleToAvatar() {
uni.navigateTo({
url: '/pages_mine/pages/avatar/index'
});
};
function handleLogout() {
popup.value.open();
};
function dialogConfirm() {
//console.log('----------------------------')
userStore.logOut().then(() => {
uni.reLaunch({
url: '/pages/login'
});
}) })
};
console.log(avatar.value) function dialogClose() {
//console.log('')
function handleToInfo() { };
uni.navigateTo({ function handleHelp() {
url: '/pages_mine/pages/info/index' uni.navigateTo({
}); url: '/pages_mine/pages/help/index'
}; });
function handleToEditInfo() { };
uni.navigateTo({ function handleAbout() {
url: '/pages_mine/pages/info/edit' uni.navigateTo({
}); url: '/pages_mine/pages/about/index'
}; });
function handleToSetting() { };
uni.navigateTo({ function handleJiaoLiuQun() {
url: '/pages_mine/pages/setting/index' uni.showToast({
}); title: 'QQ群133713780',
}; mask: false,
function handleToLogin() { icon: "none",
uni.reLaunch({ duration: 1000
url: '/pages/login' });
}); };
}; function handleBuilding() {
function handleToAvatar() { uni.showToast({
uni.navigateTo({ title: '模块建设中~',
url: '/pages_mine/pages/avatar/index' mask: false,
}); icon: "none",
}; duration: 1000
function handleLogout() { });
popup.value.open(); }
};
function dialogConfirm() {
//console.log('----------------------------')
store.dispatch('LogOut').then(() => {
uni.reLaunch({
url: '/pages/login'
});
})
};
function dialogClose() {
//console.log('')
};
function handleHelp() {
uni.navigateTo({
url: '/pages_mine/pages/help/index'
});
};
function handleAbout() {
uni.navigateTo({
url: '/pages_mine/pages/about/index'
});
};
function handleJiaoLiuQun() {
uni.showToast({
title: 'QQ群133713780',
mask: false,
icon:"none",
duration: 1000
});
};
function handleBuilding() {
uni.showToast({
title: '模块建设中~',
mask: false,
icon:"none",
duration: 1000
});
}
</script> </script>
<style lang="scss"> <style lang="scss">
page {
background-color: #f5f6f7;
}
page { .mine-container {
background-color: #f5f6f7; width: 100%;
} height: 100%;
.mine-container {
width: 100%;
height: 100%;
.header-section { .header-section {
padding: 15px 15px 45px 15px; padding: 15px 15px 45px 15px;
background-color: #3c96f3; background-color: #3c96f3;
color: white; color: white;
.login-tip { .login-tip {
font-size: 18px;
margin-left: 10px;
}
.cu-avatar {
border: 2px solid #eaeaea;
.icon {
font-size: 40px;
}
}
.user-info {
margin-left: 15px;
.u_title {
font-size: 18px; font-size: 18px;
margin-left: 10px; line-height: 30px;
}
.cu-avatar {
border: 2px solid #eaeaea;
.icon {
font-size: 40px;
}
}
.user-info {
margin-left: 15px;
.u_title {
font-size: 18px;
line-height: 30px;
}
} }
} }
}
.content-section { .content-section {
position: relative; position: relative;
top: -50px; top: -50px;
.mine-actions { .mine-actions {
margin: 15px 15px; margin: 15px 15px;
padding: 20px 0px; padding: 20px 0px;
border-radius: 8px; border-radius: 8px;
background-color: white; background-color: white;
.action-item { .action-item {
.icon { .icon {
font-size: 28px; font-size: 28px;
} }
.text { .text {
display: block; display: block;
font-size: 13px; font-size: 13px;
margin: 8px 0px; margin: 8px 0px;
}
} }
} }
} }
} }
}
</style> </style>

View File

@ -1,10 +0,0 @@
import { GetterTree } from "vuex"
const getters:GetterTree<any,any> = {
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
roles: state => state.user.roles,
permissions: state => state.user.permissions
}
export default getters

View File

@ -1,12 +1,4 @@
import user from '@/store/modules/user' import { createPinia } from "pinia"
import dict from '@/store/modules/dict'
import getters from './getters' const store = createPinia()
import { createStore } from "vuex"; export default store
const store = createStore<any>({
modules: {
user,
dict
},
getters
});
export default store;

View File

@ -1,27 +1,18 @@
import config from "@/config"; import { defineStore } from "pinia";
import storage from "@/utils/storage"; const useDictStore = defineStore("dict", {
import constant from "@/utils/constant"; state: () => ({
import { login, logout, getInfo } from "@/api/login";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { dictStateType, dictType } from "@/types/store";
import { Module } from "vuex";
const baseUrl = config.baseUrl;
const dict: Module<dictStateType, dictStateType> = {
state: {
dict: new Array(), dict: new Array(),
}, }),
actions: { actions: {
// 获取字典 // 获取字典
getDict({ state }, _key) { getDict(_key: string) {
if (_key == null && _key == "") { if (_key == null && _key == "") {
return null; return null;
} }
try { try {
for (let i = 0; i < state.dict.length; i++) { for (let i = 0; i < this.dict.length; i++) {
if (state.dict[i].key == _key) { if (this.dict[i].key == _key) {
return state.dict[i].value; return this.dict[i].value;
} }
} }
} catch (e) { } catch (e) {
@ -29,21 +20,21 @@ const dict: Module<dictStateType, dictStateType> = {
} }
}, },
// 设置字典 // 设置字典
setDict({ state }, dict: dictType) { setDict(_key: string, value: any) {
if (dict.key !== null && dict.key !== "") { if (_key !== null && _key !== "") {
state.dict.push({ this.dict.push({
key: dict.key, key: _key,
value: dict.value, value: value,
}); });
} }
}, },
// 删除字典 // 删除字典
removeDict({ state }, _key) { removeDict(_key: string) {
var bln = false; var bln = false;
try { try {
for (let i = 0; i < state.dict.length; i++) { for (let i = 0; i < this.dict.length; i++) {
if (state.dict[i].key == _key) { if (this.dict[i].key == _key) {
state.dict.splice(i, 1); this.dict.splice(i, 1);
return true; return true;
} }
} }
@ -53,12 +44,12 @@ const dict: Module<dictStateType, dictStateType> = {
return bln; return bln;
}, },
// 清空字典 // 清空字典
cleanDict({ state }) { cleanDict() {
state.dict = new Array(); this.dict = new Array();
}, },
// 初始字典 // 初始字典
initDict() {}, initDict() {},
}, },
}; });
export default dict; export default useDictStore;

View File

@ -1,99 +1,80 @@
import config from '@/config'
import storage from '@/utils/storage'
import constant from '@/utils/constant'
import { login, logout, getInfo } from '@/api/login' import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
import { UserState, UserForm } from '@/types/store' import defAva from '@/static/images/profile.jpg'
import { Module } from 'vuex' import { defineStore } from 'pinia'
const baseUrl = config.baseUrl export interface LoginForm {
username: string
const user: Module<UserState, UserState> = { password: string
state: { code: string
token: getToken(), uuid: string
name: storage.get(constant.name),
avatar: storage.get(constant.avatar),
roles: storage.get(constant.roles),
permissions: storage.get(constant.permissions)
},
mutations: {
SET_TOKEN: (state, token: string) => {
state.token = token
},
SET_NAME: (state, name: string) => {
state.name = name
storage.set(constant.name, name)
},
SET_AVATAR: (state, avatar: string) => {
state.avatar = avatar
storage.set(constant.avatar, avatar)
},
SET_ROLES: (state, roles: Array<string>) => {
state.roles = roles
storage.set(constant.roles, roles)
},
SET_PERMISSIONS: (state, permissions: Array<string>) => {
state.permissions = permissions
storage.set(constant.permissions, permissions)
}
},
actions: {
// 登录
Login({ commit }, userInfo: UserForm) {
const username = userInfo.username
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then((res: any) => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then((res: any) => {
const user = res.user
const avatar = (user == null || user.avatar == "" || user.avatar == null) ? "@/static/images/profile.jpg" : baseUrl + user.avatar
const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
if (res.roles && res.roles.length > 0) {
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_NAME', username)
commit('SET_AVATAR', avatar)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout().then((res) => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
removeToken()
storage.clean()
resolve(res)
}).catch(error => {
reject(error)
})
})
}
}
} }
export default user
const useUserStore = defineStore(
'user',
{
state: () => ({
token: getToken(),
name: '',
avatar: '',
roles: Array(),
permissions: []
}),
actions: {
// 登录
login(userInfo: LoginForm) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then((res:any) => {
setToken(res.token)
this.token = res.token
resolve(null)
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
getInfo() {
return new Promise((resolve, reject) => {
getInfo().then((res:any) => {
const user = res.user
// @ts-ignore
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
this.roles = res.roles
this.permissions = res.permissions
} else {
this.roles = ['ROLE_DEFAULT']
}
this.name = user.userName
this.avatar = avatar;
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
logOut() {
return new Promise((resolve, reject) => {
logout().then(() => {
this.token = ''
this.roles = []
this.permissions = []
removeToken()
resolve(null)
}).catch(error => {
reject(error)
})
})
}
}
})
export default useUserStore

View File

@ -1,19 +0,0 @@
export interface UserState {
token: string,
name: string,
avatar: string,
roles: Array<string>
permissions: Array<string>
}
export interface UserForm {
username: string
password: string
code: string
uuid: string
}
export type dictType = { key: string; value: string };
export type dictStateType = { dict: Array<dictType> };

View File

@ -1,4 +1,4 @@
import store from "@/store"; import useDictStore from "@/store/modules/dict";
import { getDicts } from "@/api/system/dict/data"; import { getDicts } from "@/api/system/dict/data";
import { Ref, ref, toRefs } from "vue"; import { Ref, ref, toRefs } from "vue";
@ -8,9 +8,9 @@ import { Ref, ref, toRefs } from "vue";
export function useDict(...args: any[]) { export function useDict(...args: any[]) {
const res: Ref<any> = ref({}); const res: Ref<any> = ref({});
return (() => { return (() => {
args.forEach(async (dictType: string, index) => { args.forEach((dictType, index) => {
res.value[dictType] = []; res.value[dictType] = [];
const dicts = await store.dispatch("getDict", dictType); const dicts = useDictStore().getDict(dictType);
if (dicts) { if (dicts) {
res.value[dictType] = dicts; res.value[dictType] = dicts;
} else { } else {
@ -21,10 +21,7 @@ export function useDict(...args: any[]) {
elTagType: p.listClass, elTagType: p.listClass,
elTagClass: p.cssClass, elTagClass: p.cssClass,
})); }));
store.dispatch("setDict", { useDictStore().setDict(dictType, res.value[dictType]);
key: dictType,
value: res.value[dictType],
});
}); });
} }
}); });