基于uniapp的登录状态保持(APP免登录)

基于uniapp的登录状态保持(APP免登录)

           本文介绍了uniapp的登录状态保持(APP免登录)实现方法。在rouyi-uniapp框架开发中,解决用户退出软件/关闭应用/更新安装包后,再打开进入应用需要重新登录,不符合用户使用习惯。本文介绍了如何通过将用户登录信息存储到缓存和文件中,判断用户登录状态直接进入应用。用户登录信息用必要存储到文件中,解决安装更新包更新后用户私有应用缓存被删除。

一、主要思路

  1. 改造登录方法,登录成功后,留存登录状态和登录信息、token等到缓存和本地txt文件中。(安装更新包更新后用户私有应用缓存被删除, 存储到文件中可解决问题)
  2. App.vue为公共组件,每次打开应用或者任意页面都会执行方法。在该文件中写入读取缓存和本地txt文件的方法,如果留存用户登录信息,则自动执行登录方法并跳转到首页。如果缓存和文件里都没有用户登录信息,则跳转到登录页。

二、Uniapp主要技术应用

1、uniapp本地缓存(非持久化)

const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据

uni.setStorage({   key: 'userInfo',   data: user,});//设置本地存储数据

2、Uniapp文件缓存(持久化)

//文件缓存插件filePersistentIO读取文件

this.$filePersistentIO.read('JTG_USR_TOKEN_INFO.txt').then(res => {
  loginInfoFromFile = res
  return loginInfoFromFile

  /*          console.log('loginInfoFromFile   res  ======================>')
            console.log(JSON.stringify(res))
            console.log(loginInfoFromFile)*/

})



//文件缓存插件filePersistentIO写入文件

this.$filePersistentIO.storage('JTG_USR_INFO.txt', loginInfo)

3、文件缓存插件

plugins/filePersistentIO.js

// 数据持久化存储
// let addr = "file://storage/emulated/0/京唐港app/";
// let addr = "file:///storage/emulated/0/";
let addr = "JTGUser/Info/";  // 手机存储的文件位置

export default {
    storage(className, data) {
        plus.io.requestFileSystem(
            // plus.io.PRIVATE_DOC, // 程序私有文档目录常量
            // plus.io.PUBLIC_DOWNLOADS, // 程序私有文档目录常量
         plus.io.PUBLIC_DOCUMENTS,
            fs => {
                // 创建或打开文件, fs.root是根目录操作对象,直接fs表示当前操作对象
                fs.root.getFile(
                    addr + className,
                    {create: true},// 文件不存在则创建
                    fileEntry => {
                        // 文件在手机中的路径
                        fileEntry.createWriter(writer => {
                            // 写入文件成功完成的回调函数
                            writer.onwrite = e => {
                                //console.log('写入成功');
                            };
                            // 向文件中写入数据
                            writer.write(
                                JSON.stringify(data)
                            );
                            // 写入完成回调
                            writer.onwriteend = function(res) {
                                console.log('写入文件成功', res.target.fileName);
                            };
                            // 写入错误回调
                            writer.onerror = function(err) {
                                console.error('写入文件失败', err);
                            };
                        });
                    },
                    e => {
                        console.log('getFile failed: ', e);
                    }
                );
            },
            e => {
                console.log(e.message);
            }
        );
    },
    read(className) {
        let that = this;
        return new Promise((resolve, reject) => {
            plus.io.requestFileSystem(
                // plus.io.PRIVATE_DOC,
                // plus.io.PUBLIC_DOWNLOADS,
            plus.io.PUBLIC_DOCUMENTS,

                fs => {
                    fs.root.getFile(
                        addr + className,
                        {create: false},
                        fileEntry => {
                            fileEntry.file(function(file) {
                                console.log('文件大小:' + file.size + '-- 文件名:' + file.name);
                                //创建读取文件对象
                                let fileReader = new plus.io.FileReader();
                                //以文本格式读取文件数据内容
                                fileReader.readAsText(file, 'utf-8');
                                //文件读取操作完成时的回调函数
                                fileReader.onloadend = (evt) => {
                           console.log(evt.target.result)
                           console.log('evt.target.result')
                                    console.log(JSON.parse(evt.target.result),
                                        'JSON.parse(evt.target.result)')
                                    resolve(JSON.parse(evt.target.result))
                                    // sURL = JSON.parse(evt.target.result).URL;
                                }

                                // fileReader.onloadend = function(evt) {
                                //     resolve(evt.target.result)
                                // };
                            });
                        },
                        e => {
                            reject(e);
                        }
                    );
                },
                e => {
                    reject(e);
                    console.log(e.message);
                }
            );
        })
    }
}

3、插件引入

plugins/index.js

import filePersistentIO from './filePersistentIO'

Vue.prototype.$filePersistentIO = filePersistentIO

三、实现案例

1、登录方法

登录信息持久化存储和缓存

(1)pages/login.vue

import {mapMutations}from 'vuex';

...mapMutations(['login']),



// 密码登录
async pwdLogin() {
 this.$store.dispatch('Login', this.loginForm).then(() => {
  this.$modal.closeLoading()
  //将登陆成功后的账号/密码放入到缓存
  let loginInfo = {
   username: this.loginForm.username,
   password: this.loginForm.password
  }
  uni.setStorage({
   key: 'loginInfo',
   data: loginInfo,
  });
       /** 登录信息持久化存储  */
       // 登录成功后将用户名密码存储到文件【安装包更新后-用户名密码自动填充,但不免登录】
       this.$filePersistentIO.storage('JTG_USR_INFO.txt',loginInfo)
  this.loginSuccess()
 }).catch(() => {
  if (this.captchaEnabled) {
   this.getCode()
  }
 })
},

 

  // 登录成功后,处理函数
  loginSuccess(result) {    
    // 设置用户信息
    this.$store.dispatch('GetInfo').then(res => {
 let userInfo = {
  userId: res.user.userName,
  token: uni.getStorageSync("token"),
  phone: res.user.phonenumber,
  userName: res.user.userName,
  jurisdiction: res.user.roleS,
 }   
 console.log("state"+uni.getStorageSync("state"))
 console.log("userinfo"+userInfo)
 debugger
 this.login(userInfo)  
      this.$tab.reLaunch('/pages/index')
    })
}
getLoginInfoFromFile(){
  /** 持久化存储数据读取 */
  let loginInfoFromFile = null
  this.$filePersistentIO.read('JTG_USR_INFO.txt').then(res => {
    loginInfoFromFile = res
  if (this.loginForm.username != '' && (loginInfoFromFile != "" && loginInfoFromFile.username == '' && loginInfoFromFile.password == '')) {
      this.loginForm.username = loginInfoFromFile.username
      this.loginForm.password = loginInfoFromFile.password
    }

    /*          console.log('loginInfoFromFile   res  ======================>')
              console.log(JSON.stringify(res))
              console.log(loginInfoFromFile)*/

  })
},

  (2)store/index.js

Mutation触发此处的login,将登录信息存储到缓存。退出登录时清除登录信息。

import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/store/modules/user'
import businessGlobeVariable from '@/store/modules/businessGlobeVariable'
import getters from './getters'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    user,
    businessGlobeVariable
  },
     state: {
      hasLogin:false,        //用户是否登录
      userInfo:{}             //用户数据
   },
      mutations: {
         // 登录
         login(state,user){
         //登录状态为已登录
            state.hasLogin = true
            state.userInfo = user
            //储存用户数据到本地
            uni.setStorage({
               key: 'userInfo',
               data: user,
            });
            console.log('登陆成功')
            console.log(state.hasLogin,state.userInfo)
         },

         // 退出登录
         logout(state,user){
            //登录状态为未登录
            state.hasLogin = false
            state.userInfo = {}
            //删除本地储存
            uni.removeSavedFile({
               key: 'userInfo',
            })
            console.log('退出登录')
            console.log(state.hasLogin,state.userInfo)
         }
      },
         actions: {

         },
  getters
})

export default store

2、App.vue根组件读取登录缓存和文件

onLaunch: function() {
// 加入如下代码
 const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据
 
 //判断本地缓存是否存在数据
 if (userInfo != "") {
  //传到vuex里面储存起来,并改变登录状态
  this.login(userInfo)

// 成功即跳转到首页
  this.$tab.reLaunch('/pages/index')
 }
},

checkLogin() {
     //debugger
     console.log('getToken()=>'+getToken())
 if (!getToken()) {
  this.$tab.reLaunch('/pages/login')
 }else{
       const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据
       const userInfo1 = this.getLoginTokenInfoFromFile(); //同步获取本地数据(更新安装包后,缓存删除,从文件读取)

       //判断本地缓存是否存在数据
       if (userInfo != "") {
         //传到vuex里面储存起来,并改变登录状态
         this.login(userInfo)
         this.$tab.reLaunch('/pages/index')
       }else if (userInfo1 != "") {
         //传到vuex里面储存起来,并改变登录状态
         this.login(userInfo1)
         this.$tab.reLaunch('/pages/index')
       }
     }
},
getLoginTokenInfoFromFile(){
  /** 持久化存储数据读取 (用户名及token自动登录)*/
  let loginInfoFromFile = null
  this.$filePersistentIO.read('JTG_USR_TOKEN_INFO.txt').then(res => {
    loginInfoFromFile = res
    return loginInfoFromFile
    /*          console.log('loginInfoFromFile   res  ======================>')
              console.log(JSON.stringify(res))
              console.log(loginInfoFromFile)*/

  })
},

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
uniapp 是一款基于 Vue.js 的跨平台应用框架,支持快速构建原生体验的移动应用、小程序及微信公众号等。在 uniapp 开发过程中,状态栏是位于应用顶部的一个区域,通常用于显示系统通知、时间、电池电量等信息,并且可以自定义背景色。 **uniapp 中的状态栏的主要功能和配置包括以下几个方面:** ### 1. 显示内容 - **通知信息**:通常在设备处于待机模式或充电时显示通知。 - **系统图标**:如时间、电池电量指示器等。 - **自定义背景颜色**:通过样式设置调整状态栏的颜色,使其与应用程序的主题相匹配。 ### 2. 配置方式 在 uniapp 中,你可以通过配置文件 `.vue` 或 `.json` 文件来调整状态栏的外观和功能: #### 使用 `App.vue` 在 App.vue 文件中,你可以利用 `style` 属性来自定义状态栏背景颜色: ```html <template> <view class="page"> <!-- 页面组件 --> </view> </template> <style> .page { background-color: #fff; /* 设置页面背景颜色 */ } /* 自定义状态栏颜色 */ #app .uni-page-bar .uni-header { color: #000; } #app .uni-page-bar .uni-header { background-color: #F7F8FA; } </style> ``` #### 使用 `uni-app.json` 在项目根目录下的 `uni-app.json` 文件里,你可以直接指定状态栏的样式属性: ```json { "pages": [ "pages/index/index" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#f4511e", "navigationBarTitleText": "uni-app", "navigationBarTextStyle": "white" } } ``` 上述配置中,“window”部分包含了对窗口级别的样式控制,例如改变导航栏的背景颜色、标题文字的颜色和样式等。其中,状态栏背景颜色默认由操作系统决定,但在某些情况下需要额外调整,可以在更详细的样式层面上进行定制。 ### 3. 关于状态栏的其他注意事项: - **兼容性**:不同平台(Android、iOS)以及不同版本的操作系统对于状态栏的支持程度存在差异,因此在开发时需要注意兼容性和性能优化。 - **响应式设计**:确保状态栏的处理不影响应用的整体布局和用户体验。 ### 相关问题: 1. 如何在 uniapp 应用中自定义状态栏的背景颜色? 2. uniapp 中如何处理状态栏与导航栏之间的位置关系? 3. uniapp 对于状态栏的适配策略是什么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值