溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

TP6+vue-element-admin怎么實(shí)現(xiàn)后臺(tái)登錄驗(yàn)證碼

發(fā)布時(shí)間:2021-12-10 16:39:03 來源:億速云 閱讀:167 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“TP6+vue-element-admin怎么實(shí)現(xiàn)后臺(tái)登錄驗(yàn)證碼”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

tp6+vue-element-admin 制作后臺(tái)登錄驗(yàn)證碼

此處tp6為多應(yīng)用模式

安裝驗(yàn)證碼擴(kuò)展

composer require topthink/think-captcha

在擴(kuò)展里面找到 Captcha.php

->[此處為我修改過后的代碼]

  • 因?yàn)橹笆莝ession驅(qū)動(dòng),但是我項(xiàng)目是前后端分離的,所以要改成cache驅(qū)動(dòng),增加use  Cache,然后將所Session相關(guān)的都改為Cache

  • 有個(gè)要注意的地方  就是  check方法,已經(jīng)在代碼處做了注釋

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkyisu.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
 
namespace think\captcha;
 
use Exception;
use think\Config;
use think\facade\Log;
use think\Response;
use think\Session;
use think\Cache;
 
class Captcha
{
    private $im    = null; // 驗(yàn)證碼圖片實(shí)例
    private $color = null; // 驗(yàn)證碼字體顏色
 
    /**
     * @var Config|null
     */
    private $config = null;
 
    /**
     * @var Session|null
     */
    private $cache = null;
 
    // 驗(yàn)證碼字符集合
    protected $codeSet = '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY';
    // 驗(yàn)證碼過期時(shí)間(s)
    protected $expire = 1800;
    // 使用中文驗(yàn)證碼
    protected $useZh = false;
    // 中文驗(yàn)證碼字符串
    protected $zhSet = '們以我到他會(huì)作時(shí)要?jiǎng)訃a(chǎn)的一是工就年階義發(fā)成部民可出能方進(jìn)在了不和有大這主中人上為來分生對于學(xué)下級地個(gè)用同行面說種過命度革而多子后自社加小機(jī)也經(jīng)力線本電高量長黨得實(shí)家定深法表著水理化爭現(xiàn)所二起政三好十戰(zhàn)無農(nóng)使性前等反體合斗路圖把結(jié)第里正新開論之物從當(dāng)兩些還天資事隊(duì)批點(diǎn)育重其思與間內(nèi)去因件日利相由壓員氣業(yè)代全組數(shù)果期導(dǎo)平各基或月毛然如應(yīng)形想制心樣干都向變關(guān)問比展那它最及外沒看治提五解系林者米群頭意只明四道馬認(rèn)次文通但條較克又公孔領(lǐng)軍流入接席位情運(yùn)器并飛原油放立題質(zhì)指建區(qū)驗(yàn)活眾很教決特此常石強(qiáng)極土少已根共直團(tuán)統(tǒng)式轉(zhuǎn)別造切九你取西持總料連任志觀調(diào)七么山程百報(bào)更見必真保熱委手改管處己將修支識(shí)病象幾先老光專什六型具示復(fù)安帶每東增則完風(fēng)回南廣勞輪科北打積車計(jì)給節(jié)做務(wù)被整聯(lián)步類集號列溫裝即毫知軸研單色堅(jiān)據(jù)速防史拉世設(shè)達(dá)爾場織歷花受求傳口斷況采精金界品判參層止邊清至萬確究書術(shù)狀廠須離再目海交權(quán)且兒青才證低越際八試規(guī)斯近注辦布門鐵需走議縣兵固除般引齒千勝細(xì)影濟(jì)白格效置推空配刀葉率述今選養(yǎng)德話查差半敵始片施響收華覺備名紅續(xù)均藥標(biāo)記難存測士身緊液派準(zhǔn)斤角降維板許破述技消底床田勢端感往神便賀村構(gòu)照容非搞亞磨族火段算適講按值美態(tài)黃易彪服早班麥削信排臺(tái)聲該擊素張密害侯草何樹肥繼右屬市嚴(yán)徑螺檢左頁抗蘇顯苦英快稱壞移約巴材省黑武培著河帝僅針怎植京助升王眼她抓含苗副雜普談圍食射源例致酸舊卻充足短劃劑宣環(huán)落首尺波承粉踐府魚隨考刻靠夠滿夫失包住促枝局菌桿周護(hù)巖師舉曲春元超負(fù)砂封換太模貧減陽揚(yáng)江析畝木言球朝醫(yī)校古呢稻宋聽唯輸滑站另衛(wèi)字鼓剛寫劉微略范供阿塊某功套友限項(xiàng)余倒卷創(chuàng)律雨讓骨遠(yuǎn)幫初皮播優(yōu)占死毒圈偉季訓(xùn)控激找叫云互跟裂糧粒母練塞鋼頂策雙留誤礎(chǔ)吸阻故寸盾晚絲女散焊功株親院冷徹彈錯(cuò)散商視藝滅版烈零室輕血倍缺厘泵察絕富城沖噴壤簡否柱李望盤磁雄似困鞏益洲脫投送奴側(cè)潤蓋揮距觸星松送獲興獨(dú)官混紀(jì)依未突架寬冬章濕偏紋吃執(zhí)閥礦寨責(zé)熟穩(wěn)奪硬價(jià)努翻奇甲預(yù)職評讀背協(xié)損棉侵灰雖矛厚羅泥辟告卵箱掌氧恩愛停曾溶營終綱孟錢待盡俄縮沙退陳討奮械載胞幼哪剝迫旋征槽倒握擔(dān)仍呀鮮吧卡粗介鉆逐弱腳怕鹽末陰豐霧冠丙街萊貝輻腸付吉滲瑞驚頓擠秒懸姆爛森糖圣凹陶詞遲蠶億矩康遵牧遭幅園腔訂香肉弟屋敏恢忘編印蜂急拿擴(kuò)傷飛露核緣游振操央伍域甚迅輝異序免紙夜鄉(xiāng)久隸缸夾念蘭映溝乙嗎儒殺汽磷艱晶插埃燃?xì)g鐵補(bǔ)咱芽永瓦傾陣碳演威附牙芽永瓦斜灌歐獻(xiàn)順豬洋腐請透司危括脈宜笑若尾束壯暴企菜穗楚漢愈綠拖牛份染既秋遍鍛玉夏療尖殖井費(fèi)州訪吹榮銅沿替滾客召旱悟刺腦措貫藏敢令隙爐殼硫煤迎鑄粘探臨薄旬善??v擇禮愿伏殘雷延煙句純漸耕跑澤慢栽魯赤繁境潮橫掉錐希池?cái)〈倭林^托伙哲懷割擺貢呈勁財(cái)儀沉煉麻罪祖息車穿貨銷齊鼠抽畫飼龍庫守筑房歌寒喜哥洗蝕廢納腹乎錄鏡婦惡脂莊擦險(xiǎn)贊鐘搖典柄辯竹谷賣亂虛橋奧伯趕垂途額壁網(wǎng)截野遺靜謀弄掛課鎮(zhèn)妄盛耐援扎慮鍵歸符慶聚繞摩忙舞遇索顧膠羊湖釘仁音跡碎伸燈避泛亡答勇頻皇柳哈揭甘諾概憲濃島襲誰洪謝炮澆斑訊懂靈蛋閉孩釋乳巨徒私銀伊景坦累勻霉杜樂勒隔彎績招紹胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗堿殊崗?fù)谑先袆《押蘸尚睾馇谀て邱v案刊秧緩?fù)挂奂舸ㄑ╂湞O啦臉戶洛孢勃盟買楊宗焦賽旗濾硅炭股坐蒸凝竟陷槍黎救冒暗洞犯筒您宋弧爆謬涂味津臂障褐陸啊健尊豆拔莫抵桑坡縫警挑污冰柬嘴啥飯塑寄趙喊墊丹渡耳刨虎筆稀昆浪薩茶滴淺擁穴覆倫娘噸浸袖珠雌媽紫戲塔錘震歲貌潔剖牢鋒疑霸閃埔猛訴刷狠忽災(zāi)鬧喬唐漏聞沈熔氯荒莖男凡搶像漿旁玻亦忠唱蒙予紛捕鎖尤乘烏智淡允叛畜俘摸銹掃畢璃寶芯爺鑒秘凈蔣鈣肩騰枯拋軌堂拌爸循誘祝勵(lì)肯酒繩窮塘燥泡袋朗喂鋁軟渠顆慣貿(mào)糞綜墻趨彼屆墨礙啟逆卸航衣孫齡嶺騙休借';
    // 使用背景圖片
    protected $useImgBg = false;
    // 驗(yàn)證碼字體大小(px)
    protected $fontSize = 25;
    // 是否畫混淆曲線
    protected $useCurve = true;
    // 是否添加雜點(diǎn)
    protected $useNoise = true;
    // 驗(yàn)證碼圖片高度
    protected $imageH = 0;
    // 驗(yàn)證碼圖片寬度
    protected $imageW = 0;
    // 驗(yàn)證碼位數(shù)
    protected $length = 5;
    // 驗(yàn)證碼字體,不設(shè)置隨機(jī)獲取
    protected $fontttf = '';
    // 背景顏色
    protected $bg = [243, 251, 254];
    //算術(shù)驗(yàn)證碼
    protected $math = false;
 
    /**
     * 架構(gòu)方法 設(shè)置參數(shù)
     * @access public
     * @param Config  $config
     * @param Session $session
     */
    public function __construct(Config $config, Cache $cache)
    {
        $this->config  = $config;
        $this->cache = $cache;
    }
 
    /**
     * 配置驗(yàn)證碼
     * @param string|null $config
     */
    protected function configure(string $config = null): void
    {
        if (is_null($config)) {
            $config = $this->config->get('captcha', []);
        } else {
            $config = $this->config->get('captcha.' . $config, []);
        }
 
        foreach ($config as $key => $val) {
            if (property_exists($this, $key)) {
                $this->{$key} = $val;
            }
        }
    }
 
    /**
     * 創(chuàng)建驗(yàn)證碼
     * @return array
     * @throws Exception
     */
    protected function generate(): array
    {
        $bag = '';
 
        if ($this->math) {
            $this->useZh  = false;
            $this->length = 5;
 
            $x   = random_int(10, 30);
            $y   = random_int(1, 9);
            $bag = "{$x} + {$y} = ";
            $key = $x + $y;
            $key .= '';
        } else {
            if ($this->useZh) {
                $characters = preg_split('/(?<!^)(?!$)/u', $this->zhSet);
            } else {
                $characters = str_split($this->codeSet);
            }
 
            for ($i = 0; $i < $this->length; $i++) {
                $bag .= $characters[rand(0, count($characters) - 1)];
            }
 
            $key = mb_strtolower($bag, 'UTF-8');
        }
 
        $hash = password_hash($key, PASSWORD_BCRYPT, ['cost' => 10]);
 
        $this->cache->set('captcha', [
            'key' => $hash,
        ]);
        Log::info($bag);
        Log::info($hash);
        return [
            'value' => $bag,
            'key'   => $hash,
        ];
    }
 
    /**
     * 驗(yàn)證驗(yàn)證碼是否正確
     * @access public
     * @param string $code 用戶驗(yàn)證碼
     * @return bool 用戶驗(yàn)證碼是否正確
     */
    public function check(string $code): bool
    {
 
        if (!$this->cache->has('captcha')) {
            return false;
        }
 
//        $key = $this->cache->get('captcha.key');
        //改為cache以后,是數(shù)組,不是對象,所以不能這么取值
        $key1 = $this->cache->get('captcha');
        $key = $key1['key'];
        Log::info($key);
        $code = mb_strtolower($code, 'UTF-8');
//        Log::info($code);
 
        $res = password_verify($code, $key);
 
 
        if ($res) {
            $this->cache->delete('captcha');
        }
 
        return $res;
    }
 
    /**
     * 輸出驗(yàn)證碼并把驗(yàn)證碼的值保存的session中
     * @access public
     * @param null|string $config
     * @param bool        $api
     * @return Response
     */
    public function create(string $config = null, bool $api = false): Response
    {
        $this->configure($config);
 
        $generator = $this->generate();
 
        // 圖片寬(px)
        $this->imageW || $this->imageW = $this->length * $this->fontSize * 1.5 + $this->length * $this->fontSize / 2;
        // 圖片高(px)
        $this->imageH || $this->imageH = $this->fontSize * 2.5;
        // 建立一幅 $this->imageW x $this->imageH 的圖像
        $this->im = imagecreate($this->imageW, $this->imageH);
        // 設(shè)置背景
        imagecolorallocate($this->im, $this->bg[0], $this->bg[1], $this->bg[2]);
 
        // 驗(yàn)證碼字體隨機(jī)顏色
        $this->color = imagecolorallocate($this->im, mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150));
 
        // 驗(yàn)證碼使用隨機(jī)字體
        $ttfPath = __DIR__ . '/../assets/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/';
 
        if (empty($this->fontttf)) {
            $dir  = dir($ttfPath);
            $ttfs = [];
            while (false !== ($file = $dir->read())) {
                if ('.' != $file[0] && substr($file, -4) == '.ttf') {
                    $ttfs[] = $file;
                }
            }
            $dir->close();
            $this->fontttf = $ttfs[array_rand($ttfs)];
        }
 
        $fontttf = $ttfPath . $this->fontttf;
 
        if ($this->useImgBg) {
            $this->background();
        }
 
        if ($this->useNoise) {
            // 繪雜點(diǎn)
            $this->writeNoise();
        }
        if ($this->useCurve) {
            // 繪干擾線
            $this->writeCurve();
        }
 
        // 繪驗(yàn)證碼
        $text = $this->useZh ? preg_split('/(?<!^)(?!$)/u', $generator['value']) : str_split($generator['value']); // 驗(yàn)證碼
 
        foreach ($text as $index => $char) {
 
            $x     = $this->fontSize * ($index + 1) * mt_rand(1.2, 1.6) * ($this->math ? 1 : 1.5);
            $y     = $this->fontSize + mt_rand(10, 20);
            $angle = $this->math ? 0 : mt_rand(-40, 40);
 
            imagettftext($this->im, $this->fontSize, $angle, $x, $y, $this->color, $fontttf, $char);
        }
 
        ob_start();
        // 輸出圖像
        imagepng($this->im);
        $content = ob_get_clean();
        imagedestroy($this->im);
 
        return response($content, 200, ['Content-Length' => strlen($content)])->contentType('image/png');
    }
 
    /**
     * 畫一條由兩條連在一起構(gòu)成的隨機(jī)正弦函數(shù)曲線作干擾線(你可以改成更帥的曲線函數(shù))
     *
     *      高中的數(shù)學(xué)公式咋都忘了涅,寫出來
     *        正弦型函數(shù)解析式:y=Asin(ωx+φ)+b
     *      各常數(shù)值對函數(shù)圖像的影響:
     *        A:決定峰值(即縱向拉伸壓縮的倍數(shù))
     *        b:表示波形在Y軸的位置關(guān)系或縱向移動(dòng)距離(上加下減)
     *        φ:決定波形與X軸位置關(guān)系或橫向移動(dòng)距離(左加右減)
     *        ω:決定周期(最小正周期T=2π/∣ω∣)
     *
     */
    protected function writeCurve(): void
    {
        $px = $py = 0;
 
        // 曲線前部分
        $A = mt_rand(1, $this->imageH / 2); // 振幅
        $b = mt_rand(-$this->imageH / 4, $this->imageH / 4); // Y軸方向偏移量
        $f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X軸方向偏移量
        $T = mt_rand($this->imageH, $this->imageW * 2); // 周期
        $w = (2 * M_PI) / $T;
 
        $px1 = 0; // 曲線橫坐標(biāo)起始位置
        $px2 = mt_rand($this->imageW / 2, $this->imageW * 0.8); // 曲線橫坐標(biāo)結(jié)束位置
 
        for ($px = $px1; $px <= $px2; $px = $px + 1) {
            if (0 != $w) {
                $py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
                $i  = (int) ($this->fontSize / 5);
                while ($i > 0) {
                    imagesetpixel($this->im, $px + $i, $py + $i, $this->color); // 這里(while)循環(huán)畫像素點(diǎn)比imagettftext和imagestring用字體大小一次畫出(不用這while循環(huán))性能要好很多
                    $i--;
                }
            }
        }
 
        // 曲線后部分
        $A   = mt_rand(1, $this->imageH / 2); // 振幅
        $f   = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X軸方向偏移量
        $T   = mt_rand($this->imageH, $this->imageW * 2); // 周期
        $w   = (2 * M_PI) / $T;
        $b   = $py - $A * sin($w * $px + $f) - $this->imageH / 2;
        $px1 = $px2;
        $px2 = $this->imageW;
 
        for ($px = $px1; $px <= $px2; $px = $px + 1) {
            if (0 != $w) {
                $py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
                $i  = (int) ($this->fontSize / 5);
                while ($i > 0) {
                    imagesetpixel($this->im, $px + $i, $py + $i, $this->color);
                    $i--;
                }
            }
        }
    }
 
    /**
     * 畫雜點(diǎn)
     * 往圖片上寫不同顏色的字母或數(shù)字
     */
    protected function writeNoise(): void
    {
        $codeSet = '2345678abcdefhijkmnpqrstuvwxyz';
        for ($i = 0; $i < 10; $i++) {
            //雜點(diǎn)顏色
            $noiseColor = imagecolorallocate($this->im, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225));
            for ($j = 0; $j < 5; $j++) {
                // 繪雜點(diǎn)
                imagestring($this->im, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor);
            }
        }
    }
 
    /**
     * 繪制背景圖片
     * 注:如果驗(yàn)證碼輸出圖片比較大,將占用比較多的系統(tǒng)資源
     */
    protected function background(): void
    {
        $path = __DIR__ . '/../assets/bgs/';
        $dir  = dir($path);
 
        $bgs = [];
        while (false !== ($file = $dir->read())) {
            if ('.' != $file[0] && substr($file, -4) == '.jpg') {
                $bgs[] = $path . $file;
            }
        }
        $dir->close();
 
        $gb = $bgs[array_rand($bgs)];
 
        list($width, $height) = @getimagesize($gb);
        // Resample
        $bgImage = @imagecreatefromjpeg($gb);
        @imagecopyresampled($this->im, $bgImage, 0, 0, 0, 0, $this->imageW, $this->imageH, $width, $height);
        @imagedestroy($bgImage);
    }
 
}

vue-elemen-admin

login/index.vue

<template>
  <div>
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" autocomplete="on" label-position="left">
 
      <div>
        <h4>Login Form</h4>
      </div>
 
      <el-form-item prop="username">
        <span>
          <svg-icon icon-class="user" />
        </span>
        <el-input
          ref="username"
          v-model="loginForm.username"
          placeholder="Username"
          name="username"
          type="text"
          tabindex="1"
          autocomplete="on"
        />
      </el-form-item>
 
      <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
        <el-form-item prop="password">
          <span>
            <svg-icon icon-class="password" />
          </span>
          <el-input
            :key="passwordType"
            ref="password"
            v-model="loginForm.password"
            :type="passwordType"
            placeholder="Password"
            name="password"
            tabindex="2"
            autocomplete="on"
            @keyup.native="checkCapslock"
            @blur="capsTooltip = false"
            @keyup.enter.native="handleLogin"
          />
          <span @click="showPwd">
            <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
          </span>
        </el-form-item>
      </el-tooltip>
 
      <el-form-item prop="captcha" style="width:280px">
        <el-input
          ref="captcha"
          v-model="loginForm.captcha"
          placeholder="驗(yàn)證碼"
          name="captcha"
          type="text"
          tabindex="1"
          autocomplete="on"
         >
           </el-input>
      </el-form-item>
      <img :src="imgcode" @click="captchas" >
 
      <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
    </el-form>
 
    <el-dialog title="Or connect with" :visible.sync="showDialog">
      Can not be simulated on local, so please combine you own business simulation! ! !
      <br>
      <br>
      <br>
      <social-sign />
    </el-dialog>
  </div>
</template>
 
<script>
// import {  } from '@/api/user'
 
import { validUsername } from '@/utils/validate'
import SocialSign from './components/SocialSignin'
 
export default {
  name: 'Login',
  components: { SocialSign },
  data() {
    const validateUsername = (rule, value, callback) => {
      if (!validUsername(value)) {
        callback(new Error('Please enter the correct user name'))
      } else {
        callback()
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (value.length < 6) {
        callback(new Error('The password can not be less than 6 digits'))
      } else {
        callback()
      }
    }
    return {
      loginForm: {
        username: 'admin',
        password: '222222',
        captcha:''
      },
      loginRules: {
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
        password: [{ required: true, trigger: 'blur', validator: validatePassword }],
        captcha:     [{ required: true,trigger: 'blur'}]
      },
      passwordType: 'password',
      capsTooltip: false,
      loading: false,
      showDialog: false,
      redirect: undefined,
      otherQuery: {},
      imgcode:''
    }
  },
  watch: {
    $route: {
      handler: function(route) {
        const query = route.query
        if (query) {
          this.redirect = query.redirect
          this.otherQuery = this.getOtherQuery(query)
        }
      },
      immediate: true
    }
  },
  created() {
    this.captchas()
  },
  mounted() {
    if (this.loginForm.username === '') {
      this.$refs.username.focus()
    } else if (this.loginForm.password === '') {
      this.$refs.password.focus()
    }
  },
  destroyed() {
  },
  methods: {
    checkCapslock(e) {
      const { key } = e
      this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
    },
    showPwd() {
      if (this.passwordType === 'password') {
        this.passwordType = ''
      } else {
        this.passwordType = 'password'
      }
      this.$nextTick(() => {
        this.$refs.password.focus()
      })
    },
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          console.log(this.loginForm)
          this.$store.dispatch('user/login', this.loginForm)
            .then(() => {
              this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
              this.loading = false
            })
            .catch(() => {
              this.loading = false
            })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    getOtherQuery(query) {
      return Object.keys(query).reduce((acc, cur) => {
        if (cur !== 'redirect') {
          acc[cur] = query[cur]
        }
        return acc
      }, {})
    },
    captchas(){
     this.imgcode =  adminUrl+'/admin/captcha?'+Date.parse(new Date())
 
    }
  }
}
</script>
 
<style>
/* 修復(fù)input 背景不協(xié)調(diào) 和光標(biāo)變色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
 
$bg:#283443;
$light_gray:#fff;
$cursor: #fff;
 
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
  .login-container .el-input input {
    color: $cursor;
  }
}
 
/* reset element-ui css */
.login-container {
  .el-input {
    display: inline-block;
    height: 47px;
    width: 85%;
 
    input {
      background: transparent;
      border: 0px;
      -webkit-appearance: none;
      border-radius: 0px;
      padding: 12px 5px 12px 15px;
      color: $light_gray;
      height: 47px;
      caret-color: $cursor;
 
      &:-webkit-autofill {
        box-shadow: 0 0 0px 1000px $bg inset !important;
        -webkit-text-fill-color: $cursor !important;
      }
    }
  }
 
  .el-form-item {
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(0, 0, 0, 0.1);
    border-radius: 5px;
    color: #454545;
  }
}
</style>
 
<style scoped>
$bg:#2d3a4b;
$dark_gray:#889aa4;
$light_gray:#eee;
 
.login-container {
  min-height: 100%;
  width: 100%;
  background-color: $bg;
  overflow: hidden;
 
  .login-form {
    position: relative;
    width: 520px;
    max-width: 100%;
    padding: 160px 35px 0;
    margin: 0 auto;
    overflow: hidden;
  }
 
  .tips {
    font-size: 14px;
    color: #fff;
    margin-bottom: 10px;
 
    span {
      &:first-of-type {
        margin-right: 16px;
      }
    }
  }
 
  .svg-container {
    padding: 6px 5px 6px 15px;
    color: $dark_gray;
    vertical-align: middle;
    width: 30px;
    display: inline-block;
  }
 
  .title-container {
    position: relative;
 
    .title {
      font-size: 26px;
      color: $light_gray;
      margin: 0px auto 40px auto;
      text-align: center;
      font-weight: bold;
    }
  }
 
  .show-pwd {
    position: absolute;
    right: 10px;
    top: 7px;
    font-size: 16px;
    color: $dark_gray;
    cursor: pointer;
    user-select: none;
  }
 
  .thirdparty-button {
    position: absolute;
    right: 0;
    bottom: 6px;
  }
 
  @media only screen and (max-width: 470px) {
    .thirdparty-button {
      display: none;
    }
  }
}
.picture{
  // display: flex;
  // flex: 1;
  height: 42px;
  width: 150px;
  float: right;
  margin-top: -65px;
 
}
</style>

store/user.js

const actions = {
  // user login
  login({ commit }, userInfo) {
    const { username, password,captcha } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password ,captcha:captcha.trim()}).then(response => {
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

“TP6+vue-element-admin怎么實(shí)現(xiàn)后臺(tái)登錄驗(yàn)證碼”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI