几天没有更新,最近参加了前端学习的夏令营,收获了很多东西。
学习周期
7月26~8月4日
学习内容
1. 统一讲授基础的技术(前端 + 后端)
2. 暂定时间 7月30日 结束基础技术讲解
3. 7月31日 开始进入到团队项目
整个B站项目 - 基于B站小程序视频播放平台
1. 前端架构 - 小程序技术支撑
1)完成界面开发
2)完成数据渲染
3)动态效果设计
2. 后端架构 - Java技术支撑
1)提供前端小程序所需要的数据接口
2)提供一个管理数据的平台
a:统计数据 - 今天又多少人访问我们小程序
b:新增视频 - 难道请数据库管理员(DBA)进行数据添加???
今日头条 - 聚会类型平台 - 用户群体面向(个人;媒体)
1. 自媒体 - 新闻;抖音;视频
2. 类似知了堂视频平台管理端
思考:
1. 尽量满足用户需求 - 开发人员职责
2. 后端同学需不需开发一个后端数据管理中心???
项目去学习技术
1. 需求分析 - 功能(团队)
1)前端
a:主页 - 提供怎样的功能(需要多少数据 - 参数)
b:分类 - 提供怎样的功能(需要多少数据 - 参数)
c:个人 - 提供怎样的功能(需要多少数据 - 参数)
d:视频 - 播放页面(需要多少数据 - 参数)
结论:找后端开发人员给我数据
2)后端
a:数据库怎么设计
b:视频主页 - 提供怎样的功能
c:发表视频 - 提供怎样的功能
d:内容管理 - 提供怎样的功能
e:评论管理 - 提供怎样的功能
f:视频数据 - 提供怎样的功能
产出内容:需求分析 - 思维导图
2. 原型图设计 - axure 工具
3. 开发文档设计 - 前端和后端开发规范
1)设计接口文档
2)如下非常重要内容
a:接口地址 - 网络地址 - 访问地址,则可以获取服务器上数据
b:接口功能
c:请求参数
d:请求方式
e:返回数据类型
f:返回数据结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCNw73uD-1595950549581)(day0.assets/image-20200726140338845.png)]
具体的接口文档格式,请参考上课word文档
任务 - 团队合作任务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QIqLVrQt-1595950549587)(day0.assets/image-20200726150800623.png)]
工具
1.1 课程介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g4da4zsd-1595950602505)(day1.assets/image-20200723141241139.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WEvvZzY8-1595950602507)(day1.assets/image-20200723141337217.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RWTpjLU5-1595950602509)(day1.assets/image-20200723141437942.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64RM2Ie4-1595950602511)(day1.assets/image-20200723141530324.png)]
前端展示型标签:
后端数据控制中心标签:
CSS概念:层叠样式表,用于美化我们网页标签外观样式。比如:图片圆角;阴影效果;动画效果
CSS版本:CSS2 ;CSS3
/* 独立新建样式文件,后缀名.css */
body {...}
img {...}
ul {...}
<html>
<head>
<link href='1.css' type='text/css' rel='stylesheet'>
head>
html>
<html>
<head>
<style>
body {...}
img {...}
ul {...}
style>
head>
html>
<html>
<head>head>
<body>
<img style='width:100px; height: 100px'>
body>
html>
注意:
1.样式有一个优先级,内嵌样式 > 内部样式 > 外部样式
2.样式代码需要用分号 ; 结束
选择器:给标签指定样式(不是所有标签都需要进行样式美化)
选择器分类:
第1钟:id选择器,根据标签属性id值来进行样式定义
<div id="d1">div>
#d1 {
样式代码
}
第2钟:class选择器,根据标签属性class值来进行样式定义
<div class='d2'>div>
.d2 {
样式代码
}
第3钟:标签选择器,根据标签的名字来进行样式定义
<div>div>
div {
样式代码
}
第4钟:群组选择器,可以一次性为多个不同的标签统一的去定义相同样式
<div>div>
<button>button>
<div class='d3'>div>
div, button, .d3 {
样式代码
}
第5钟:层次选择器,如果我想去定义div里面button标签的样式
<div class='d4'>
<button>button>
<button>button>
<button>button>
div>
.d4 > button { // 使用大于号,则定义直接子元素样式
样式代码
}
.d4 button { // 空格,则定义子元素,或 子元素的子元素样式(儿子,孙子,孙子的孙子)
样式代码
}
<html>
<head>
<title>title>
<style type="text/css">
#d1 {
width: 300px;
height: 100px;
background-color: red;
}
.d2 {
width: 400px;
height: 100px;
background-color: black;
}
div {
width: 500px;
height: 100px;
background-color: blue;
}
.d3 {
width: 600px;
height: 100px;
background-color: yellow;
}
/* 层次选择器 */
.d3 > button {
width: 50px;
}
/* 群组选择器 */
.d4, p {
width: 700px;
height: 100px;
background-color: gray;
}
style>
head>
<body>
<div id="d1">div>
<div class="d2">div>
<div>div>
<div class="d3">
<button>按钮1button>
<button>按钮2button>
<button>按钮3button>
div>
<div class="d4">我是一个divdiv>
<p>我是一个p标签p>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
div {
/* 文本样式 */
color: red; /* 颜色 */
font-size: 20px;
font-weight: bold;
line-height: 50px; /* 当行高 = 盒子高度 垂直居中效果 */
text-align: center;
/*盒模型*/
width: 200px;
height: 50px;
border: 1px solid black;
margin: 0 auto; /* margin 设置 上右下左 外边距距离 */
padding: 0 10px; /* 文字内容 与 div的边框左右距离 10px */
border-radius: 5px; /* 设置 div的四个角 */
box-shadow: 10px 10px 10px gray; /* 边框阴影设置 (x,y,blur,color) */
}
style>
head>
<body>
<div>HelloWorlddiv>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
.d1 {
width: 100%;
height: 300px;
margin: 0 auto;
background: rgb(74,36,121);
}
.d2 {
width: 800px;
height: 300px;
margin: 0 auto;
background-image: url(img/109951165132818526.jpg);
background-size: cover;
}
style>
head>
<body>
<div class="d1">
<div class="d2">div>
div>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
.d1 {
width: 500px;
height: 300px;
background-color: gray;
margin: 0 auto;
position: relative; /* 加入了一个相对定位,则它里面的子元素就可以针对它定位了 */
}
.d2 {
width: 200px;
height: 100px;
background-color: black;
/* 如果是绝对定位, 针对父元素进行定位, 绝对定位往往有一个坑(它的父元素设置定位没有) */
/* 如果父元素没有设置定位,则相对浏览器定位 */
position: absolute;
left: 10px;
top: 30px;
}
style>
head>
<body>
<div class="d1">
<div class="d2">div>
div>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
.d2 {
width: 200px;
height: 30px;
color: white;
line-height: 30px;
background-color: black;
position: fixed; /* 固定定位, 针对浏览器的定位 */
right: 0;
top: 100px;
}
style>
head>
<body>
<div class="d1">
# 2.系统架构演变
随着互联网的发展,网站应用的规模不断扩大。需求的激增,带来的是技术上的压力。系统架构也因此不断的演进、升级、迭代。从单一应用,到垂直拆分,到分布式服务,到SOA,以及现在火热的微服务架构,还有在Google带领下来势汹涌的Service Mesh。我们到底是该乘坐微服务的船只驶向远方,还是偏安一隅得过且过?
其实生活不止眼前的苟且,还有诗和远方。所以我们今天就回顾历史,看一看系统架构演变的历程;把握现在,学习现在最火的技术架构;展望未来,争取成为一名优秀的Java工程师。
## 2.1.集中式架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是影响项目开发的关键。
![1525529091749](day1.assets/1525529091749.png)
存在的问题:
- 代码耦合,开发维护困难
- 无法针对不同模块进行针对性优化
- 无法水平扩展
- 单点容错率低,并发能力差
## 2.2.垂直拆分
当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分:
![1525529671801](day1.assets/1525529671801.png)
优点:
- 系统拆分实现了流量分担,解决了并发问题
- 可以针对不同模块进行优化
- 方便水平扩展,负载均衡,容错率提高
缺点:
- 系统间相互独立,会有很多重复开发工作,影响开发效率
## 2.3.分布式服务
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。
![1525530657919](day1.assets/1525530657919.png)
优点:
- 将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率
缺点:
- 系统间耦合度变高,调用关系错综复杂,难以维护
## 2.4.流动计算架构(SOA)
SOA :面向服务的架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键
![1525530804753](day1.assets/1525530804753.png)
以前出现了什么问题?
- 服务越来越多,需要管理每个服务的地址
- 调用关系错综复杂,难以理清依赖关系
- 服务过多,服务状态难以管理,无法根据服务情况动态管理
服务治理要做什么?
- 服务注册中心,实现服务自动注册和发现,无需人为记录服务地址
- 服务自动订阅,服务列表自动推送,服务调用透明化,无需关心依赖关系
- 动态监控服务状态监控报告,人为控制服务状态
缺点:
- 服务间会有依赖关系,一旦某个环节出错会影响较大
- 服务关系复杂,运维、测试部署困难,不符合DevOps思想
## 2.5.微服务
前面说的SOA,英文翻译过来是面向服务。微服务,似乎也是服务,都是对系统进行拆分。因此两者非常容易混淆,但其实却有一些差别:
微服务的特点:
- 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责
- 微:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
- 面向服务:面向服务是说每个服务都要对外暴露Rest风格服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口即可。
- 自治:自治是说服务间互相独立,互不干扰
- 团队独立:每个服务都是一个独立的开发团队,人数不能过多。
- 技术独立:因为是面向服务,提供Rest接口,使用什么技术没有别人干涉
- 前后端分离:采用前后端分离开发,提供统一Rest接口,后端不用再为PC、移动段开发不同接口
- 数据库分离:每个服务都使用自己的数据源
- 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
微服务结构图:
![1526860071166](day1.assets/1526860071166.png)
# 3.后端技术能力要求
同学们一定要注意,目前企业的后端技术开发趋势,务必是前后端技术整合
对于目前应届生同学需要学习技术内容如下,这个也是企业的要求
## 3.1 前端技术
前端技术:
- 基础的HTML、CSS、JavaScript(基于ES6标准)
- Vue.js 2.0以及基于Vue的UI框架:Vuetify
- 前端构建工具:WebPack
- 前端安装包工具:NPM
- Vue脚手架:Vue-cli
- Vue路由:vue-router
- ajax框架:axios
- 基于Vue的富文本框架:quill-editor
## 3.2 后端技术
后端技术:
- 基础的SpringMVC、Spring 5.0和MyBatis3
- Spring Boot 2.0.1版本
- Spring Cloud 最新版 Finchley.RC1
- Redis-4.0
- RabbitMQ-3.4
- Elasticsearch-5.6.8
- nginx-1.10.2
- FastDFS - 5.0.8
- MyCat
- Thymeleaf
- JWT
## 3.3 技术解读
上面的技术组合可以在项目中解决以下的典型问题:
- 利用Node.js及Vue.js技术栈,实现前后端分离开发
- 利用SpringCloud技术栈,实现真正的微服务实战开发,并且是基于SpringBoot2.0和SpringCloud最新版本Finchley.RC1实现,业内领先。
- 基于FastDFS解决大数据量的分布式文件存储问题
- 基于Elasticsearch高级聚合功能,实现商品的智能过滤搜索
- 基于Elasticsearch高级聚合功能,实现销售业务的复杂统计及报表输出
- 基于LocalStorage实现离线客户端购物车,减轻服务端压力。
- 基于JWT技术及RSA非对称加密实现真正无状态的单点登录。
- 结合JWT和RSA非对称加密,自定义Feign过滤器实现自动化服务间鉴权,解决服务对外暴露的安全问题
- 基于RabbitMQ实现可靠消息服务,解决服务间通信问题
- 基于RabbitMQ实现可靠消息服务,解决分布式事务问题
- 使用微信SDK实现微信扫码支付,符合主流付款方式
- 基于Redis搭建高可用集群,实现可靠缓存服务即热点数据保存。持久化,集群,哨兵,主从,缓存击穿
- 基于Redis和Mq来应对高可用高并发的秒杀场景
- 基于MyCat实现数据库的读写分离和分库分表
- 基于Thymeleaf实现页面模板和静态化,提高页面响应速度和并发能力
- 基于Nginx实现初步的请求负载均衡和请求限流
div>
<div class="d2">
对话框: 正在讲话 刘阳
div>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
.d1 {
/* 如果没有设置定位,则div是在浏览器的左上角 */
width: 200px;
height: 50px;
background-color: black;
transition: 5s all; /* 动态的特效 */
}
.d1:hover {
/* 相对原来的位置移动 10px;50px; */
position: relative;
top: 200px;
left: 100px;
}
style>
head>
<body>
<div class="d1">div>
body>
html>
目的:
学习弹性布局,最关键的因素,同学必须了解什么是块级元素标签
弹性布局样式
.d1 {
display: flex; /* 表示当前div是一个弹性布局 */
jusitfy-content: space-around; /* 控制元素在X轴一个对齐方式(主轴) */
}
<html>
<head>
<title>title>
<style type="text/css">
/* 弹性布局用于在父级标签上, 作用控制子级标签的布局 */
.d1 {
width: 90%;
height: 80px;
background-color: green;
margin: 0 auto;
display: flex;
justify-content: center;
}
/* 层次选择器,设置d1下面的所有div的样式 */
.d1 > div {
width: 180px;
height: 80px;
background-color: blue;
margin: 0 3px;
}
style>
head>
<body>
<div class="d1">
<div>div>
<div>div>
<div>div>
<div>div>
<div>div>
div>
<div class="d1">div>
body>
html>
完成西瓜视频首页实战 - 弹性布局练习
难点:
整体布局代码
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%; /* 相当于能够针对不同浏览器能够全屏显示 */
height: 100%; /* 相当于整个网页是整屏显示,局部滚动 */
overflow: hidden; /* 局部内容的高度肯定会大于整个浏览器的高度,那么超出部分要隐藏 */
}
.xg-nav {
width: 100%;
height: 73px;
background-color: #000;
}
.xg-body {
width: 100%;
height: calc(100vh - 73px); /* 自动计算出下方div的高度,针对不同浏览器分辨率算出div高度 */
background-color: blue;
display: flex;
}
.xg-menu {
width: 200px;
height: 100%;
background-color: yellow;
}
.xg-ctn {
width: calc(100vw - 200px);
height: 100%;
background-color: red;
}
style>
head>
<body>
<div class="xg-nav">div>
<div class="xg-body">
<div class="xg-menu">div>
<div class="xg-ctn">div>
div>
body>
html>
局部带滚动条的代码
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%; /* 相当于能够针对不同浏览器能够全屏显示 */
height: 100%; /* 相当于整个网页是整屏显示,局部滚动 */
overflow: hidden; /* 局部内容的高度肯定会大于整个浏览器的高度,那么超出部分要隐藏 */
}
.xg-nav {
width: 100%;
height: 73px;
background-color: #000;
}
.xg-body {
width: 100%;
height: calc(100vh - 73px); /* 自动计算出下方div的高度,针对不同浏览器分辨率算出div高度 */
background-color: blue;
display: flex;
}
.xg-menu {
width: 200px;
height: 100%;
background-color: yellow;
}
.xg-ctn {
width: calc(100vw - 200px);
height: 100%;
background-color: rgb(247,247,247);
display: flex;
justify-content: space-around;
flex-wrap: wrap; /* 自动换行 当屏幕的宽度不够,则自动换行*/
overflow-y: auto;
}
/* 内容区的样式 */
.xg-item {
width: 270px;
height: 212px;
background-color: hotpink; /* #代表颜色取值是一个十六进制数 0~F */
margin-top: 30px;
border-radius: 5px;
display: flex; /* 调整弹性布局的方向,默认方向是水平方向 */
flex-direction: column; /* 调整弹性布局为垂直方向 */
justify-content: space-between; /* 上下对齐,均匀分布 */
}
/* 内容区的样式中图片 */
.xg-item > img {
width: 100%;
height: 145px;
border-radius: 5px;
}
style>
head>
<body>
<div class="xg-nav">div>
<div class="xg-body">
<div class="xg-menu">div>
<div class="xg-ctn">
<div class="xg-item">
<img src="img/1.jpg">
<p>龙珠Z: 复活的菲利沙p>
<p>龙珠之宇宙最强对决p>
div>
<div class="xg-item">
<img src="img/2.jpg">
<p>吹哨人p>
<p>雷佳音汤唯陷两难抉择p>
div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
<div class="xg-item">div>
div>
div>
body>
html>
同学需要了解一个伪类:hover
,当鼠标移动到元素上时候会触发一个动作(鼠标悬停效果)
<html>
<head>
<title>title>
<style type="text/css">
.d-scale, .d-translate, .d-rotate {
width: 300px;
height: 100px;
margin: 0 auto;
margin-top: 100px;
background-color: blue;
transition: 2s all; /* 时间 规定设置过渡效果的 CSS 属性的名称 */
}
/* 伪类:hover设置变大的效果; */
.d-scale:hover {
transform: scale(1.2);
}
/* 单独在修改d-translate局部样式 */
.d-translate {
margin-top: 15px;
background-color: green;
}
/* 伪类:hover鼠标悬停事件 */
.d-translate:hover {
transform: translateX(-50px); /* 水平X轴反方向移动 */
}
/* 局部修改部分样式 */
.d-rotate {
margin-top: 50px;
background-color: red;
}
.d-rotate:hover {
transform: rotate(-30deg);
}
style>
head>
<body>
<div class="d-scale">div>
<div class="d-translate">div>
<div class="d-rotate">div>
body>
html>
自定义动画语法
/* @keyframes语法一 */
@keyframes 动画名称 {
from{ /* 开始动画 */
}to{ /* 结束动画 */
}
}
/* @keyframes语法二 */
@keyframes 动画名称 {
0%{ /* 动画执行的时间点 */
}
30%{ /* 动画执行的时间点 */
}
50%{ /* 动画执行的时间点 */
}
100%{ /* 动画执行的时间点 */
}
}
/* 动画的运行语法, animation必须放到选择器里面 */
/* animation所有动画属性的简写属性 */
animation: 动画名称 时间 速度 延迟多久开始执行 逆向播放 次数
小小技巧扩展:如何让元素垂直居中 + 水平居中
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
.d-animation {
width: 200px;
height: 100px;
background-color: #000;
position: absolute; /* 针对浏览器定位 */
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -50px;
}
style>
head>
<body>
<div class="d-animation">div>
body>
html>
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
.d-animation {
width: 200px;
height: 100px;
background-color: #000;
position: absolute; /* 针对浏览器定位 */
left: 50%;
top: 50%;
transform: translate(-100px, -50px);
}
style>
head>
<body>
<div class="d-animation">div>
body>
html>
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.d-animation {
width: 200px;
height: 100px;
background-color: #000;
}
style>
head>
<body>
<div class="d-animation">div>
body>
html>
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.d-animation {
width: 200px;
height: 100px;
background-color: #000;
animation: kf .5s linear 1s infinite;
}
/* 定义动画 */
@keyframes kf {
0%{
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
style>
head>
<body>
<div class="d-animation">div>
body>
html>
<html>
<head>
<title>title>
<meta charset="utf-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.box {
width: 180px;
height: 160px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -90px;
margin-top: -80px;
animation: kf 1s alternate infinite;
}
.round1 {
width: 100px;
height: 100px;
border-radius: 50%; /* 圆 */
background-color: hotpink;
position: absolute;
left: 0;
top: 0;
}
.round2 {
width: 100px;
height: 100px;
border-radius: 50%; /* 圆 */
background-color: hotpink;
position: absolute;
right: 0;
top: 0;
}
.bottom {
width: 100px;
height: 100px;
background-color: hotpink;
position: absolute;
left: 40px;
top: 40px;
transform: rotate(45deg);
}
@keyframes kf {
0%{
transform: scale(0.6);
}
100%{
transform: scale(1);
}
}
style>
head>
<body>
<div class="box">
<div class="round1">div>
<div class="round2">div>
<div class="bottom">div>
div>
body>
html>
<html>
<head>
<title>title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.taiji {
margin: 0 auto; /* 水平居中 */
margin-top: 100px; /* 顶部距离100px */
width: 400px;
height: 200px;
border-radius: 50%;
border: 1px solid black;
border-bottom-width: 200px;
position: relative; /* 相对定位:针对自己的位置进行定位 */
animation: kf 5s 10s infinite;
}
/* ::before 伪元素(虚拟元素); */
/* css的伪元素,之所以被称为伪元素,是因为他们不是真正的页面元素 */
.taiji::before {
content: '';
border: 85px solid black;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: white;
position: absolute; /* 父元素只要有定位才能控制子元素的在父元素中位置 */
top: 50%;
left: 0;
}
.taiji::after {
content: '';
border: 85px solid white;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: black;
position: absolute; /* 父元素只要有定位才能控制子元素的在父元素中位置 */
top: 50%;
right: 0;
}
@keyframes kf {
0%{
transform: rotate(0deg);
}100%{
transform: rotate(360deg);
}
}
style>
head>
<body>
<div class="taiji">div>
body>
html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GjVemG9K-1595950602513)(day1.assets/image-20200727160430449.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Smrc92IJ-1595950602515)(day1.assets/image-20200727160505831.png)]
<html>
<head>
<title>title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.box {
position: relative;
width: 200px;
height: 200px;
margin: 200px auto;
transform-style: preserve-3d; /* 开启 3D 特效 */
transition: all 2s ease;
}
.side {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 36px;
color: #fff;
background-color: rgba(66, 66, 66, 0.5);
}
.left {
transform: translateX(-100px) rotateY(90deg);
background-color: rgba(57, 57, 107, 0.5);
}
.right {
transform: translateX(100px) rotateY(90deg);
background-color: rgba(62, 238, 86, 0.5);
}
.top {
transform: translateY(-100px) roateX(90deg);
background-color: rgba(164, 57, 226, 0.5);
}
.bottom {
transform: translateY(100px) roateX(90deg);
background-color: rgba(212, 214, 53, 0.5);
}
.before {
transform: translateZ(100px);
background-color: rgba(216, 107, 53, 0.5);
}
.after {
transform: translateZ(-100px);
background-color: rgba(221, 41, 176, 0.5);
}
.box:hover {
transform: rotateX(360deg) rotateY(360deg);
}
style>
head>
<body>
<div class="box">
<div class="side before">前div>
<div class="side after">后div>
<div class="side left">左div>
<div class="side right">右div>
<div class="side top">上div>
<div class="side bottom">下div>
div>
body>
html>
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/
注意:先创建一个空目录,存储小程序源代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzYnPN9n-1595950602516)(day1.assets/image-20200727165401745.png)]
wxml:小程序页面
wxss:小程序样式
js:小程序业务逻辑代码
"pages":[
"pages/index/index",
"pages/logs/logs"
],
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构
通过 {{}} 表示要绑定数据
<text>{{username}}text>
<text>{{userage}}text>
/**
* 页面的初始数据
*/
data: {
'username': '张三',
'userage': 23
},
注意:数据绑定
<text>{{username}}text>
<text>{{userage}}text>
<text wx:if='{{useraddress != ""}}'>{{useraddress}}text>
<text wx:for='{{users}}'>{{item}}text>
/**
* 页面的初始数据
*/
data: {
'username': '张三',
'userage': 23,
'useraddress': '成都',
'users':['李四', 23, '成都']
},
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cyvhaquh-1595950624800)(day2.assets/image-20200728110458673.png)]
<view class='container'>
<view class="battery">view>
view>
/* 设置一个页面样式 */
page {
width: 100%;
height: 100%;
display: flex;
}
/* 电池充电壳 - 容器 */
.container {
position: relative;
width: 340rpx;
height: 500rpx;
margin: auto;
}
/* 存储电量 - 容器*/
.battery {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 15rpx 15rpx 5rpx 5rpx;
background-color: #fff;
filter: drop-shadow(0 1rpx 3rpx rgba(1,188,213, .82));
}
/* 电池正极 */
.battery::before {
content: '';
position: absolute;
left: 50%;
top: 0;
width: 80rpx;
height: 30rpx;
background-color: rgba(2,119,253, .88);
border-radius: 5rpx 5rpx 0 0;
transform: translate(-50%, -30rpx);
}
/* 电量样式 */
.battery::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 80%;
border-radius: 0 0 5rpx 5rpx;
background: linear-gradient(to bottom, #7abcff 0%, #00BCD4 44%, #2196F3 100%);
animation: chong 6s linear infinite;
}
@keyframes chong {
95%{
top: 5%;
border-radius: 0 0 5rpx 5rpx;
}100%{
top: 0;
border-radius: 15rpx 15rpx 5rpx 5rpx;
}
}
JavaScript是一种属于网络的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的
JavaScript的标准是ECMAScript 。截至 2012 年,所有浏览器都完整的支持ECMAScript 5.1,旧版本的浏览器至少支持ECMAScript 3 标准。2015年6月17日,ECMA国际组织发布了ECMAScript的第六版,该版本正式名称为 ECMAScript 2015,但通常被称为ECMAScript 6 或者ES6
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iguGiyfn-1595950624803)(day2.assets/image-20200728111750870.png)]
ECMAScript 6(ES6) 目前基本成为业界标准,它的普及速度比 ES5 要快很多,主要原因是现代浏览器对 ES6 的支持相当迅速,尤其是 Chrome 和 Firefox 浏览器,已经支持 ES6 中绝大多数的特性
ES6推荐使用let定义局部变量
var x = '全局变量';
{
let x = '局部变量';
console.log(x); // 局部变量
}
console.log(x); // 全局变量
const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了
const a = 1
a = 0 //报错
ES6之前处理字符串:通过\
或 +
来构建模板
$("body").html("This demonstrates the output of HTML \
content to the page, including student's\
" + name + ", " + seatNumber + ", " + sex + " and so on.");
ES6的字符串应用
$("body").html(`This demonstrates the output of HTML content to the page,
including student's ${name}, ${seatNumber}, ${sex} and so on.`);
ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体
箭头函数三大特点
return
关键字// ES5
var add = function (a, b) {
return a + b;
};
// 使用ES6箭头函数
var add = (a, b) => a + b;
// ES5
[1,2,3].map((function(x){
return x + 1;
}).bind(this));
// 使用ES6箭头函数
[1,2,3].map(x => x + 1);
// ES6之前,当未传入参数时,text = 'default';
function printText(text) {
text = text || 'default';
console.log(text);
}
// ES6;
function printText(text = 'default') {
console.log(text);
}
printText('hello'); // hello
printText();// default
for…of 用于遍历一个迭代器,如数组
let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
console.log(letter);
}
// 结果: a, b, c
for…in 用来遍历对象中的属性:
let stus = ["Sam", "22", "男"];
for (let stu in stus) {
console.log(stus[stu]);
}
// 结果: Sam, 22, 男
ES6 允许在对象中使用 super 方法
var parent = {
foo() {
console.log("Hello from the Parent");
}
}
var child = {
foo() {
super.foo();
console.log("Hello from the Child");
}
}
Object.setPrototypeOf(child, parent);
child.foo(); // Hello from the Parent
// Hello from the Child
小程序JS的开发,完全采用ECMAScript语法标准来执行的。所以,大家学习小程序开发之前一定要把JavaScript学好
小程序中渲染层和逻辑层是理解小程序实现动态数据交互,以及如何操作网页标签和样式的核心
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N8KOVgGy-1595950624805)(day2.assets/image-20200728120720328.png)]
小程序启动后,界面被展示给用户,此时小程序处于前台状态。
当用户点击右上角胶囊按钮关闭小程序,或者按了设备 Home 键离开微信时,小程序并没有完全终止运行,而是进入了后台状态,小程序还可以运行一小段时间。
当用户再次进入微信或再次打开小程序,小程序又会从后台进入前台。但如果用户很久没有再进入小程序,或者系统资源紧张,小程序可能被销毁,即完全终止运行。
这样,小程序启动可以分为两种情况,一种是冷启动,一种是热启动。
通常,只有当小程序进入后台一定时间,或者系统资源占用过高,才会被销毁。具体而言包括以下几种情形:
以下内容你不需要立马完全弄明白,不过以后它会有帮助
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfzE3Wjs-1595950624807)(day2.assets/page-lifecycle.2e646c86.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8UR5UoJv-1595950624809)(day2.assets/image-20200728143032313.png)]
案例界面:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jdo4e9zw-1595950624811)(day2.assets/image-20200728143117700.png)]
涉及到技术
<view class='swiper-tab'>
<view class="swiper-tab-item {{currentTab == 0 ? 'active': ''}}" data-current='0' bindtap='clickTab'>全部view>
<view class="swiper-tab-item {{currentTab == 1 ? 'active': ''}}" data-current='1' bindtap='clickTab'>提现中view>
<view class="swiper-tab-item {{currentTab == 2 ? 'active': ''}}" data-current='2' bindtap='clickTab'>已提现view>
view>
<swiper duration="300" current="{{currentTab}}" bindchange='swiperTab'>
<swiper-item>
<view>全部页面view>
swiper-item>
<swiper-item>
<view>提现中页面view>
swiper-item>
<swiper-item>
<view>已提现页面view>
swiper-item>
swiper>
.swiper-tab {
width: 100%;
height: 88rpx;
border-bottom: 2rpx solid #ccc;
text-align: center;
line-height: 88rpx;
display: flex;
flex-flow: row;
justify-content: space-around;
}
.swiper-tab-item {
width: 22%;
color: #434343;
}
.active {
color: #F65959;
border-bottom: 4rpx solid #F65959;
}
swiper {
height: 800rpx;
line-height: 800rpx;
font-weight: bold;
font-size: 45rpx;
text-align: center;
}
// pages/aliplay/aliplay.js
Page({
/**
* 页面的初始数据
*/
data: {
'currentTab': 0
},
// 滑块左右滑动会触发此事件
swiperTab: function(e) {
let _this = this;
_this.setData({ // 如果要去修改 data 里面变量 currentTab,则需使用 setData() 函数
currentTab: e.detail.current // 给变量currentTab进行重新赋值
});
},
// 卡片点击事件
clickTab: function(e) {
// 当点中卡片需要去改变 currentTab 变量
// currentTab 变量的值怎么来
// e.target.dataset.current 相当于
let _this = this;
if(_this.data.currentTab === e.target.dataset.current) {
return false;
} else {
_this.setData({
currentTab: e.target.dataset.current
})
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-utwo6duk-1595950624812)(day2.assets/image-20200728153930723.png)]
目标达成:
this.data.变量名
this.setData(...)
function(e) {}
,e.target.dataset.index
<view class='page'>
<view class="page-bottom">
<view class="page-content">
<view class="wc">
<text>第一个item-1text>
view>
<view class="wc">
<text>第二个item-2text>
view>
<view class="wc">
<text>第三个item-3text>
view>
<view class="wc">
<text>第四个item-4text>
view>
view>
view>
<view class="page-top {{open ? 'c-state1': ''}}">
<image src="/images/btn.png" bindtap="tap_ch">image>
view>
view>
page, .page {
height: 100%;
}
.page-bottom {
height: 100%;
width: 750rpx;
position: fixed;
z-index: 0;
background-color: rgb(0, 68, 97);
}
.page-content {
padding-top: 300rpx;
}
.wc {
color: #fff;
padding: 30rpx 0 30rpx 40rpx;
}
.page-top {
height: 100%;
position: fixed;
width: 750rpx;
z-index: 0;
background-color: rgb(57, 125, 230);
transition: 0.4s all ease;
}
.page-top image {
position: absolute;
width: 68rpx;
height: 38rpx;
left: 20rpx;
top: 20rpx;
}
.c-state1 {
transform: rotate(0deg) scale(1) translate(75%, 0%);
}
// pages/side/side.js
Page({
/**
* 页面的初始数据
*/
data: {
open: false
},
tap_ch: function(e) {
// 点击控制样式的变化
// this 当前页面的对象,包含:js里面函数,变量名,内置方法 setData()
let _this = this;
if(_this.data.open) {
_this.setData({
open: false // 关闭状态
});
} else {
_this.setData({
open: true // 打开状态
});
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
目标达成:
实现步骤:
第一步:寻找提供天气预报第三方服务器,分析服务器提供的数据接口格式
第二步:通过微信小程序网络请求组件,能够拉取第三方服务器发送数据
wx.request
函数请求网络数据[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xTItlNqU-1595950624813)(day2.assets/image-20200728172025795.png)]
wx.request({
url: 'http://api.tianapi.com/txapi/tianqi/index?key=xxx&city=成都',
method: 'GET',
dataType: 'JSON',
success: function(e) {}
});
第三步:设计天气预报界面,然后将数据渲染到界面里面
newslist
// pages/weather/weather.js
Page({
/**
* 页面的初始数据
*/
data: {
weatherlist: [] // 给wxml传递数据
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var _this = this;
console.log(_this.data.weatherlist);
wx.request({
url: 'http://api.tianapi.com/txapi/tianqi/index?key=ed1394ce936a5526c70fea58875538e0&city=成都',
method: 'GET',
dataType: 'json', // 小写的json
success: function(e) {
// e.newslist 返回存储天气信息数据
// let newslist 自己定义的变量, 接收 e.newslist 里面数据
let newslist = e.data.newslist;
_this.setData({
weatherlist: newslist
});
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
今天学习了微信小程序的开发文档,写了电池的小程序,和天气预报,掌握了小程序开发的主要步骤。