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

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

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

一、主要思路

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

二、Uniapp主要技术应用

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

javascript 复制代码
const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据

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

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

javascript 复制代码
//文件缓存插件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

javascript 复制代码
// 数据持久化存储
// 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

javascript 复制代码
import filePersistentIO from './filePersistentIO'

Vue.prototype.$filePersistentIO = filePersistentIO

三、实现案例

1、登录方法

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

(1)pages/login.vue

javascript 复制代码
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()
  }
 })
},
javascript 复制代码
  // 登录成功后,处理函数
  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')
    })
}
javascript 复制代码
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,将登录信息存储到缓存。退出登录时清除登录信息。

javascript 复制代码
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根组件读取登录缓存和文件

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

// 成功即跳转到首页
  this.$tab.reLaunch('/pages/index')
 }
},
javascript 复制代码
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')
       }
     }
},
javascript 复制代码
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)*/

  })
},
相关推荐
Marry1.04 分钟前
uniapp背景图用本地图片
前端·uni-app
夏河始溢10 分钟前
一七八、Node.js PM2使用介绍
前端·javascript·node.js·pm2
蜕变菜鸟11 分钟前
uni-app 实现自定义底部导航
uni-app·notepad++
记忆深处的声音11 分钟前
vue2 + Element-ui 二次封装 Table 组件,打造通用业务表格
前端·vue.js·代码规范
陈随易11 分钟前
兔小巢收费引发的论坛调研Node和Deno有感
前端·后端·程序员
熊的猫26 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
速盾cdn33 分钟前
速盾:vue的cdn是干嘛的?
服务器·前端·网络
四喜花露水1 小时前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy1 小时前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
瑶琴AI前端2 小时前
uniapp实现H5和微信小程序获取当前位置(腾讯地图)
微信小程序·小程序·uni-app