http://www.reibang.com/p/89b0c29cbc5d
相同瀏覽器只允許登錄一個賬號的需求相信是很多前端小伙伴的面臨過或者將要面臨的問題,看似沒有什么大問題的問題,其實有點(diǎn)東西的践惑。嘶卧。凉袱。。這里介紹一下我嘗試多種辦法之后得出的一個最優(yōu)的解決辦法
1.情況一钟鸵,當(dāng)窗口一登錄了admin賬號涤躲,再去復(fù)制項目里面的地址用窗口二打開
注意這里是項目里面的地址,有點(diǎn)東西的地方在于登錄地址蒙袍,下面再介紹嫩挤,且看:
窗口二打開任意一個項目里面的地址我們要的效果都是可以直接訪問的(各大bat的產(chǎn)品也是這樣的效果,毋庸置疑)以现。那么我們是怎么做到當(dāng)窗口一登錄了之后约啊,其他窗口可以訪問項目里面的任意地址,而當(dāng)沒有窗口登錄恰矩,復(fù)制項目里面的地址不能訪問(安全問題)讓其跳轉(zhuǎn)到登錄頁
上代碼:我們在main.js里面
router.beforeEach((to,from,next) => { //這里是在所有路由跳轉(zhuǎn)之前都會去執(zhí)行以下操作
if(to.path == '/'){ //如果要去的是登錄頁
next() //那么隨意外傅,去就是了
} else { //如果不是
if(localStorage.getItem('isLogin')){ //判斷當(dāng)前瀏覽器的本地存儲里面是不是有已經(jīng)登錄的信息
next() //有的話,ok彬碱,去你想去的地址
} else { //沒有的話奥洼,也就是沒有登錄
next({path:'/'}) //去登錄頁
}
}
})
這里的isLogin是我自己命名在login.vue的登錄的時候存進(jìn)去本地的,當(dāng)然也可以存接口返回的user信息,whatever you like
// 登錄按鈕執(zhí)行登錄的時候估盘,至于為什么存localStorage,不用sessionStore,自行百度其中的區(qū)別骡尽,相信你會明了的
localStorage.setItem("isLogin", 1)
這里要注意,在退出按鈕的時候要執(zhí)行清除登錄狀態(tài)的操作箫踩,否則本地存儲會一直保留(不手動清緩存的情況下)
// 執(zhí)行退出登錄操作的時候執(zhí)行
localStorage.removeItem("isLogin")
到這里應(yīng)該都沒有什么問題谭贪,都是常規(guī)操作 >o<!
情況二,當(dāng)窗口二去到登錄頁面慨削,并且登錄了另一個非admin的賬號
這種情況下套媚,我們是不是要把窗口一的admin的賬號覆蓋掉?是的猿规,可能菜單權(quán)限不一樣宙橱,頁面風(fēng)格都不一樣的情況下,我們怎么去覆蓋這個頁面所展示的信息师郑?
剛開始我的想法是監(jiān)聽瀏覽器的窗口切換宝冕,再次切回窗口一的時候再次點(diǎn)擊頁面上的某處去執(zhí)行接口請求的時候刷新頁面,這是有邏輯上的問題的地梨,因為我們并不能檢測到頁面是否有接口請求,只能接測到是否有路由跳轉(zhuǎn)洁闰,但是頁面上只有一部分比如菜單點(diǎn)擊才有路由跳轉(zhuǎn)万细,所以這個方法是有問題的。(這段廢話是為了更好的表明我的思路emmmm......)
換種思路腰素!要實現(xiàn)這個邏輯,我們就必須要檢測到瀏覽器是否有新窗口執(zhí)行了賬號登錄衡便,也就是監(jiān)測瀏覽器的本地存儲是否有東西洋访,vue的watch監(jiān)測并不能監(jiān)測非vue機(jī)制存放的數(shù)據(jù)(這句話我在上一篇文章中也提過),也就是說watch不能實時監(jiān)測localStorage里面的數(shù)據(jù),而我們或許會想到把localStorage里面的數(shù)據(jù)在保存到vuex里面去達(dá)到實時監(jiān)測的效果总寒,但是摄闸,vuex會在其他窗口登錄的時候被重置,但是這個思路是對的D暾怼!品洛!直接說我怎么實現(xiàn)的:
手動去創(chuàng)建一個js文佳再在里面創(chuàng)建一個全局變量export出去摩桶,把這個全局變量創(chuàng)建在一個單獨(dú)的文件中,然后再去組件里面引用辅斟,這個全局變量是能被watch監(jiān)測
要做到這個全局變量不被其他窗口的登錄給重置掉芦拿,這里就是個小心思了
在登陸組件login.vue里面引入這個全局變量,在登陸按鈕執(zhí)行成功的時候去賦值酵幕,主要看帶注釋的地方
// login.vue先引入
import global from '@/config/common.js'
methods: {
login () {
if (this.user == '') {
this.message.error('密碼不能為空!');
} else {
this.setCookie(this.user)
this.md5(this.password)
}).then(res => {
localStorage.setItem("isLogin", 1)
global.aaa = res.obj.id //這里才是登錄成功的時候去賦值番官,我是創(chuàng)建的 aaa 這個變量為例子
localStorage.setItem('userId', res.obj.id) // 同時也要做的是將這個用戶id存進(jìn)localStorage
this.message.error(err.msg)
})
}
}
}
那我們登錄成功之后會在本地代碼里面保存這個用戶id徘熔,也在瀏覽器的localStorage里面保存了一份,接著讶凉,在main.js里面
import global from '@/config/common.js'
window.addEventListener("visibilitychange",function(){ //這個方法是監(jiān)測瀏覽器窗口發(fā)生變化的時候執(zhí)行
if (document.hidden == false && global.aaa != localStorage.getItem('userId')) {
global.aaa = localStorage.getItem('userId') //只有當(dāng)初始創(chuàng)建的aaa不等于localStorage里面的userId的時候去覆蓋掉這個aaa
}
//不覆蓋的話aaa永遠(yuǎn)都是我們設(shè)的初始值
});
最后山孔,我們在app.vue里面去監(jiān)聽這個全局變量的變化
watch: {
'global.aaa' : 'refresh'
},
methods: {
refresh () {
//執(zhí)行刷新操作,這里我沒有寫this.nextTick(() => {
this.hackReset = true
})
}
}
好了,在第二個窗口登錄另一個賬號坛吁,返回第一個窗口的時候拨脉,改窗口登了的賬號被擠掉,整個頁面同步到第二個窗口所登錄的賬號信息女坑,這個效果實現(xiàn)了!@途啊碉就!代碼倒是沒有什么很高深的要寫,只是思路很重要筋量,有點(diǎn)曲折,實現(xiàn)完功能發(fā)現(xiàn)桨武,頭發(fā)又掉了好幾根。凉蜂。性誉。。纫雁。倾哺。
<每次寫東西過程中感覺都寫很多廢話,但是這些廢話不寫吧闲勺,又怕表達(dá)不清楚扣猫,更怕一段時間之后自己看自己的文章都看不懂翘地,允悲!>
作者:蝸牛先笙
鏈接:http://www.reibang.com/p/89b0c29cbc5d
來源:簡書
著作權(quán)歸作者所有昧穿。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)橙喘,非商業(yè)轉(zhuǎn)載請注明出處时鸵。