项目背景:vue2
业务需求:用Vue+Element 写一个前端框架
今日主线任务:完成静态登陆页面
项目地址:
https://gitee.com/whwbs/my_project.git
准备工作
1.全局引入 Element UI
上一篇文章安装了Element 现在全局引入 在项目文件 my_project/src/main.js 加入以下代码:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
2.找一个好看的登陆页原型图
登陆首页排版参照d2-admin 你也可以自行选择,其中核心的其实都是登陆机制问题,至于披得是什么皮肤,刚开始可以不做太高要求。
3.新建首页文件
新建首页文件夹及文件 my_project/src/login/index.vue 这里需要提一下 每个项目从无到有,文件结构会变得十分复杂,所以从开始就规划好文件结构,不然项目后期会十分头疼,刚入门的童鞋直接参考d2-admin 的项目结构,等你项目经历多了,不用查文档就知道某些代码会写在哪个文件中。D2Admin | D2 Open Sourcehttps://d2.pubhttps://d2.pub/zh/doc/d2-admin/#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84
5.修改标准项目文件
修改my_project/src/App.vue ,将index.vue作为子组件引入App.vue 代码块中1.2.3.4步骤 分别引入 声明和使用。
<template>
<div id="app">
<!-- 3.登陆页 -->
<HomePage />
</div>
</template>
<script>
import HomePage from './login/index.vue' // 1.引入登陆页
export default {
name: 'App',
components: {
HomePage // 2.登陆组件
}
}
</script>
<style>
// 4.修改下css
#app {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
}
</style>
my_project/src/login/index.vue
现在在浏览器中刷新页面,观察效果 如果可以显示 登陆页 字样证明页面修改成功。
4.登陆页排版分解
背景(包括背景色和时钟效果)、顶部标语、登录框、底部版权信息等
现在开始写代码,先通过css勾勒三块主区域
<!--
* @Description: 登陆页面
* @Author: Walis
* @Date: 2022-11-04 13:00:48
* @LastEditors: Walis
* @LastEditTime: 2022-11-04 16:26:56
-->
<template>
<div class="container">
<!-- 提示信息 -->
<div class="tips">{{tipsList[tipsIndex]}}</div>
<!-- 登录框 -->
<div class="login_box">
<el-card class="login_form">
登陆
</el-card>
</div>
<!-- 底部版权信息 -->
<div class="copyright">copyright@一个总在代码给自己下毒的程序猿</div>
</div>
</template>
<script>
export default {
data () {
return {
tipsIndex: 0, // 随机提示信息索引
tipsList: [ // 随机提示信息数组
'一个好的程序员是那种过单行线马路都要往两边看的人。(Doug Linder)',
'程序有问题时不要担心。如果所有东西都没问题,你就失业了。(软件工程的Mosher定律)',
'程序员的麻烦在于,你无法弄清他在捣腾什么,当你最终弄明白时,也许已经晚了。(超级计算机之父Seymour Cray) ',
'程序员最讨厌的两件事:写文档写注释,别人不写文档别人不写注释'
],
}
},
methods: {
},
mounted () {
// 初始化提示信息
this.tipsIndex = Math.floor((Math.random() * this.tipsList.length))
}
}
</script>
<style scoped>
.container {
background-color: #f0f2f5;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.tips {
top: 20px;
position: absolute;
}
.login_box {
top: 30%;
position: absolute;
}
.login_form {
height: 400px;
width: 350px;
}
.copyright {
bottom: 20px;
position: absolute;
}
</style>
到这里之后,基本上就是填补工作了,先加个比较好看的背景动效 particles.js。
npm install --save particles.js
引入、初始化和销毁,snow是网上找一个particles配置json文件(附在末尾)
// 注意 这里用 require 引入 particles.js
require('particles.js') /* eslint-disable */ // 使eslint忽略对该行代码的检查
import config from './config/snow'// 雪花动效组件配置 如需更换动效 修改名称即可
mounted () {
particlesJS('container', config)// 初始化粒子插件 将其挂载到dom上 注意dom上声明id
},
// 注意在销毁
beforeDestroy () {
if (pJSDom && pJSDom.length > 0) { // 销毁 particlesJS 解决内存溢出问题
pJSDom[0].pJS.fn.vendors.destroypJS()
pJSDom = []
}
},
开始写登陆表单,可以再对登陆表单进行分解,logo、表单、底部帮助信息或单点登录等,常规的css代码,没难度就不单独说明
到这里开始使用sass 安装一下,这里注意和node版本匹配问题本项目nodejs是v12.14.0,本来要安装scss的 结果一直和nodejs版本不匹配,干错来个省心的 直接sass,两个的区别自己查下百度,记得清楚一点。
"sass": "^1.18.0",
"sass-loader": "^7.1.0",
到这里登陆页面大体上就完成了
以下是主要文件的代码
my_project/src/login/index.vue
<!--
* @Description: 登陆页面
* @Author: Walis
* @Date: 2022-11-04 13:00:48
* @LastEditors: Walis
* @LastEditTime: 2022-11-04 19:30:02
-->
<template>
<div class="container"
id="container">
<!-- 提示信息 -->
<div class="tips">{{tipsList[tipsIndex]}}</div>
<!-- 登录框 -->
<div class="login_box">
<el-card class="login_form">
<!-- 这里可以替换成svg图 -->
<div class="logo">
系统登陆
</div>
<div class="form">
<el-form ref="form"
:model="form"
style="padding:30px 0px;">
<el-form-item>
<el-input placeholder="请输入用户名"
v-model="form.username">
<i slot="prepend"
class="el-icon-user"></i>
</el-input>
</el-form-item>
<el-form-item>
<el-input v-model="form.password"
placeholder="请输入密码">
<i slot="prepend"
class="el-icon-lock"></i>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary"
class="button_login">登陆</el-button>
</el-form-item>
<p class="login_help">
<span><i class="el-icon-question"></i>忘记密码</span>
<span style="float:right">注册用户</span>
</p>
</el-form>
</div>
</el-card>
</div>
<!-- 底部版权信息 -->
<div class="copyright">copyright@一个总在代码给自己下毒的程序猿</div>
</div>
</template>
<script>
// 注意 这里用 require 引入 particles.js
require('particles.js') /* eslint-disable */ // 使eslint忽略对该行代码的检查
import config from './config/snow'// 雪花动效组件配置 如需更换动效 修改名称即可
export default {
components: {},
data () {
return {
form: {},
tipsIndex: 0, // 随机提示信息索引
tipsList: [ // 随机提示信息数组
'一个好的程序员是那种过单行线马路都要往两边看的人。(Doug Linder)',
'程序有问题时不要担心。如果所有东西都没问题,你就失业了。(软件工程的Mosher定律)',
'程序员的麻烦在于,你无法弄清他在捣腾什么,当你最终弄明白时,也许已经晚了。(超级计算机之父Seymour Cray) ',
'程序员最讨厌的两件事:写文档写注释,别人不写文档别人不写注释'
],
}
},
methods: {
},
mounted () {
// 初始化提示信息
this.tipsIndex = Math.floor((Math.random() * this.tipsList.length))
particlesJS('container', config)// 初始化粒子插件
},
beforeDestroy () {
if (pJSDom && pJSDom.length > 0) { // 销毁 particlesJS 解决内存溢出问题
pJSDom[0].pJS.fn.vendors.destroypJS()
pJSDom = []
}
},
}
</script>
<style scoped lang="scss">
.container {
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
background-image: url("./image/back1.jpeg");
background-position: center top;
background-size: 100% 100%;
overflow: hidden;
.tips {
top: 20px;
position: absolute;
font-size: 20px;
color: #fff;
}
.login_box {
top: 30%;
position: absolute;
}
.logo {
font-size: 30px;
text-align: center;
}
.login_form {
height: 400px;
width: 350px;
.button_login {
width: 100%;
}
.login_help {
font-size: 14px;
color: #409eff;
}
}
.copyright {
bottom: 20px;
position: absolute;
color: #fff;
}
}
</style>
效果图
明天对已完成的代码进行优化,使得更优雅一些,会用到flex.css,可以提前做下功课。
snow.js文件
/* eslint-disable */
export default {
"particles": {
"number": {
"value": 400,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#fff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.5,
"random": true,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 10,
"random": true,
"anim": {
"enable": false,
"speed": 40,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 500,
"color": "#ffffff",
"opacity": 0.4,
"width": 2
},
"move": {
"enable": true,
"speed": 6,
"direction": "bottom",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 0.5
}
},
"bubble": {
"distance": 400,
"size": 4,
"duration": 0.3,
"opacity": 1,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}