后端开发必备的前端知识
一、开发流程
最初所有的开发工作都是由后端工程师完成的,随着业务越来越繁杂,工作量变大,于是我们将项目中的可视化部分和一部分交互功能的开发工作剥离出来,形成了前端开发。
大约从2005年开始正式的前端工程师角色被行业所认可,到了2010年,互联网开始全面进入移动时代,前端开发的工作越来越重要
1、常用软件
1.1 VS Code
下载: https://code.visualstudio.com/Download
安装插件:
1.2 WebStorm
下载:https://www.jetbrains.com/zh-cn/webstorm/download/other.html
安装插件:
二、JQuery
2.1概念:
一个JavaScript框架,简化JS开发
JQ是一个快速、简介的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。JQ设计的宗旨是’write Less,Do More’,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
JavaScript框架:本质上就是一些JS文件,封装了JS的原生代码
2.2快速入门
下载JQuery:https://jquery.com/
中文文档: https://jquery.cuishifeng.cn/
目前JQuery有三个大版本:
1.x:兼容ie867,使用最为广泛的,官方只做BUG维护,功能不再新增。因此一般项目来说,使用1.x版本就可以了,最终版本:1.12.4(2016年5月20日)
2.x:不兼容ie867,很少有人使用,官方只做BUG维护,功能不再新增。如果不考虑兼容低版本的浏览器可以使用2.x,最终版本:2.2.4(2016年5月20日)
3.x:比兼容ie867,只支持最新的浏览器。除非特殊要求,一般不会使用3.x版本,很多老的JQuery插件不支持这个版本。目前该版本是官方主要更新维护的版本。
jQuery-xxx.js 与 jQuery-xxx.min.js区别:
1.Query-xxx.js:开发版本,给程序员看的,有良好的缩进和注释,体积大一些。
2.jQuery-xxx.min.js:生产版本,程序中使用的,没有缩进。体积小,程序运行快。
使用:
1.导入JQuery的js文件
2.代码
$(document).ready(funcation(){
//执行代码
});
在上面代码中我们看到jQuery语句主要包含$()、document、ready()中分别为工厂函数、选择器和方法类似于下面
window.onload=funcation(){
//执行代码
}
工厂函数$() (入口函数)
在jQuery中’ ′ 等 价 于 j Q u e r y , 即 '等价于jQuery,即 ′等价于jQuery,即()=jQuery,起作用就是将DOM对象转换为jQuery对象,只有转换完才能使用jQuery中的方法。
jQuery与JavaScript的互相转换:
//DOM转为jQuery对象
/**
对于一个DOM对象,只需要用$()把DOM对象包装起来,就可以获得一个jQuery对象
*/
var hello = document.getElementById("hello");
$(hello).css("color","#fff");
//jQuery转DOM对象
/**
方法一:jQuery对像是一个数组对象可以通过[index]的方法得到对应的DOM对象
*/
($(hello)[0]).innertHTML="sss"
/**
方法二:使用jQuery中的get(index)方法得到相应的DOM对象。
*/
($(hello).get(0)).innerHTML="sss"
/**
两者相互转换
* jq -- > js : jq对象[索引] 或者 jq对象.get(索引)
* js -- > jq : $(js对象)
*/
选择器
选择器:筛选具有相似特征的元素(标签、ID、类等)
基本操作:
事件绑定
//获取b1按钮
$("#b1").click(funcation(){
alert
})
入口函数:
$(function(){
})
window.onload和 ( f u n c a t i o n ) 区 别 : 1. w i n d o w . o n l o a d 只 能 定 义 一 次 , 如 果 定 义 多 次 , 后 边 会 将 前 边 的 覆 盖 掉 2. (funcation)区别: 1.window.onload只能定义一次,如果定义多次,后边会将前边的覆盖掉 2. (funcation)区别:1.window.onload只能定义一次,如果定义多次,后边会将前边的覆盖掉2.(funcation)可以定义多次的
选择器分类
基本选择器
层次选择器
属性选择器
过滤选择器
方法
DOM操作:
1.内容操作:
html():获取/设置元素的标签体内容
text():获取/设置元素的标签体纯文本内容
val():获取/设置元素的value属性值
<body>
<input id="myinput" type="text" name="username" value="张三" /><br />
<div id="mydiv"><p><a href="#">标题标签</a></p></div>
</body>
<script>
$(function () {
//获取myinput 的value值
var value = $("#myinput").val();
alert(value);
$("#myinput").val("李四");
//获取mydiv的标签体内容
var html = $("#mydiv").html();
alert(html);
$("#mydiv").html("<p>aaaa</p>");
//获取mydiv文本内容
var text = $("#mydiv").text();
alert(text);
$("#mydiv").text("bbb");
});
</script>
2.属性操作:
通用属性操作:
attr():获取/设置元素的属性
removeAttr():删除属性
prop():获取/设置元素的属性
removeProp():删除属性
attr 和 prop的区别:
1.如果操作的是元素的固有属性,则建议使用prop
2.如果操作的是元素的自定义属性,则建议使用attr
<style type="text/css">
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div.mini{
width: 30px;
height: 30px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<body>
<ul>
<li id="bj" name="beijing" xxx="yyy">北京</li>
<li id="tj" name="tianjin">天津</li>
</ul>
<input type="checkbox" id="hobby"/>
</body>
<script type="text/javascript">
$(function () {
//获取北京节点的name属性值
var name = $("#bj").attr("name");
//alert(name);
//设置北京节点的name属性的值为dabeijing
$("#bj").attr("name","dabeijing");
//新增北京节点的discription属性 属性值是didu
$("#bj").attr("discription","didu");
//删除北京节点的name属性并检验name属性是否存在
$("#bj").removeAttr("name");
//获得hobby的的选中状态
var checked = $("#hobby").prop("checked");
alert(checked);
});
</script>
对class属性操作
addClass():添加class属性值
removeClass():删除calss属性值
toggleClass():切换class属性值
toggleClass(“one”):判断元素对象上存在"class=one",则删除属性值one,如果不存在则添加one属性值
css():添加cass属性键值
3.CRUD操作:
<style type="text/css">
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 30px;
height: 30px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<body>
<input type="button" value="将反恐放置到city的后面" id="b1"/>
<input type="button" value="将反恐放置到city的最前面" id="b2"/>
<input type="button" value="将反恐插入到天津后面" id="b3"/>
<input type="button" value="将反恐插入到天津前面" id="b4"/>
<ul id="city">
<li id="bj" name="beijing">北京</li>
<li id="tj" name="tianjin">天津</li>
<li id="cq" name="chongqing">重庆</li>
</ul>
<ul id="love">
<li id="fk" name="fankong">反恐</li>
<li id="xj" name="xingji">星际</li>
</ul>
<div id="foo1">Hello1</div>
</body>
<script type="text/javascript">
$(function () {
// <input type="button" value="将反恐放置到city的后面" id="b1"/>
$("#b1").click(function () {
//append
//$("#city").append($("#fk"));
//appendTo
$("#fk").appendTo($("#city"));
});
// <input type="button" value="将反恐放置到city的最前面" id="b2"/>
$("#b2").click(function () {
//prepend
//$("#city").prepend($("#fk"));
//prependTo
$("#fk").prependTo($("#city"));
});
// <input type="button" value="将反恐插入到天津后面" id="b3"/>
$("#b3").click(function () {
//after
//$("#tj").after($("#fk"));
//insertAfter
$("#fk").insertAfter($("#tj"));
});
// <input type="button" value="将反恐插入到天津前面" id="b4"/>
$("#b4").click(function () {
//before
//$("#tj").before($("#fk"));
//insertBefore
$("#fk").insertBefore($("#tj"));
});
});
</script>
<style type="text/css">
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div.mini{
width: 30px;
height: 30px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<body>
<input type="button" value="删除<li id='bj' name='beijing'>北京</li>" id="b1"/>
<input type="button" value="删除所有的子节点 清空元素中的所有后代节点(不包含属性节点)" id="b2"/>
<ul id="city">
<li id="bj" name="beijing">北京</li>
<li id="tj" name="tianjin">天津</li>
<li id="cq" name="chongqing">重庆</li>
</ul>
<p class="hello">Hello</p> how are <p>you?</p>
</body>
<script type="text/javascript">
$(function () {
// <input type="button" value="删除<li id='bj' name='beijing'>北京</li>" id="b1"/>
$("#b1").click(function () {
$("#bj").remove();
});
// <input type="button" value="删除city所有的li节点 清空元素中的所有后代节点(不包含属性节点)" id="b2"/>
$("#b2").click(function () {
$("#city").empty();
});
});
</script>
4.动画
<body>
<input type="button" value="点击按钮隐藏div" onclick="hideFn()">
<input type="button" value="点击按钮显示div" onclick="showFn()">
<input type="button" value="点击按钮切换div显示和隐藏" onclick="toggleFn()">
<div id="showDiv" style="width:300px;height:300px;background:pink">
div显示和隐藏
</div>
</body>
<script>
//隐藏div
function hideFn(){
/* $("#showDiv").hide("slow","swing",function(){
alert("隐藏了...")
});*/
/*
//默认方式
$("#showDiv").hide(5000,"swing");
*/
/*
//滑动方式
$("#showDiv").slideUp("slow");
*/
//淡入淡出方式
$("#showDiv").fadeOut("slow");
}
//显示div
function showFn(){
/*$("#showDiv").show("slow","swing",function(){
alert("显示了...")
});*/
/*
//默认方式
$("#showDiv").show(5000,"linear");
*/
/*
//滑动方式
$("#showDiv").slideDown("slow");
*/
//淡入淡出方式
$("#showDiv").fadeIn("slow");
}
//切换显示和隐藏div
function toggleFn(){
/*
//默认方式
$("#showDiv").toggle("slow");
*/
/*
//滑动方式
$("#showDiv").slideToggle("slow");
*/
//淡入淡出方式
$("#showDiv").fadeToggle("slow");
}
</script>
5.遍历
<body>
<ul id="city">
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
</body>
<script type="text/javascript">
/*
遍历
1. js的遍历方式
* for(初始化值;循环结束条件;步长)
2. jq的遍历方式
1. jq对象.each(callback)
2. $.each(object, [callback])
3. for..of:jquery 3.0 版本之后提供的方式
*/
$(function () {
//1.获取所有的ul下的li
var citys = $("#city li");
/* //2.遍历li
for (var i = 0; i < citys.length; i++) {
if("上海" == citys[i].innerHTML){
//break; 结束循环
//continue; //结束本次循环,继续下次循环
}
//获取内容
alert(i+":"+citys[i].innerHTML);
}*/
/*
//2. jq对象.each(callback)
citys.each(function (index,element) {
//3.1 获取li对象 第一种方式 this
//alert(this.innerHTML);
//alert($(this).html());
//3.2 获取li对象 第二种方式 在回调函数中定义参数 index(索引) element(元素对象)
//alert(index+":"+element.innerHTML);
//alert(index+":"+$(element).html());
//判断如果是上海,则结束循环
if("上海" == $(element).html()){
//如果当前function返回为false,则结束循环(break)。
//如果返回为true,则结束本次循环,继续下次循环(continue)
return true;
}
alert(index+":"+$(element).html());
});*/
//3 $.each(object, [callback])
/* $.each(citys,function () {
alert($(this).html());
});*/
//4. for ... of:jquery 3.0 版本之后提供的方式
for(li of citys){
alert($(li).html());
}
});
</script>
6.事件绑定
绑定事件
<body>
<input id="btn" type="button" value="使用on绑定点击事件">
<input id="btn2" type="button" value="使用off解绑点击事件">
</body>
<script type="text/javascript">
$(function () {
//1.使用on给按钮绑定单击事件 click
$("#btn").on("click",function () {
alert("我被点击了。。。")
}) ;
//2. 使用off解除btn按钮的单击事件
$("#btn2").click(function () {
//解除btn按钮的单击事件
//$("#btn").off("click");
$("#btn").off();//将组件上的所有事件全部解绑
});
});
</script>
事件切换
<body>
<input id="btn" type="button" value="事件切换">
<div id="myDiv" style="width:300px;height:300px;background:pink">
点击按钮变成绿色,再次点击红色
</div>
</body>
<script type="text/javascript">
$(function () {
//获取按钮,调用toggle方法
$("#btn").toggle(function () {
//改变div背景色backgroundColor 颜色为 green
$("#myDiv").css("backgroundColor","green");
},function () {
//改变div背景色backgroundColor 颜色为 pink
$("#myDiv").css("backgroundColor","pink");
});
});
</script>
三、BootStrap
3.1概念
一个前端开发的框架,Bootstrap,来自twitter,是目前很受欢迎的前端框架。Bootstrap是基于HTML、CSS、JavaScript的,它简洁灵活,使得WEB开发更加快捷
3.2快速入门
下载bootstrap: https://v3.bootcss.com/getting-started/#download
创建HTML页面,引入必要的资源文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<h1>你好,世界!</h1>
</body>
</html>
3.3响应式布局
概念:同一套页面可以兼容不同分辨率的设备
实现:依赖于栅格系统:将一行平均分成12个格子,可以指定元素占几个格子
步骤:
1.定义容器。(相当于table)
容器分类:
1.container:两边留白
2.container-fluid:每一种设备都是100%宽度
2.定义行。(相当于tr,样式row)
3.定义元素。指定该元素在不同设备上,所占的各自数目。样式:col-设备代号-各自数目
设备代号:
1.xs:超小屏幕 手机(<768px):col-xs-12
2.sm:小屏幕 平板(>=768px)
3.md:中等屏幕 桌面显示器(>=992px)
4.lg:大屏幕 大桌面显示器(>=1200px)
注意:
1.一行中如果各自数目超过12,则超出部分自动换行
2.栅格类属性可以向上兼容。栅格类适用于与屏幕宽度大于或等于分界点大小的设备
3.如果真是设备宽度小于了设置栅格类属性的设备代码的最小值,会一个元素占满一整行
栅格系统
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
<style>
.inner{
border:1px solid red;
}
</style>
</head>
<body>
<!--1.定义容器-->
<div class="container">
<!--2.定义行-->
<div class="row">
<!--3.定义元素
在大显示器一行12个格子
在pad上一行6个格子
-->
<!--<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>
<div class="col-lg-1 col-sm-2 inner">栅格</div>-->
<div class="col-md-4 inner">栅格</div>
<div class="col-md-4 inner">栅格</div>
<div class="col-md-4 inner">栅格</div>
</div>
</div>
</body>
</html>
3.4 CSS样式和JavaScript插件
按钮:class=“btn btn-default”
图片:class=“img-responsive”
图片形状:class=“img-circle”
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
<style>
</style>
</head>
<body>
<a class="btn btn-default" href="#" >Link</a>
<button class="btn btn-default" type="submit">Button</button>
<input class="btn btn-default" type="button" value="Input">
<input class="btn btn-default" type="submit" value="Submit">
<br>
<!-- Provides extra visual weight and identifies the primary action in a set of buttons -->
<button type="button" class="btn btn-primary">(首选项)Primary</button>
<!-- Indicates a successful or positive action -->
<button type="button" class="btn btn-success">(成功)Success</button>
<!-- Contextual button for informational alert messages -->
<button type="button" class="btn btn-info">(一般信息)Info</button>
<!-- Indicates caution should be taken with this action -->
<button type="button" class="btn btn-warning">(警告)Warning</button>
<!-- Indicates a dangerous or potentially negative action -->
<button type="button" class="btn btn-danger">(危险)Danger</button>
<!-- Deemphasize a button by making it look like a link while maintaining button behavior -->
<button type="button" class="btn btn-link">(链接)Link</button>
<hr>
<img src="img/banner_1.jpg" class="img-responsive"/>
<img src="img/banner_1.jpg" class="img-responsive img-rounded" />
<img src="img/banner_1.jpg" class="img-responsive img-circle"/>
<img src="img/banner_1.jpg" class="img-responsive img-thumbnail"/>
</body>
</html>
表格:table table-bordered table-hover
表单:class=“form-control”
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
<style>
</style>
</head>
<body>
<table class="table table-bordered table-hover">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<tr>
<td>001</td>
<td>张三</td>
<td>23</td>
</tr>
<tr>
<td>002</td>
<td>张三</td>
<td>23</td>
</tr>
<tr>
<td>003</td>
<td>张三</td>
<td>23</td>
</tr>
</table>
<hr><hr><hr>
<form class="form-horizontal">
<div class="form-group">
<label for="exampleInputEmail1" class="col-sm-2 control-label">Email address</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</form>
</body>
</html>
组件:
导航栏
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<!-- 定义汉堡按钮 -->
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">首页</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</body>
</html>
分页条
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<nav aria-label="Page navigation">
<ul class="pagination">
<li class="disabled">
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li class="active"><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</body>
</html>
插件:轮播图
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
<li data-target="#carousel-example-generic" data-slide-to="3"></li>
<li data-target="#carousel-example-generic" data-slide-to="4"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="img/banner_1.jpg" alt="...">
</div>
<div class="item">
<img src="img/banner_2.jpg" alt="...">
</div>
<div class="item">
<img src="img/banner_3.jpg" alt="...">
</div>
<div class="item">
<img src="img/banner_3.jpg" alt="...">
</div>
<div class="item">
<img src="img/banner_3.jpg" alt="...">
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</body>
</html>
四、Node.js
4.1概念
JavaScript引擎:
1.DOM渲染引擎
2.JavaScript解析引擎
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- Dom渲染引擎会将html元素渲染成相应的表现形式 -->
<h1>Hello Node.js</h1>
<!-- JavaScript解析引擎会在浏览器中解析并执行JavaScript代码 -->
<script>
alert('hello Node.js')
</script>
</body>
</html>
Node.js
脱离浏览器也可以运行JavaScript,只要有JavaScript引擎就可以。Node.js内置了Chrome的V8引擎,可以在Node.js环境中直接运行JavaScript程序。Node.js没有浏览器API,即document、window等,增加了许多Node.js专属API,例如:文件系统、进程、http功能
下载:
官网: https://nodejs.org/en/
中文网: http://nodejs.cn/
查看版本,检查是否安装成功
node -v
4.2Node.js程序
创建一个名为01-hello-node.js的文件
console.log("hello node")
使用cmd进入到程序所在目录,输入:
node 01-hello-node.js
常见问题:
如果安装Node.js之前已经打开VS Code,则会看到如下错误,重启VS就能解决问题
4.2.1 文件读取
//引入Node.js文件系统模块
//fs是node.js自带的模块,使用node.js中的关键字require将模块引入,使用const定义模块常量
const fs = require("fs");//文件系统模块
//调用readFill方法读取磁盘文件:异步操作
fs.readFile("./read.txt", function (err, data) {
//当读取失败时,可以获得错误信息,输出错误信息
if (err) throw err;
//当读取成功时,可以获取data的值,输出响应的内容
console.log(data.toString());
})
console.log("读取文件");
4.2.2服务器端程序
//引入Node.js的http模块:
const http = require('http')
//调用createServer创建服务器
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, { 'Content-Type': 'text/html' })
// 发送响应数据 "Hello World"
response.end('<h1>Hello Node.js Server</h1>')
}).listen(8888) //调用listen方法在8888端口监听客户端请求
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/')
4.3 Node.js的作用
4.3.1Node.js的应用场景
如果你是一个前端程序员,想开发类似JavaWeb的简单后端程序,那么Node.js是一个非常好的选择。
如果你是一个架构师,想部署一些高性能的服务,那么Node.js也是一个非常好的选择。
通常它会被用来作一个BFF层,即Backend For Frontend (服务于前端的后端),通俗的说就是一个专门用于为前端业务提供数据的后端程序。
4.3.2BFF解决什么问题
一个前端页面向服务A和服务B发送请求,不同的微服务返回的值用于渲染页面中不同的组件。此时,所有的数据在PC端浏览器渲染。
我们可以使用一个BFF层提前将页面渲染好,发送给浏览器,那么BFF层提前将多个服务的数据聚合起来。
五、ECMAScript 6
5.1介绍
1、ECMA
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际。
2、ECMAScript
ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。
3、什么是ECMA-262
Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个
4、ECMA-262 历史
ECMA-262(ECMAScript)历史版本查看网址
http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm
5、ECMAScript 和 JavaScript 的关系
要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。 因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)
5.2基本语法
ES6相对之前的版本语法更严格,新增了面向对象的很多特性以及一些高级特性。本部分只学习项目开发中涉及到ES6的最少必要知识,方便项目开发中对代码的理解。
5.2.1let声明变量
//声明变量
let a
let b,c,d
let e = 100
let f = 521, g = 'iloveyou', h = []
//1. 变量不能重复声明
let name = 'Helen'
let name = '环'//报错:SyntaxError: Identifier 'name' has already been declared
//2. 存在块儿级作用域
// if else while for
{
let star = 5
}
console.log(star)//报错:star is not defined
//3. 不存在变量提升
console.log(song)//报错:Cannot access 'song' before initialization
let song = '依然爱你';
5.2.2const声明常量
//声明常量
const SCHOOL = '尚硅谷'
console.log(SCHOOL)
//1. 一定要赋初始值
const A//报错:SyntaxError: Missing initializer in const declaration
//2. 一般常量使用大写(潜规则)
const a = 100
//3. 常量的值不能修改
SCHOOL = 'ATGUIGU'//报错:TypeError: Assignment to constant variable.
console.log(PLAYER)//报错:ReferenceError: PLAYER is not defined
//4. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
const TEAM = ['康师傅','海狗人参丸','雷神','阳哥']
TEAM.push('环') //常量地址不变,不会报错
TEAM = 100 //报错:TypeError: Assignment to constant variable.
5.2.3结构赋值
//ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,
//这被称为解构赋值。
//1. 数组的解构
const F4 = ['小沈阳','刘能','赵四','宋小宝']
let [xiao, liu, zhao, song] = F4
console.log(xiao)
console.log(liu)
console.log(zhao)
console.log(song)
//2. 对象的解构
const zbs = {
username: '赵本山',
age: '不详',
xiaopin: function(){
console.log("演小品");
}
}
let {username, age, xiaopin} = zbs
console.log(username)
console.log(age)
console.log(xiaopin)
xiaopin()
//3. 根据名字自动解构
// let {xiaopin} = zbs
// xiaopin()
5.2.4模板字符串
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
// ES6 引入新的声明字符串的方式 『``』 '' ""
//1. 声明
let str = `我也是一个字符串哦!`
console.log(str, typeof str)
//2. 内容中可以直接出现换行符
let list = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`
console.log(list)
//3. 变量拼接
let hello = 'javascript'
let out = `hello ${hello}`
console.log(out)
5.2.5声明对象简写
let username = 'Tom'
let age = 2
let sing = function () {
console.log('I love Jerry')
}
// 传统
let person1 = {
username: username,
age: age,
sing: sing,
}
console.log(person1)
person1.sing()
// ES6:这样的书写更加简洁
let person2 = {
age,
username,
sing,
}
console.log(person2)
person2.sing()
5.2.6定义方法简写
// 传统
let person1 = {
sayHi: function () {
console.log('Hi')
},
}
person1.sayHi()
// ES6
let person2 = {
sayHi() {
console.log('Hi')
},
}
person2.sayHi()
5.2.7参数的默认值
注:函数在JavaScript中也是一种数据类型,JavaScript中没有方法的重载
//ES6 允许给函数参数赋值初始值
//1. 形参初始值 具有默认值的参数
function add(a, b, c = 0) {
return a + b + c
}
let result = add(1, 2)
console.log(result)
//2. 与解构赋值结合
function connect({ host = '127.0.0.1', username, password, port }) {
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306,
})
5.2.8对象拓展运算符
扩展运算符 (spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
//展开对象(拷贝对象)
let person = { name: '路飞', age: 17 }
// let someone = person //引用赋值
let someone = { ...person } //对拷拷贝
someone.name = '索隆'
console.log(person)
console.log(someone)
5.2.9箭头函数
箭头函数提供了一种更加简洁的函数书写方式。基本语法是:
参数=>函数体
箭头函数多用于匿名函数的定义
//声明一个函数
let fn = function(a){
return a + 100
}
//箭头函数
let fn = (a) => {
return a + 100
}
//简写
let fn = a => a + 100
//调用函数
let result = fn(1)
console.log(result)
5.2.10Promise
Promise 是ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。
const fs = require('fs')
//实例化 Promise 对象:
//Promise对象有三个状态:初始化、成功、失败
const p = new Promise((resolve, reject) => {
//调用readFile方法读取磁盘文件:异步操作
fs.readFile('./他.txt', (err, data) => {
//当文件读取失败时,可以获取到err的值
if (err) reject(err) //reject将Promise对象的状态设置为失败
//当文件读取成功时,可以获取到data的值
resolve(data) //resolve将Promise对象的状态设置为成功
})
})
//调用 promise 对象的方法
//then:当 Promise状态成功时执行
//catch:当 Promise状态失败时执行
p.then(response => {
console.log(response.toString())
}).catch(error => {
console.log('出错了')
console.error(error)
})
总结:借助于Promise,可以使异步操作中的成功和失败的处理函数独立出来。
六、AXIOS
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KKZUujXE-1642434485813)(axios.png)]
6.1入门
axios的作用
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
官方网站:http://www.axios-js.com
6.1.1axios案例
step1: mybatis-plus中添加后端接口(可以看之前的文章)
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
controller :
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@GetMapping("/list")
public List<User> list(){
return userService.list();
}
}
启动项目
访问: http://localhost:8080/user/list
创建index.html文件
导入axios.js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="axios.js"></script>
<script>
//基于promise
axios({
method: 'get',
url: 'http://localhost:8080/user/list',
})
.then((response) => {
console.log('获取数据成功', response)
})
.catch((error) => {
console.log('获取数据失败', error)
})
//另一种写法
axios
.get('http://localhost:8080/user/list')
.then((response) => {
console.log('获取数据成功1', response)
})
.catch((error) => {
console.log('获取数据失败1', error)
})
</script>
</body>
</html>
6.2跨域
6.2.1为什么会产生跨域问题
出于浏览器的同源策略限制。
所谓同源(即指在同一个域)就是两个地址具有相同的协议(protocol)、主机(host)和端口号(port)以下情况都属于跨域:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CQMnPmT1-1642434485815)(跨域.png)]
http和https也属于跨域。
如果域名和端口都相同,但是请求路径不同,不属于跨域,如:www.jd.com/item 和 www.jd.com/goods
同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。
而我们刚才是从localhost:5500端口去访问localhost:8080端口,这属于端口不同,跨域了。
6.2.2解决跨域问题
Spring早就给我们提供了解决方案,我们只需要在对应controller上添加一个注解就可以了,我们在 UserController 类上添加跨域标签@CrossOrigin,再进行测试,则测试成功!
@CrossOrigin //解决跨域问题
6.3自定义配置
6.3.1配置axios示例
可以对axios进行配置,简化代码的编写
//使用自定义配置
const request = axios.create({
baseURL: 'http://localhost:8080', //url前缀
timeout: 1000, //超时时间
headers: {'token': 'helen123456'} //携带令牌
})
6.3.2配置请求参数
这样,远程接口的url地址就可以修改成相对路径了
//基于promise
//注意:这里使用了前面定义的request
request({
method:'get',
url:'/user/list'
}).then(response => {
console.log('获取数据成功', response)
}).catch(error => {
console.log('获取数据失败', error)
})
6.4拦截器
在请求或响应被then或catch处理前拦截它们
6.4.1请求拦截器
在发送axios请求前,可以拦截请求,对请求做一些处理
// 请求拦截器
request.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么,例如:在请求头中携带一个令牌
config.headers.token = 'helen123456'
return config
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error)
}
)
发送请求时,在请求头中会携带这个token
6.4.2响应拦截器
在发完请求,获取响应后,可以对响应做一些处理,在返回非前端用户
// 添加响应拦截器
request.interceptors.response.use(
function (response) {
// 对响应数据做点什么,例如:使用response.data替代response,简化前端拿到的数据结果
return response.data
},
function (error) {
// 对响应错误做点什么
return Promise.reject(error)
}
)
七、模块化
7.1产生背景
创建a.js
var star='lisi'
创建b.js
var star=18
创建demo.html
从这个例子可以看出,star的值不确定性很大,a和b两个脚本文件中的同名变量互相干扰
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="a.js"></script>
<script src="b.js"></script>
<script>
console.log(star)
</script>
</body>
</html>
7.1.1模块化解决的问题
模块化主要解决JavaScript程序中全局空间内被污染的问题
7.1.2模块化规范
CommonJS模块化规范(基于ES6语法之前)
例如:node.js中的require引入模块,exprots导出模块
ES6模块化规范(使用ES6语法)
export导出模块 import导出模块
7.2ES6模块化规范
7.2.1导出模块
创建m1.js
export let star = 'lisi';
export function sing(){
console.log('hello javascript')
}
还可以这样导出
let star = '王力宏';
function sing(){
console.log('大城小爱')
}
export {star, sing}
创建m2.js
export let star = 18
7.2.2导入模块
创建demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import * as m1 from './m1.js'
import * as m2 from './m2.js'
console.log(m1)
console.log(m2)
console.log(m1.star)
console.log(m2.star)
//还可以这样导入:解构赋值的形式
import {star, sing} from './m1.js'
import {star as star2} from './m2.js' //使用as防止重名
console.log(star)
sing()
console.log(star2)
</script>
</body>
</html>
运行html文件测试
7.3默认暴露模块
7.3.1默认暴露
创建m3.js
//可以导出任意类型,但同时只能有一个export default
// export default 'helen'
// export default 99
//大部分情况是导出对象
export default{
username: 'helen',
age: 20,
coding(){
console.log('hello world')
}
}
7.3.2导入模块
在demo.html中导入模块
//导入m3
import m3 from './m3.js'
console.log(m3)
运行html文件测试
7.4封装代码
7.4.1创建app.js
可以看作是程序的入口文件
import * as m1 from './m1.js'
import * as m2 from './m2.js'
import m3 from './m3.js'
console.log(m1)
console.log(m2)
console.log(m3)
7.4.2引入入口文件
创建demo-app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="app.js" type="module"></script>
</body>
</html>
运行测试文件
八、Vue.js
8.1 Vue.js
8.1.1Vue.js基本认识
1、官网:
英文官网:https://vuejs.org
中文官网:https://cn.vuejs.org
2、简介
渐进式JavaScript 框架(核心 + 扩展)
作者:尤雨溪(一位华裔前 Google 工程师)
作用:动态构建用户界面
3、优点
体积小:压缩后33K
更高的运行效率:基于虚拟dom
双向数据绑定:不操作dom,关注业务逻辑
生态丰富、学习成本低:入门容易,学习资料多
8.1.2第一个Vue应用
1、引入脚本库
创建html文件
<script src="vue.js"></script>
2、数据绑定
<body>
<!-- id标识vue作用的范围,绑定的数据必须写在这个div内部 -->
<div id="app">
<!-- {{}} 插值表达式,声明式渲染,绑定vue中的data数据 -->
{{ message }}
</div>
<script src="vue.js"></script>
<script>
// 创建一个vue对象
// Vue构造函数的参数是一个配置对象,对象中的key是一些固定的关键字
new Vue({
el: '#app', //绑定vue作用的范围,用id选择器选中div
data: {
//在data中注册变量,用于视图中的数据绑定
message: 'Hello Vue!',
}
})
</script>
</body>
这就是声明式渲染:Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统
data: {
message: 'Hello Vue!'
}
也可以写成:
data() {
return {
message: 'Hello Vue!'
}
}
8.1.3数据绑定指令
1、数据绑定指令
创建html文件,引入脚本,创建Vue对象
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
company: '尚硅谷',
site: 'http://www.atguigu.com'
}
})
</script>
使用数据绑定指令做数据渲染
<div id="app">
<a v-bind:href="site" target="_blank">{{company}}</a>
<input type="text" v-bind:value="company">
</div>
v-bind指令的简写形式
<!-- v-bind: 指令的简写形式 : -->
<a :href="site" target="_blank">{{company}}</a>
<input type="text" :value="company">
2、双向数据绑定指令
创建html文件,赋值1的html代码,将v-bind改为v-model
<!-- v-bind:value 单向数据绑定 -->
<input type="text" v-bind:value="company">
<!-- v-model 双向数据绑定 -->
<input type="text" v-model="company">
什么时双向数据绑定
1、当数据发生变化时,视图也跟着发生变化
数据模型发生了改变,会直接显示在页面上
2、当时图发生变化时侯,数据也会跟着同步变化
用户在页面上的修改,会自动同步到数据模型中去
注:v-model只用于用户交互组件中
8.1.4理解MVVM
1、安装Vue.js devtools
使用Edge在线安装,别问为什么不是Chrome…
2、MVVM
8.1.5绑定事件监听
创建html文件,使用 v-on 进行事件绑定,v-on:click 表示处理鼠标点击事件,事件调用的方法定义在 vue 对象声明的 methods 节点中
<body>
<div id="app">
<button v-on:click="study">去学习</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
company: '尚硅谷'
},
methods: {
study(){
alert('我要去' + this.company + '学习')
}
}
})
</script>
</body>
v-on指令的简写形式
<!-- v-on: 指令的简写形式 @ -->
<button @click="study">去学习</button>s
8.1.6计算属性
创建html文件
1、模板中使用js表达式
<body>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'hello',
},
})
</script>
</body>
模板表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会难以维护。
<div id="app">
<p>原始值: {{ message }}</p>
<!-- 1、插值数据绑定中使用表达式 -->
<p>反转消息: {{ message.split('').reverse().join('') }}</p>
</div>
所以,对于任何复杂逻辑,你都应当使用计算属性
2、使用计算属性
computed: {
reversedMessage () {
console.log('计算属性执行')
return this.message.split('').reverse().join('')
}
}
<!-- 2、使用计算属性 -->
<p>反转消息: {{ reversedMessage }}</p>
3、使用方法
methods:{
reversed () {
console.log('方法执行')
return this.message.split('').reverse().join('')
}
}
<!-- 3、使用方法 -->
<p>反转消息: {{ reversed() }}</p>
计算属性缓存 vs 方法
看起来计算属性和方法完全相同的功能,那么它们有什么区别
1.计算属性基于缓存
2.方法将总会再次执行
<!-- 2、使用计算属性 -->
<p>反转消息: {{ reversedMessage }}</p>
<!-- 调用两次只执行一次属性的计算 -->
<p>反转消息: {{ reversedMessage }}</p>
<!-- 3、使用方法 -->
<p>反转消息: {{ reversed() }}</p>
<!-- 调用两次执行了两次属性的计算 -->
<p>反转消息: {{ reversed() }}</p>
案例:计算属性的单向和双向绑定
<body>
<div id="app">
姓: <input placeholder="First Name" v-model="firstName" /><br />
名: <input placeholder="Last Name" v-model="lastName" /><br />
姓名1(单向): <input placeholder="Full Name1" v-model="fullName1" /><br />
姓名2(双向): <input placeholder="Full Name2" v-model="fullName2" /><br />
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
firstName: 'Helen',
lastName: 'Yao',
// fullName: 'Helen Yao',
},
computed: {
fullName1() {
console.log('计算fullName1')
return this.firstName + ' ' + this.lastName
},
fullName2: {
get() {
console.log('计算fullName2')
return this.firstName + ' ' + this.lastName
},
//当给fullName2指定新值时自动调用:实现双向绑定
set(value) {
console.log('fullName2 的 setter')
const names = value.split(' ')
this.firstName = names[0]
this.lastName = names[1]
},
},
},
})
</script>
</body>
8.1.7监听
创建html文件
<body>
<div id="app">
姓: <input placeholder="First Name" v-model="firstName" /><br />
名: <input placeholder="Last Name" v-model="lastName" /><br />
姓名: <input placeholder="Full Name" v-model="fullName" /><br />
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
firstName: 'Helen',
lastName: 'Yao',
// fullName: 'Helen Yao',
},
watch: {
//当firstName改变时自动调用
firstName(value) {
console.log('watch firstName')
this.fullName = value + ' ' + this.lastName
console.log(this.fullName)
},
//当lastName改变时自动调用
lastName(value) {
console.log('watch lastName')
this.fullName = this.firstName + ' ' + value
}
},
})
</script>
</body>
8.1.8条件渲染
创建html文件
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
ok: false
}
})
</script>
点击复选框,显示或隐藏协议内容。分别使用v-if和v-show实现
<div id="app">
<input type="checkbox" v-model="ok" />同意许可协议
<!-- v:if条件指令:还有v-else、v-else-if 切换开销大 -->
<p v-if="ok">yes.</p>
<p v-else>no.</p>
<!-- v:show 条件指令 初始渲染开销大 -->
<p v-show="ok">yes.</p>
<p v-show="!ok">no.</p>
</div>
8.1.9列表渲染
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
userList: [
{ username: 'helen', age: 18 },
{ username: 'peter', age: 28 }
]
}
})
</script>
v-for:列表循环指令
<div id="app">
<ul>
<!-- item:当前元素,index:当前元素的索引 -->
<li v-for="(item, index) in userList">
{{index}} {{item.username}} {{item.age}}
</li>
</ul>
</div>
8.1.10实例生命周期
创建html文件
<div id="app">
<h3 id="h3">{{ message }}</h3>
</div>
分析生命周期相关方法的执行时机
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
message: '床前明月光'
},
// 页面在内存中已经初始化完毕:
// 可以操作 data 中的数据、调用methods中的方法
// 但是数据尚未被渲染到页面中:用户看不见
created() {
console.log('created')
//可以操作 data 中的数据
console.log(this.message)
//可以调用methods中的方法
this.show()
//无法取出dom节点取数据,说明用户无法在浏览器中看见这个内容
console.log(document.getElementById('h3').innerText)
},
// 数据已经被渲染到页面中
mounted() { // 第四个被执行的钩子方法
console.log('mounted')
//可以取出dom节点取数据,说明用户已经在浏览器中看见内容
console.log(document.getElementById('h3').innerText)
},
methods: {
show() {
console.log('show方法被调用')
}
},
})
</script>
8.1.11综合案例
<body>
<div id="app">
<table>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>email</th>
</tr>
<tr v-for="(item, index) in userList">
<td>{{index + 1}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.email}}</td>
</tr>
</table>
</div>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
userList: [],
}
},
created() {
this.showList()
},
methods: {
showList() {
//使用自定义配置
const request = axios.create({
baseURL: 'http://localhost:8080', //url前缀
timeout: 1000, //超时时间
headers: { token: 'helen123456' }, //携带令牌
})
// 请求拦截器
request.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么,例如:在请求头中携带一个令牌
config.headers.token = 'helen123456'
return config
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error)
}
)
// 添加响应拦截器
request.interceptors.response.use(
function (response) {
// 对响应数据做点什么,例如:使用response.data替代response,简化前端拿到的数据结果
return response.data
},
function (error) {
// 对响应错误做点什么
return Promise.reject(error)
}
)
//基于promise
request({
method: 'get',
url: '/user/list',
})
.then((response) => {
console.log('获取数据成功', response)
this.userList = response
})
.catch((error) => {
console.log('获取数据失败', error)
})
},
},
})
</script>
</body>
8.2 Vue UI
8.2.1常用组件库
1、Mint UI
主页:http://mint-ui.github.io/#!/zh-cn
说明:饿了么开源的基于Vue的移动端UI组件库
2、Element-UI
主页:http://element-cn.eleme.io/#/zh-CN
说明:饿了么开源的基于Vue的PC端UI组件库
8.2.1Element-UI实例
1、引入脚本库
复制8.1.11的综合案例
2、引入css和脚本
在html中引入css和js
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="vue.js"></script>
<script src="axios.js"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
3、渲染用户列表
<div id="app">
<el-button>默认按钮</el-button>
<el-table :data="userList" stripe border style="width: 100%">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" width="55" label="序号"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="email" label="email"></el-table-column>
</el-table>
</div>
8.3 Vue Router
8.3.1认识路由
1、锚点的概念
案例:百度百科
特点:单页Web应用,预先加载页面内容
形式:url#锚点
2、路由的作用
Vue.js 路由允许我们通过锚点定义不同的 URL, 达到访问不同的页面的目的,每个页面的内容通过延迟加载渲染出来。
通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)
3、参考 https://router.vuejs.org/zh/
8.3.2路由实例
1、创建html文件
2、复制js资源 vue.js vue-router.js
3、引入js
<script src="vue.js"></script>
<script src="vue-router.js"></script>
4、编写html
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<!-- 通过传入 `to` 属性指定链接. -->
<router-link to="/">首页</router-link>
<router-link to="/invest">我要投资</router-link>
<router-link to="/user">用户中心</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
5、编写JS
<script>
// 1. 定义(路由)组件。
// 复杂的组件也可以从独立的vue文件中引入
const welcome = { template: '<div>尚融宝主页</div>' }
const invest = { template: '<div>投资产品</div>' }
const user = { template: '<div>用户信息</div>' }
// 2. 定义路由
// 每个路由应该映射一个组件。
const routes = [
{ path: '/', redirect: '/welcome' }, //设置默认指向的路径
{ path: '/welcome', component: welcome },
{ path: '/invest', component: invest },
{ path: '/user', component: user },
]
// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
routes, // (缩写)相当于 routes: routes
})
// 4. 创建和挂载根实例。
// 从而让整个应用都有路由功能
new Vue({
el: '#app',
router,
})
// 现在,应用已经启动了!
</script>
例
1、引入脚本库
复制8.1.11的综合案例
2、引入css和脚本
在html中引入css和js
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="vue.js"></script>
<script src="axios.js"></script>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
3、渲染用户列表
<div id="app">
<el-button>默认按钮</el-button>
<el-table :data="userList" stripe border style="width: 100%">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column type="index" width="55" label="序号"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="email" label="email"></el-table-column>
</el-table>
</div>
8.3 Vue Router
8.3.1认识路由
1、锚点的概念
案例:百度百科
特点:单页Web应用,预先加载页面内容
形式:url#锚点
2、路由的作用
Vue.js 路由允许我们通过锚点定义不同的 URL, 达到访问不同的页面的目的,每个页面的内容通过延迟加载渲染出来。
通过 Vue.js 可以实现多视图的单页Web应用(single page web application,SPA)
3、参考 https://router.vuejs.org/zh/
8.3.2路由实例
1、创建html文件
2、复制js资源 vue.js vue-router.js
3、引入js
<script src="vue.js"></script>
<script src="vue-router.js"></script>
4、编写html
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<!-- 通过传入 `to` 属性指定链接. -->
<router-link to="/">首页</router-link>
<router-link to="/invest">我要投资</router-link>
<router-link to="/user">用户中心</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
5、编写JS
<script>
// 1. 定义(路由)组件。
// 复杂的组件也可以从独立的vue文件中引入
const welcome = { template: '<div>尚融宝主页</div>' }
const invest = { template: '<div>投资产品</div>' }
const user = { template: '<div>用户信息</div>' }
// 2. 定义路由
// 每个路由应该映射一个组件。
const routes = [
{ path: '/', redirect: '/welcome' }, //设置默认指向的路径
{ path: '/welcome', component: welcome },
{ path: '/invest', component: invest },
{ path: '/user', component: user },
]
// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
routes, // (缩写)相当于 routes: routes
})
// 4. 创建和挂载根实例。
// 从而让整个应用都有路由功能
new Vue({
el: '#app',
router,
})
// 现在,应用已经启动了!
</script>