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",
"vue": "^3.2.47",
"vue-i18n": "^9.2.2",
"vuex": "^4.1.0"
"pinia": "2.0.22"
},
"devDependencies": {
"@dcloudio/types": "^3.3.3",

View File

@ -59,6 +59,9 @@ dependencies:
dayjs:
specifier: ^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:
specifier: ^2.6.2
version: 2.6.2
@ -71,9 +74,6 @@ dependencies:
vue-i18n:
specifier: ^9.2.2
version: 9.2.2(vue@3.2.47)
vuex:
specifier: ^4.1.0
version: 4.1.0(vue@3.2.47)
devDependencies:
'@dcloudio/types':
@ -3412,6 +3412,7 @@ packages:
/abab@2.0.6:
resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==}
deprecated: Use your platform's native atob() and btoa() methods instead
dev: true
/accepts@1.3.8:
@ -4116,6 +4117,7 @@ packages:
/domexception@2.0.1:
resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
engines: {node: '>=8'}
deprecated: Use your platform's native DOMException instead
dependencies:
webidl-conversions: 5.0.0
dev: true
@ -5864,6 +5866,24 @@ packages:
requiresBuild: 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:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
@ -6610,7 +6630,6 @@ packages:
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
engines: {node: '>=4.2.0'}
hasBin: true
dev: true
/unicode-canonical-property-names-ecmascript@2.0.0:
resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
@ -6747,6 +6766,21 @@ packages:
optionalDependencies:
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):
resolution: {integrity: sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==}
engines: {node: '>= 14'}
@ -6797,15 +6831,6 @@ packages:
'@vue/server-renderer': 3.2.47(vue@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:
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
deprecated: Use your platform's native performance.now() and performance.timeOrigin.

View File

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

View File

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

View File

@ -1,5 +1,5 @@
<template>
<view class="mine-container" :style="{height: `${windowHeight}px`}">
<view class="mine-container" :style="{ height: `${windowHeight}px` }">
<!--顶部个人信息栏-->
<view class="header-section">
<view class="flex padding justify-between">
@ -86,151 +86,152 @@
</template>
<script setup>
import storage from '@/utils/storage'
import store from '@/store'
import { ref } from "vue";
import config from '@/config.js'
const name=store.state.user.name;
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', () => {
avatar.value=store.state.user.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('----------------------------')
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
});
}
import { ref } from "vue";
import config from '@/config.js'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore()
const name = userStore.name;
const version = config.appInfo.version;
const avatar = ref(userStore.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'
});
})
};
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>
<style lang="scss">
page {
background-color: #f5f6f7;
}
page {
background-color: #f5f6f7;
}
.mine-container {
width: 100%;
height: 100%;
.mine-container {
width: 100%;
height: 100%;
.header-section {
padding: 15px 15px 45px 15px;
background-color: #3c96f3;
color: white;
.header-section {
padding: 15px 15px 45px 15px;
background-color: #3c96f3;
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;
margin-left: 10px;
}
.cu-avatar {
border: 2px solid #eaeaea;
.icon {
font-size: 40px;
}
}
.user-info {
margin-left: 15px;
.u_title {
font-size: 18px;
line-height: 30px;
}
line-height: 30px;
}
}
}
.content-section {
position: relative;
top: -50px;
.content-section {
position: relative;
top: -50px;
.mine-actions {
margin: 15px 15px;
padding: 20px 0px;
border-radius: 8px;
background-color: white;
.mine-actions {
margin: 15px 15px;
padding: 20px 0px;
border-radius: 8px;
background-color: white;
.action-item {
.icon {
font-size: 28px;
}
.action-item {
.icon {
font-size: 28px;
}
.text {
display: block;
font-size: 13px;
margin: 8px 0px;
}
.text {
display: block;
font-size: 13px;
margin: 8px 0px;
}
}
}
}
}
</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 dict from '@/store/modules/dict'
import getters from './getters'
import { createStore } from "vuex";
const store = createStore<any>({
modules: {
user,
dict
},
getters
});
export default store;
import { createPinia } from "pinia"
const store = createPinia()
export default store

View File

@ -1,27 +1,18 @@
import config from "@/config";
import storage from "@/utils/storage";
import constant from "@/utils/constant";
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: {
import { defineStore } from "pinia";
const useDictStore = defineStore("dict", {
state: () => ({
dict: new Array(),
},
}),
actions: {
// 获取字典
getDict({ state }, _key) {
getDict(_key: string) {
if (_key == null && _key == "") {
return null;
}
try {
for (let i = 0; i < state.dict.length; i++) {
if (state.dict[i].key == _key) {
return state.dict[i].value;
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
return this.dict[i].value;
}
}
} catch (e) {
@ -29,21 +20,21 @@ const dict: Module<dictStateType, dictStateType> = {
}
},
// 设置字典
setDict({ state }, dict: dictType) {
if (dict.key !== null && dict.key !== "") {
state.dict.push({
key: dict.key,
value: dict.value,
setDict(_key: string, value: any) {
if (_key !== null && _key !== "") {
this.dict.push({
key: _key,
value: value,
});
}
},
// 删除字典
removeDict({ state }, _key) {
removeDict(_key: string) {
var bln = false;
try {
for (let i = 0; i < state.dict.length; i++) {
if (state.dict[i].key == _key) {
state.dict.splice(i, 1);
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
this.dict.splice(i, 1);
return true;
}
}
@ -53,12 +44,12 @@ const dict: Module<dictStateType, dictStateType> = {
return bln;
},
// 清空字典
cleanDict({ state }) {
state.dict = new Array();
cleanDict() {
this.dict = new Array();
},
// 初始字典
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 { getToken, setToken, removeToken } from '@/utils/auth'
import { UserState, UserForm } from '@/types/store'
import { Module } from 'vuex'
import defAva from '@/static/images/profile.jpg'
import { defineStore } from 'pinia'
const baseUrl = config.baseUrl
const user: Module<UserState, UserState> = {
state: {
token: getToken(),
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 interface LoginForm {
username: string
password: string
code: string
uuid: string
}
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 { Ref, ref, toRefs } from "vue";
@ -8,9 +8,9 @@ import { Ref, ref, toRefs } from "vue";
export function useDict(...args: any[]) {
const res: Ref<any> = ref({});
return (() => {
args.forEach(async (dictType: string, index) => {
args.forEach((dictType, index) => {
res.value[dictType] = [];
const dicts = await store.dispatch("getDict", dictType);
const dicts = useDictStore().getDict(dictType);
if (dicts) {
res.value[dictType] = dicts;
} else {
@ -21,10 +21,7 @@ export function useDict(...args: any[]) {
elTagType: p.listClass,
elTagClass: p.cssClass,
}));
store.dispatch("setDict", {
key: dictType,
value: res.value[dictType],
});
useDictStore().setDict(dictType, res.value[dictType]);
});
}
});