在uniapp项目根目录创建store文件夹,并在其中创建index.js文件
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
isLogin: false,
openId: '',
userInfo: {
nickName: '',
profilePicture: ''
}
},
mutations: {
SET_LOGIN_STATE(state, status) {
state.isLogin = status
uni.setStorageSync('isLogin', status)
},
SET_OPEN_ID(state, openId) {
state.openId = openId
uni.setStorageSync('openId', openId)
},
SET_USER_INFO(state, userInfo) {
state.userInfo = userInfo
uni.setStorageSync('userInfo', userInfo)
},
LOGOUT(state) {
state.isLogin = false
state.openId = ''
state.userInfo = {
nickName: '',
profilePicture: ''
}
uni.removeStorageSync('isLogin')
uni.removeStorageSync('openId')
uni.removeStorageSync('userInfo')
}
},
actions: {
login({ commit }, { openId, userInfo }) {
commit('SET_LOGIN_STATE', true)
commit('SET_OPEN_ID', openId)
commit('SET_USER_INFO', userInfo)
},
logout({ commit }) {
commit('LOGOUT')
},
initState({ commit }) {
const isLogin = uni.getStorageSync('isLogin') || false
const openId = uni.getStorageSync('openId') || ''
const userInfo = uni.getStorageSync('userInfo') || { nickName: '', profilePicture: '' }
commit('SET_LOGIN_STATE', isLogin)
commit('SET_OPEN_ID', openId)
commit('SET_USER_INFO', userInfo)
}
}
})
使用示例
<script setup>
import { computed, watch } from 'vue'
import { useStore } from 'vuex'
import { onShow } from '@dcloudio/uni-app'
const store = useStore()
const isLogin = computed(() => store.state.isLogin)
const openId = computed(() => store.state.openId)
const userInfo = computed(() => store.state.userInfo)
// 页面每次显示检查登录状态
onShow(() => {
if (!isLogin.value) {
uni.redirectTo({ url: '/pages/login/login' })
}
})
// 监听登录状态变化(可选)
watch(isLogin, (newVal) => {
if (!newVal) {
console.log('用户已登出')
}
})
</script>
<template>
<view v-if="isLogin">
<text>欢迎 {{ userInfo.nickName }}</text>
<image :src="userInfo.profilePicture" mode="aspectFill" style="width:100px;height:100px;" />
</view>
<view v-else>
<text>请登录</text>
</view>
</template>
注意:
- 想要响应 Vuex 中的数据变化,使用 computed(() => store.state.xxx)
- 只在初始化时用一次,可以使用 ref(store.state.xxx)(但不响应)
- Vuex 数据是对象,使用字段响应式,拆开写多个 computed,或统一 computed 对象
在其它页面监听登录状态
用 computed + watch
<script setup>
import { computed, watch } from 'vue'
import { useStore } from 'vuex'
import { onShow } from '@dcloudio/uni-app'
const store = useStore()
// 1️⃣ 响应式绑定 Vuex 的 isLogin 状态
const isLogin = computed(() => store.state.isLogin)
// 2️⃣ 页面显示时做登录检查(用于小程序或 app 页面切换时)
onShow(() => {
if (!isLogin.value) {
uni.redirectTo({ url: '/pages/login/login' })
}
})
// 3️⃣ 实时监听 isLogin 的变化(比如登录/登出自动响应)
watch(isLogin, (newVal) => {
if (!newVal) {
console.log('用户已登出,跳转登录页')
uni.redirectTo({ url: '/pages/login/login' })
} else {
console.log('用户已登录')
}
})
</script>
<template>
<view v-if="isLogin">
欢迎回来!
</view>
<view v-else>
<text>请先登录</text>
</view>
</template>
评论区