electron 仿製QQ登陸界面

首先來看看qq的登陸界面:
圖片描述css

準備開發

製做一個窗口先

主進程代碼:

import {BrowserWindow, webContents, app, ipcMain} from 'electron'

LoginWindow();    //暫時調用

ipcMain.on('quitApp', () => {
    app.quit();
});

function LoginWindow() {
    const loginURL = process.env.NODE_ENV === 'development' ? `http://localhost:9080/#/login` : `file://${__dirname}/index.html/#/login`;
    const loginWindow = new BrowserWindow({
        width: 430,
        height: 328,
        alwaysOnTop: true,
        modal: true,
        frame: false,
        darkTheme: true,
        resizable: false,
        minimizable: false,
        maximizable: false,
        transparent: true,
        webPreferences: {
            devTools: false,
        }
    });


    loginWindow.setMenu(null);
    loginWindow.loadURL(loginURL);
}

界面基本佈局

咱們先大概作一個這樣的界面
圖片描述html

頁面代碼:

<template>
    <div class="mainWindow">
        <header class="header"></header>
        <main>
            <div class="bg"></div>
            <div class="body"></div>
        </main>
        <footer class="footer"></footer>
    </div>
</template>

<script>
    import '@/assets/css/login.css'

    export default {
      
    }
</script>

樣式代碼:

/**
取消所有的外邊距和內邊距
 */
* {
    padding: 0;
    margin: 0;
}

/*設置窗口的樣式*/
.mainWindow {
    cursor: pointer;    /*設置手型*/
    border: 1px solid red;  /*加一個邊框 調試樣式 最後要刪除或者更改**/
    width: 428px;   /*設置寬度  必需要和主進程中設置的同樣 不能大於主進程中設置的寬度 不然會出現滾動條*/
    height: 326px;  /*設置高度  必需要和主進程中設置的同樣 不能大於主進程中設置的高度 不然會出現滾動條*/
    position: relative; /*設置爲相對定位*/
    border-radius: 4px; /*設置圓角*/
}

/**
header的樣式 header中只會有一個關閉按鈕 處於右上角
 */
.mainWindow header.header {
    position: absolute; /*設置絕對定位 由於背景在他下面*/
    height: 30px;   /*設置高度*/
    background: rgba(0, 0, 0, 0.5); /*暫時設置的 後面要刪除或者更改*/
    border-radius: 4px 4px 0 0; /*給header的左上角 右上角設置圓角 否則會出現很尷尬的頁面*/
    width: 428px;   /* 由於設置了絕對定位 設置寬度*/
}

/**
背景
 */
.mainWindow main .bg {
    height: 124px;  /*設置高度*/
    width: 428px;   /*設置寬度 也能夠不用設置 由於這個元素沒有設置絕對定位 因此默認就是100%*/
    border-radius: 4px 4px 0 0; /*給左上角 右上角設置圓角 否則會出現很尷尬的頁面 這裏和header重合在一塊兒了*/
    background: blue;  /*暫時設置的 後面要刪除或者更改*/
}

/**
放置表單的元素
 */
.mainWindow main .body {
    width: 428px;  /*設置寬度 也能夠不用設置 由於這個元素沒有設置絕對定位 因此默認就是100%*/
    height: 172px;  /*設置高度 這裏的高度是 主窗口(326) - footer(30) - 背景(124) 由於header設置了絕對定位 因此不用關 */
    background: green;  /*暫時設置的 後面要刪除或者更改*/
}

.mainWindow footer.footer {
    position: absolute; /* 設置絕對定位 要讓他處於窗口的最底部*/
    height: 30px; /*設置高度 */
    background: red;  /*暫時設置的 後面要刪除或者更改*/
    bottom: 0;  /*讓footer處於底部*/
    width: 428px; /* 由於設置了絕對定位 設置寬度*/
}

窗口拖動

注意 不要使用內置的拖動 咱們要本身實現!
在頁面中加入如下代碼就能夠實現拖動了!vue

data() {
            return {
                windowX: 0,
                windowY: 0,
            }
        },
        mounted() {
            let win = this.$electron.remote.getCurrentWindow();

            document.addEventListener('mousedown', function (e) {
                this.windowX = e.x;
                this.windowY = e.y;
                document.addEventListener('mousemove', moveEvent);
            });

            document.addEventListener('mouseup', function () {
                this.windowX = 0;
                this.windowY = 0;
                document.removeEventListener('mousemove', moveEvent)
            });

            function moveEvent(e) {

                win.setPosition(e.screenX - this.windowX, e.screenY - this.windowY)
            }
        }

設置背景圖

將css裏面的 .bg修改爲:git

.mainWindow main .bg {
    height: 124px;  /*設置高度*/
    width: 428px;   /*設置寬度 也能夠不用設置 由於這個元素沒有設置絕對定位 因此默認就是100%*/
    border-radius: 4px 4px 0 0; /*給左上角 右上角設置圓角 否則會出現很尷尬的頁面 這裏和header重合在一塊兒了*/
    background: url("../images/login-back.gif") 10px;
    background-size: 100%;
}

完成以後效果如以下:github

圖片描述

製做頂部

頂部的logo和最小化就不作了 只作一個關閉的按鈕
去阿里巴巴圖標庫下載字體文件以後放到assets/fonts目錄中
在頁面中加入:web

import '@/assets/fonts/iconfont.css'

header代碼:vuex

<header class="header">
            <span class="iconfont icon-guanbi1"></span>
 </header>

css文件
注意 在css .mainWindow header.header 添加
因爲我背景圖的關係 按鈕可能不太明顯 這問題不大 你們能夠本身換一個圖!app

background: rgba(255, 255, 255, 0.2); /*暫時設置的 後面要刪除或者更改*/
text-align: right;
.mainWindow header.header span{
    display: inline-block;
    height: 30px;
    width:30px;
    text-align: center;
    line-height: 30px;
    color:#E4393c;
}
.mainWindow header.header span:hover{
    background-color: rgba(255,255,255,0.6);
}

製做表單頁

表單界面代碼

建立一個子組件 login.vue
寫入以下代碼:electron

<template>
    <div class="form">
        <form>
            <div class="form_item"><i class="iconfont icon-1zhanghu"></i><input type="text"></div>
            <div class="form_item"><i class="iconfont icon-mima1"></i><input type="password"></div>
        </form>
        <div class="buttons">
            <button>登陸</button>
        </div>
    </div>
</template>

<script>
    export default {
        name: "login"
    }
</script>

表單頁css

須要將 .mainWindow main .body 的背景顏色調成#FFFFFF佈局

.form form{
    padding:10px 90px 0 90px;
}
.form_item{
    height: 40px;
    position: relative;
}
.form_item i.iconfont{
    position: absolute;
    top:5px;
}
.form_item input{
    outline: none;
    border:none;
    padding-left: 20px;
    font-size: 16px;
    width: 230px;
    height: 30px;
    border-bottom: 1px solid #CCC;
}
.buttons{
    text-align: center;
}
.buttons button{
    background-color: #CF000E;
    border: none;
    width: 250px;
    color: #FFFFFF;
    height: 35px;
    cursor: pointer;
    font-size: 14px;
    border-radius: 4px;
    outline: none;
}

效果

最後看到是這樣的
圖片描述

複選框美化

組件代碼

<div class="login_options">
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">自動登陸</i></label>
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">記住密碼</i></label>
                <i class="text">忘記密碼</i>
</div>

css代碼

.login_options{
    margin-bottom: 10px;
    margin-top: 5px;
}
.login_options .option_item {
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-right: 5px;
    position: relative;
    border: 1px solid orange;
    vertical-align: middle;
    cursor: pointer;
    top: -2px;
}

.login_options .option_item input {
    opacity: 0;
}
.login_options  i.text{
    display: inline-block;
    margin-right: 14px;
    font-size: 13px;
    font-style: normal;
}

.login_options .option_item span.checked {
    position: absolute;
    top: -4px;
    right: -3px;
    font-weight: bold;
    display: inline-block;
    width: 20px;
    height: 20px;
    cursor: pointer;
}

.option_item span.checked img {
    width: 100%;
    height: 100%;
}

input[type="checkbox"] + span {
    opacity: 0;
}

input[type="checkbox"]:checked + span {
    opacity: 1;
}

效果

圖片描述圖片描述

註冊頁面

咱們改進一點 由於qq的註冊是一個鏈接到web頁面去申請qq號碼的 不過我作的是點擊註冊將界面切換到註冊界面,只不過是
在寫註冊界面代碼以前先將父組件種的login註釋掉備用 (別刪除哦) 在父組件中引入Register組件
註冊的邏輯是這樣的 在註冊界面輸入手機號和圖形驗證碼 獲取到短信驗證碼輸入以後跳轉到下一步輸入密碼
若是將所有的邏輯寫到一個組件中會致使太長 雖然有辦法解決 可是以後使用動畫就很難看了!

界面代碼

<template>
    <div class="form">
        <form>
            <div class="form_item"><i class="iconfont icon-phone_icon"></i><input type="text"></div>
            <div class="form_item">
                <i class="iconfont icon-yanzhengma2"></i>
                <input type="password">
                <div class="captcha">
                    <img src="@/assets/images/captcha.png" alt="">
                </div>
            </div>
            <div class="form_item">
                <i class="iconfont icon-yanzhengma5"></i>
                <input type="password">
                <div class="send_sms_captcha"><button>獲取短信驗證碼</button></div>
            </div>
        </form>
        <div class="buttons">
            <button>下一步</button>
        </div>
    </div>
</template>

<script>
    export default {
        name: "register"
    }
</script>

界面Css代碼

.captcha {
    position: absolute;
    width: 120px;
    height: 30px;
    top: -2px;
    right: 0;
}

.captcha img {
    width: 100%;
    height: 100%;
}

.send_sms_captcha {
    position: absolute;
    top: -2px;
    right: 0;
}
.send_sms_captcha  button{
    width:120px;
    height: 30px;
    border:none;
    outline: none;
    cursor: pointer;
    border-radius: 4px;
}

父組件代碼

部分代碼:

<main>
        <div class="bg"></div>
         <div class="body">
                <!--<Login></Login>-->
                <Register></Register>
            </div>
        </main>

效果

圖片描述

註冊步驟2

界面代碼

<template>
    <div class="form">
        <form>
            <div class="form_item"><i class="iconfont icon-zaicishurumima"></i><input type="text"></div>
            <div class="form_item"><i class="iconfont icon-mima1"></i><input type="password"></div>
            <div class="login_options" style="text-align: center">
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">自動登陸</i></label>
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">記住密碼</i></label>
            </div>
        </form>
        <div class="buttons">
            <button>登陸</button>
        </div>
    </div>
</template>

<script>
    export default {
        name: "steps2"
    }
</script>

展現

圖片描述

footer代碼

jie簡介

在上面中footer裏面顯示了註冊帳號
其實這只是暫時的方案 爲了方便截圖
首先來分析一下 在登陸頁面的時候在底部顯示註冊帳號 在註冊第一步的時候在底部左側顯示已經帳號,在第二步驟的時候顯示返回上一步
咱們有不少辦法在子組件通知父組件去顯示不一樣的文字
做者給出兩個方案:
1: 經過子組件給父組件傳值
2: 使用vuex
3: 將footer拆分到各個組件中
咱們代碼中使用拆分就好了 比較簡單點
將父組件的footer刪除
往組件login.vue steps1.vue steps2.vue 組件中加入footer

login.vue:

<template>
    <div class="form">
        <form>
            <div class="form_item"><i class="iconfont icon-1zhanghu"></i><input type="text"></div>
            <div class="form_item"><i class="iconfont icon-mima1"></i><input type="password"></div>
            <div class="login_options">
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">自動登陸</i></label>
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">記住密碼</i></label>
                <i class="text">忘記密碼</i>
            </div>
        </form>
        <div class="buttons">
            <button>登陸</button>
        </div>
        <footer class="footer">
            <span @click="toggleWindow">註冊帳號</span>
        </footer>
    </div>
</template>

<script>
    export default {
        name: "login",
        methods:{
            toggleWindow(){
                this.$store.dispatch('toggleLogin');
            }
        }
    }
</script>

steps1.vue

<template>
    <div class="form">
        <form>
            <div class="form_item"><i class="iconfont icon-phone_icon"></i><input type="text"></div>
            <div class="form_item">
                <i class="iconfont icon-yanzhengma2"></i>
                <input type="password">
                <div class="captcha">
                    <img src="@/assets/images/captcha.png" alt="">
                </div>
            </div>
            <div class="form_item">
                <i class="iconfont icon-yanzhengma5"></i>
                <input type="password">
                <div class="send_sms_captcha"><button>獲取短信驗證碼</button></div>
            </div>
        </form>
        <div class="buttons">
            <button @click="toggleSteps">下一步</button>
        </div>
        <footer class="footer">
            <span @click="toggleWindow">已有帳號</span>
        </footer>
    </div>
</template>

<script>
    export default {
        name: "steps1",
        methods:{
            toggleWindow(){
                this.$store.dispatch('toggleLogin');
            },
            toggleSteps(){
                this.$store.dispatch('toggleSteps');
            },
        }
    }
</script>

steps2.vue

<template>
    <div class="form">
        <form>
            <div class="form_item"><i class="iconfont icon-zaicishurumima"></i><input type="text"></div>
            <div class="form_item"><i class="iconfont icon-mima1"></i><input type="password"></div>
            <div class="login_options" style="text-align: center">
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">當即登陸</i></label>
                <label><div class="option_item"><input type="checkbox"><span class="checked"><img src="@/assets/images/checked.png" alt=""></span></div><i class="text">記住密碼</i></label>
            </div>
        </form>
        <div class="buttons">
            <button>註冊</button>
        </div>
        <footer class="footer">
            <span @click="toggleSteps">返回上一步</span>
        </footer>
    </div>
</template>

<script>
    export default {
        name: "steps2",
        methods:{
            toggleSteps(){
                this.$store.dispatch('toggleSteps');
            },
        }
    }
</script>

vuex 代碼

const state = {
    steps: true,
    login: true,
};

const actions = {
    toggleSteps: function ({state, commit}) {
        // state.steps = true;
        state.steps = !state.steps;
    },

    toggleLogin({state, commit}){
        state.login = !state.login;
    }
};

export default ({
    state,
    actions
});

效果展現

圖片描述

添加動畫效果

上面這些完成以後有點單調 尤爲是切換的時候 咱們能夠用到 animateCss
animateCss 下載地址:https://daneden.github.io/ani...

子組件加入:

import '@/assets/css/animate.css'

以後咱們在代碼中加入效果就好了
將父組件改爲:

<main>
            <div class="bg"></div>
                <transition
                        :duration="500"
                        :enter-active-class="'animated ' + (login ?  'bounceInRight' : 'bounceInLeft')"
                        :leave-active-class="'animated ' + (login ? 'bounceOutLeft' : 'bounceOutRight')"
                >
                <Login v-if="login === true" key="login"></Login>
                <Register v-else key="register"></Register>
                </transition>
        </main>

子組件 register.vue改爲:

<transition
                :duration="500"
                :enter-active-class="'animated ' + (steps ?  'bounceInRight' : 'bounceInLeft')"
                :leave-active-class="'animated ' + (steps ? 'bounceOutLeft' : 'bounceOutRight')"
        >
        <Steps1 v-if="steps === true" key="steps"></Steps1>
        <Steps2 v-else key="steps"></Steps2>
        </transition>

修改下css 由於要使用動畫就要將main定位才能用
加入:

.mainWindow main {
    position: absolute;
}

效果展現:
圖片描述
到這裏就差很少了 代碼太多無法一一發布上來 若是有須要的能夠去github下載或者加QQ羣 814270669
github地址:https://github.com/lihaotian0...
碼雲地址: https://gitee.com/leehaotian/...

個人github帳號出了問題 一直登陸不上去 因此就先發布到碼雲了

相關文章
相關標籤/搜索