使用Pinia代替Vuex进行数据存储

This commit is contained in:
RuoYi
2025-04-23 20:53:28 +08:00
parent fd97380edb
commit 3eca7b1219
15 changed files with 169 additions and 155 deletions

26
App.vue
View File

@@ -1,7 +1,9 @@
<script setup>
import config from './config'
import { getToken } from '@/utils/auth'
import { useConfigStore } from '@/store'
import { getCurrentInstance } from "vue"
import { onLaunch } from '@dcloudio/uni-app'
import { getToken } from '@/utils/auth'
import { getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance()
@@ -10,29 +12,25 @@
})
// 初始化应用
function initApp() {
function initApp() {
// 初始化应用配置
initConfig()
// 检查用户登录状态
//#ifdef H5
checkLogin()
//#endif
}
function initConfig() {
useConfigStore().setConfig(config)
}
function checkLogin() {
if (!getToken()) {
proxy.$tab.reLaunch('/pages/login')
}
}
}
</script>
<script>
import config from './config'
export default {
onLaunch: function() {
this.globalData.config = config
}
}
</script>
<style lang="scss">
@import '@/static/scss/index.scss'

View File

@@ -1,7 +1,7 @@
// 应用全局配置
export default {
baseUrl: 'https://vue.ruoyi.vip/prod-api',
// baseUrl: 'http://localhost:8080',
// baseUrl: 'https://vue.ruoyi.vip/prod-api',
baseUrl: 'http://localhost:8080',
// 应用信息
appInfo: {
// 应用名称

View File

@@ -4,9 +4,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<title></title>
<!--preload-links-->
<!--app-context-->
<title>RuoYi-App</title>
</head>
<body>

View File

@@ -35,7 +35,9 @@
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
"ios" : {
"dSYMs" : false
},
"sdkConfigs" : {}
}
},

View File

@@ -39,12 +39,12 @@
</template>
<script setup>
import { getCodeImg } from '@/api/login'
import store from '@/store'
import { ref, getCurrentInstance } from "vue"
import { getCodeImg } from '@/api/login'
import { useConfigStore, useUserStore } from '@/store'
import { ref, getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance()
const globalConfig = getApp().globalData.config
const globalConfig = useConfigStore().config
const codeUrl = ref("")
// 验证码开关
const captchaEnabled = ref(true)
@@ -101,7 +101,7 @@
// 密码登录
async function pwdLogin() {
store.dispatch('Login', loginForm.value).then(() => {
useUserStore().login(loginForm.value).then(() => {
proxy.$modal.closeLoading()
loginSuccess()
}).catch(() => {
@@ -114,7 +114,7 @@
// 登录成功后,处理函数
function loginSuccess(result) {
// 设置用户信息
store.dispatch('GetInfo').then(res => {
useUserStore().getInfo().then(res => {
proxy.$tab.reLaunch('/pages/index')
})
}

View File

@@ -43,9 +43,11 @@
</view>
</template>
<script setup>
const url = getApp().globalData.config.appInfo.site_url
const version = getApp().globalData.config.appInfo.version
<script setup>
import { useConfigStore } from '@/store'
const url = useConfigStore().config.appInfo.site_url
const version = useConfigStore().config.appInfo.version
</script>
<style lang="scss" scoped>

View File

@@ -38,7 +38,7 @@
<script>
import config from '@/config'
import store from "@/store"
import { useUserStore } from '@/store'
import { uploadAvatar } from "@/api/system/user"
const baseUrl = config.baseUrl
@@ -68,7 +68,7 @@
*/
data() {
return {
imageSrc: store.getters.avatar,
imageSrc: useUserStore().avatar,
isShowImg: false,
// 初始化的宽高
cropperInitW: SCREEN_WIDTH,
@@ -257,7 +257,7 @@
uni.hideLoading()
let data = {name: 'avatarfile', filePath: res.tempFilePath}
uploadAvatar(data).then(response => {
store.commit('SET_AVATAR', baseUrl + response.imgUrl)
useUserStore().SET_AVATAR(baseUrl + response.imgUrl)
uni.showToast({ title: "修改成功", icon: 'success' })
uni.navigateBack()
})

View File

@@ -77,13 +77,12 @@
</template>
<script setup>
import store from '@/store'
import { useUserStore } from '@/store'
import { computed , getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance()
const name = store.state.user.name
const version= getApp().globalData.config.appInfo.version
const avatar = computed(() => store.state.user.avatar)
const name = useUserStore().name
const avatar = computed(() => useUserStore().avatar)
const windowHeight = computed(() => uni.getSystemInfoSync().windowHeight - 50)
function handleToInfo() {

View File

@@ -31,7 +31,7 @@
</template>
<script setup>
import store from '@/store'
import { useUserStore } from '@/store'
import { ref, computed , getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance()
@@ -51,7 +51,7 @@
function handleLogout() {
proxy.$modal.confirm('确定注销并退出系统吗?').then(() => {
store.dispatch('LogOut').then(() => {}).finally(()=>{
useUserStore().logOut().then(() => {}).finally(()=>{
proxy.$tab.reLaunch('/pages/index')
})
})

View File

@@ -1,8 +1,8 @@
import store from '@/store'
import { useUserStore } from '@/store'
function authPermission(permission) {
const all_permission = "*:*:*"
const permissions = store.getters && store.getters.permissions
const permissions = useUserStore().permissions
if (permission && permission.length > 0) {
return permissions.some(v => {
return all_permission === v || v === permission
@@ -14,7 +14,7 @@ function authPermission(permission) {
function authRole(role) {
const super_admin = "admin"
const roles = store.getters && store.getters.roles
const roles = useUserStore().roles
if (role && role.length > 0) {
return roles.some(v => {
return super_admin === v || v === role

View File

@@ -1,8 +0,0 @@
const getters = {
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,11 +1,7 @@
import { createStore } from "vuex"
import user from '@/store/modules/user'
import getters from './getters'
import { createPinia } from 'pinia'
const store = createStore({
modules: {
user
},
getters
})
export default store
const pinia = createPinia()
export default pinia
export { useUserStore } from './modules/user'
export { useConfigStore } from './modules/config'

13
store/modules/config.js Normal file
View File

@@ -0,0 +1,13 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useConfigStore = defineStore('config', () => {
const config = ref()
const setConfig = (val) => {
config.value = val
}
return {
config,
setConfig
}
})

View File

@@ -2,102 +2,116 @@ import config from '@/config'
import storage from '@/utils/storage'
import constant from '@/utils/constant'
import { isHttp, isEmpty } from "@/utils/validate"
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { getInfo, login, logout } from '@/api/login'
import { getToken, removeToken, setToken } from '@/utils/auth'
import defAva from '@/static/images/profile.jpg'
import { ref } from 'vue'
import { defineStore } from 'pinia'
const baseUrl = config.baseUrl
const user = {
state: {
token: getToken(),
name: storage.get(constant.name),
avatar: storage.get(constant.avatar),
roles: storage.get(constant.roles),
permissions: storage.get(constant.permissions)
},
export const useUserStore = defineStore('user', () => {
const token = ref(getToken())
const id = ref(storage.get(constant.id))
const name = ref(storage.get(constant.name))
const avatar = ref(storage.get(constant.avatar))
const roles = ref(storage.get(constant.roles))
const permissions = ref(storage.get(constant.permissions))
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
storage.set(constant.name, name)
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
storage.set(constant.avatar, avatar)
},
SET_ROLES: (state, roles) => {
state.roles = roles
storage.set(constant.roles, roles)
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
storage.set(constant.permissions, permissions)
}
},
actions: {
// 登录
Login({ commit }, userInfo) {
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 => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.user
let avatar = user.avatar || ""
if (!isHttp(avatar)) {
avatar = (isEmpty(avatar)) ? defAva : baseUrl + avatar
}
const username = (isEmpty(user) || isEmpty(user.userName)) ? "" : 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(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
removeToken()
storage.clean()
resolve()
}).catch(error => {
reject(error)
})
})
}
const SET_TOKEN = (val) => {
token.value = val
}
const SET_ID = (val) => {
id.value = val
storage.set(constant.id, val)
}
const SET_NAME = (val) => {
name.value = val
storage.set(constant.name, val)
}
const SET_AVATAR = (val) => {
avatar.value = val
storage.set(constant.avatar, val)
}
const SET_ROLES = (val) => {
roles.value = val
storage.set(constant.roles, val)
}
const SET_PERMISSIONS = (val) => {
permissions.value = val
storage.set(constant.permissions, val)
}
}
export default user
// 登录
const loginAction = (userInfo) => {
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 => {
setToken(res.token)
SET_TOKEN(res.token)
resolve()
}).catch(error => {
reject(error)
})
})
}
// 获取用户信息
const getInfoAction = () => {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.user
let avatar = user.avatar || ""
if (!isHttp(avatar)) {
avatar = (isEmpty(avatar)) ? defAva : baseUrl + avatar
}
const userid = (isEmpty(user) || isEmpty(user.userId)) ? "" : user.userId
const username = (isEmpty(user) || isEmpty(user.userName)) ? "" : user.userName
if (res.roles && res.roles.length > 0) {
SET_ROLES(res.roles)
SET_PERMISSIONS(res.permissions)
} else {
SET_ROLES(['ROLE_DEFAULT'])
}
SET_ID(userid)
SET_NAME(username)
SET_AVATAR(avatar)
resolve(res)
}).catch(error => {
reject(error)
})
})
}
// 退出系统
const logOutAction = () => {
return new Promise((resolve, reject) => {
logout(token.value).then(() => {
SET_TOKEN('')
SET_ROLES([])
SET_PERMISSIONS([])
removeToken()
storage.clean()
resolve()
}).catch(error => {
reject(error)
})
})
}
return {
token,
id,
name,
avatar,
roles,
permissions,
SET_AVATAR,
login: loginAction,
getInfo: getInfoAction,
logOut: logOutAction
}
})

View File

@@ -1,8 +1,8 @@
const constant = {
avatar: 'vuex_avatar',
name: 'vuex_name',
roles: 'vuex_roles',
permissions: 'vuex_permissions'
avatar: 'user_avatar',
name: 'user_name',
roles: 'user_roles',
permissions: 'user_permissions'
}
export default constant