UML类图几种关系的总结,泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregation),组合(Composition),依赖(Dependency)
泛化(Generalization)
【泛化关系】:是一种继承关系,表示一般与特殊的关系,它指定了子类如何特化父类的所有特征和行为。例如:老虎是动物的一种,即有老虎的特性也有动物的共性。
【箭头指向】:带三角箭头的实线,箭头指向父类
实现(Realization)
【实现关系】:在这里插入图片描述是一种类与接口的关系,表示类是接口所有特征和行为的实现.
【箭头指向】:带三角箭头的虚线,箭头指向接口
关联(Association)
【关联关系】:是一种拥有的关系,它使一个类知道另一个类的属性和方法;如:老师与学生,丈夫与妻子关联可以是双向的,也可以是单向的。双向的关联可以有两个箭头或者没有箭头,单向的关联有一个箭头。
【代码体现】:成员变量
【箭头及指向】:带普通箭头的实心线,指向被拥有者
上图中,老师与学生是双向关联,老师有多名学生,学生也可能有多名老师。但学生与某课程间的关系为单向关联,一名学生可能要上多门课程,课程是个抽象的东西他不拥有学生。
聚合(Aggregation)
【聚合关系】:是整体与部分的关系,且部分可以离开整体而单独存在。如车和轮胎是整体和部分的关系,轮胎离开车仍然可以存在。
聚合关系是关联关系的一种,是强的关联关系;关联和聚合在语法上无法区分,必须考察具体的逻辑关系。
【代码体现】:成员变量
【箭头及指向】:带空心菱形的实心线,菱形指向整体
小技巧:空心菱形表示聚合,好聚好散,所以生命周期可以不同。
组合(Composition)
【组合关系】:是整体与部分的关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系,没有公司就不存在部门。
组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。
【代码体现】:成员变量
【箭头及指向】:带实心菱形的实线,菱形指向整体
依赖(Dependency)
【依赖关系】:是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖.
【代码表现】:局部变量、方法的参数或者对静态方法的调用
【箭头及指向】:带箭头的虚线,指向被使用者
各种关系的强弱顺序:
泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
下面这张UML图,比较形象地展示了各种类图关系:
在这里主要是跟大家介绍一下在js中如何使用异常捕获机制,包括try,catch,finally与我们主动抛出异常throw的用法
使用异常捕获机制可以让我们在项目中对一些可能出错的地方作出一些预防措施,让我们能够更加快速精准的找出代码错误,
也能够让我们后面的代码不受前面的错误影响继续执行,话不多说,看代码,图解在下方。
<script>
console.log(1)
try {
console.log(2)
console.log(num) // 出错,那么try块级语句出错地方后面的代码都不会执行
console.log(3)
} catch (e) { // e就是try语句中出错的错误信息,我们可以在这里捕获到并做处理
console.log(e)
} finally { // finally里面的代码不管前面是否出错都会执行
console.log(4)
}
console.log(5) // try里面出错并不会影响外层代码的执行
console.log('-------------------------------------------------')
function test() {
var a = true
if (a) {
throw '出错啦!!' // throw是我们主动抛出异常,后面可跟字符串或者对象
}
console.log(6) // 这里的代码在上面抛出异常之后就不会被执行
}
try {
console.log(7)
test()
console.log(8)
} catch (e) {
console.log(e) // 上面我们主动抛出错误,所以e就相当于我们抛出错误的内容
}
console.log(9)
</script>
一、HTML简介
HTML 俗称网页,就是我们打开浏览器访问任何一个网站所看到的都是由 HTML 页面提供的(或者与 HTML 技术相关的内容提供)。
HTML 全称为 HyperText Markup Language,被译为超文本标记语言。所谓的超文本就是不仅只有文本内容,包括链接、音频和视频、图像等内容。所谓标记语言,简单来说就是元素。也就是说,HTML 提供一系列的元素来构成一个页面中最基础的内容。
HTML 是一种描述 Web 文档结构和语义的语言,它由元素组成,每个元素可以有一些属性或文本。
当你保存 HTML 文件时,既可以使用 .htm 也可以使用 .html 文件后缀。
编写HTML代码的工具:
记事本
sublime text
hbuilder
webstorm
vscode
pycharm – python代码 也可以写html代码
二、第一张网页
一个页面有且只有一个根标签是html, 元素一般包含 和 两个元素,也就是 HTML 的头部和主体内容。
<html>
<head>
<title>网页的标题</title>
</head>
<body>
<!-- 这是一个文本框 -->
<input type="text"></input>
</body>
</html>
1
2
3
4
5
6
7
8
9
HTML标签:由尖括号包围:
成对出现: <p></p> ,即开标签和闭标签.
属性: 定义在开标签中,如input标签中的type属性
简写: 开闭标签之间的内容是标签体,如果标签体为空,则可以简写:
注释: 是注释标签
HTML文档在浏览器中被解释运行,展示的不是源码而是渲染之后的效果
三、HTML头部
< head > 元素包含了当前 HTML 页面的所有头部元素,在 < head > 元素内必须定义 < title > 元素,还可以定义 < script >、< link > 等元素。
这些 HTML 的头部元素定义了当前页面的标题、编码、使用的脚本或样式等信息。
1、title元素
< title >元素定义了当前HTML页面的标题
<title>百度一下,你就知道</title>
1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AGycI1jQ-1578023422160)(HTML.assets/1530668619163.png)]
2、meta元素
元素提供了 HTML 页面的元数据(Metadata),元数据是存储数据的信息。
通常用于设置页面的编码、描述、关键词、作者等信息。
元素不会显示在页面中,但会被浏览器解析。
2.1 定义网页内容的编码格式
<meta charset="utf-8">
1
2.2 定义HTML页面关键字,用于搜索引擎
<meta name="keywords" content="HTML,CSS,XML,JavaScript">
1
2.3 定义HTML页面描述
<meta name="description" content="百知教育IT培训,java培训,PHP培训,UI培训,H5培训,linux培训,大数据培训,Python人工智能,IT行业培训领跑者,高薪就业 ">
1
2.4 定义HTML页面作者
<meta name="author" content="百知教育">
1
四、HTML主体
1、body元素
标签定义文档的主体。 元素包含文档的所有内容(比如文本、超链接、图像、表格和列表等等)。body元素中包含的内容(子标签)是用户可以看到的。
一个 HTML 文件只能存在一个 标签。
2、HTML元素基本构成
2.1 元素类型
HTML 是标记语言,所谓标记就是指页面中的元素(元素也可以叫做标签)。一个完整的 HTML 页面都是由众多不同的元素组成的。
闭合元素:必须包含开始元素和结束元素,如果没有结束元素会产生意料之外的错误。
<title>百知教育Python人工智能培训</title>
<p>这是一个段落标签</p> <!--该标签的作用是表示一个段落,会有换行-->
1
2
空元素:也可以叫做单元素,只需要开始元素,而不需要结束元素。
<meta name="description" content="渥瑞达Web前端培训">
<br/> <!-- 换行 -- >
1
2
3
2.2 HTML属性
属性是设置在HTML元素中的,用于为元素添加附加信息。属性一般都是定义在开始元素中,并且是以“名称/值”对出现
<input type="text" /> <!-- 这是一个文本框 -->
<input type="button" value="点我" /> <!-- 这是一个按钮 -->
1
2
3
五、HTML文本
1、标题元素
HTML 提供了 6 个标题元素,由大到小依次为 <h1> 到 <h6>
<h1>这是一级标题</h1>
<h2>这是二级标题</h2>
<h3>这是三级标题</h3>
<h4>这是四级标题</h4>
<h5>这是五级标题</h5>
<h6>这是六级标题</h6>
1
2
3
4
5
6
7
8
9
10
11
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gpmb9nTx-1578023422163)(HTML.assets/1530670234313.png)]
2、段落
元素定义段落
: 浏览器会自动地在段落的前后添加空行 ```html
这是一个段落.
1
这是另一个段落.
注意: 在html中手动换行无效<br />
<br />
3、换行<br />
元素定义的段落内容是不会自动换行的,如果换行需要使用 br 元素<br />
<br />
<body><br />
<span style="white-space:pre;"> </span>生活赋予我们一种巨大的和无限高贵的礼品,这就是青春:充满着力量,充满着期待志愿,充满着求知和斗争的志向,充满着希望信心和青春。<br />
<span style="white-space:pre;"> </span><br><br />
人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。<br />
</body><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LbaNYf1L-1578023422165)(HTML.assets/1530670731312.png)]<br />
<br />
4、水平线<br />
在浏览器中显示一条水平线(分隔线)效果。<br />
属性:size=“10” color=“red” width=“100px 或者 50%” align=“left/right/center”<br />
<br />
10像素高 颜色 宽度 对齐方式<br />
<br />
<body><br />
<span style="white-space:pre;"> </span>生活赋予我们一种巨大的和无限高贵的礼品,这就是青春:充满着力量,充满着期待志愿,充满着求知和斗争的志向,充满着希望信心和青春。<br />
<span style="white-space:pre;"> </span><br><br />
<span style="white-space:pre;"> </span><hr size="1" width="100%" color="red"/><br />
<span style="white-space:pre;"> </span>人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。<br />
</body><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nK6UOf0r-1578023422166)(HTML.assets/1530671029915.png)]<br />
<br />
5、文本修饰<br />
5.1 粗体字<br />
这是一段正常未加粗的文本内容.<br />
<br><br />
<b>这是一段加粗之后的文本内容.</b><br />
<br><br />
<strong>粗体--着重强调</strong><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Va3GdgFK-1578023422168)(HTML.assets/1530672074778.png)]<br />
<br />
5.2 斜体字<br />
<i>这是一段斜体的文本内容.</i><br />
1<br />
5.3 下划线<br />
<body><br />
<span style="white-space:pre;"> </span>证明人:<u>百知教育</u><br />
</body><br />
1<br />
2<br />
3<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJY0EaxC-1578023422169)(HTML.assets/1530671768110.png)]<br />
<br />
5.4 删除线<br />
<body><br />
<span style="white-space:pre;"> </span><del>这是一段要被删除的文字</del><br />
</body><br />
1<br />
2<br />
3<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X4f2bCuN-1578023422172)(HTML.assets/1530671905293.png)]<br />
<br />
5.5 下标文字<br />
<body><br />
<span style="white-space:pre;"> </span>H<sub>2</sub>O<br />
</body><br />
1<br />
2<br />
3<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E8DEONkQ-1578023422179)(HTML.assets/1530672009385.png)]<br />
<br />
5.6 上标文字<br />
32 = 9<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NTEZhEkv-1578023422180)(HTML.assets/1530672138124.png)]<br />
<br />
5.7 小号字<br />
正常文字<br />
<small>小号文字</small><br />
1<br />
2<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6KckvEOc-1578023422182)(HTML.assets/1530672191397.png)]<br />
<br />
5.8 大号字<br />
<body><br />
<span style="white-space:pre;"> </span><small>小号文字</small><br />
<span style="white-space:pre;"> </span>正常文字<br />
<span style="white-space:pre;"> </span><big>大号文字</big><br />
</body><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gCJaBbhq-1578023422184)(HTML.assets/1530672254286.png)]<br />
<br />
六、图像与链接<br />
1、图像元素<br />
元素引入外部图像, 元素是空元素。<br />
<br />
1.1 src属性<br />
<span style="white-space:pre;"> </span>src 属性(必需),表示引入图像的 URL 地址。<br />
<br />
<img src="images/img.png"><br />
1<br />
图像可以是本地地址,也可以是网络地址。<br />
<br />
<img src="https://himg.bdimg.com/sys/portrait/item/c8764d725f6c6963656e6365g872fc876872f.jpg"><br />
1<br />
1.2 图像大小<br />
width 和 height 属性用于设置图像显示的宽度和高度。<br />
<br />
<img src="img.png" width="350" height="233" /><br />
1<br />
1.3 图像定位(了解)<br />
align 属性用于设置图像显示的位置。<br />
<br />
left:水平方向居左。<br />
right:水平方向居右。<br />
top:垂直方向居上。<br />
bottom:垂直方向居下。<br />
middle:居中。<br />
<img src="img.png" width="350" height="233" align="right" /><br />
1<br />
1.4 alt属性<br />
<img src="abcdef.png" alt="无法加载图片"/><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-evR6GiGo-1578023422185)(HTML.assets/1530673186561.png)]<br />
<br />
2、超链接<br />
2.1 用法<br />
href 属性(必需),表示指定跳转的 URL 地址<br />
<br />
<a href="http://www.baizhiedu.com">百知教育</a><br />
1<br />
2.2 打开方式: target 属性<br />
元素的 target 属性用于设置链接的打开方式。<br />
<br />
_blank:在新窗口打开链接。<br />
_self:在当前窗口打开链接。<br />
<a href="http://www.baizhiedu.com" target="_blank">百知教育</a><br />
1<br />
2.3 锚点<br />
<body><br />
<span style="white-space:pre;"> </span><a name="postion"></a> <!-- 定义锚点 --><br />
<span style="white-space:pre;"> </span><!-- 页面其它内容<br />
<span style="white-space:pre;"> </span>...<br />
<span style="white-space:pre;"> </span>...<br />
<span style="white-space:pre;"> </span>...<br />
<span style="white-space:pre;"> </span> --><br />
<span style="white-space:pre;"> </span><a href="#postion">定位到postion的位置</a> <!-- 链接到锚点 --><br />
</body><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
2.4 回到顶部的空链接<br />
<body><br />
<span style="white-space:pre;"> </span><!-- 页面其它内容<br />
<span style="white-space:pre;"> </span>...<br />
<span style="white-space:pre;"> </span>...<br />
<span style="white-space:pre;"> </span>...<br />
<span style="white-space:pre;"> </span> --><br />
<span style="white-space:pre;"> </span><a href="#">回到顶部</a> <!-- 回到顶部 --><br />
</body><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
七、列表<br />
1、无序列表<br />
1.1 定义无序列表<br />
元素定义无序列表,用于列出页面上没有特定次序的条目。<br />
<ul><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>北京市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>上海市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>重庆市</li><br />
</ul><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8MFYHQJB-1578023422187)(HTML.assets/1530684550787.png)]<br />
<br />
1.2 type属性<br />
定义列表的项目符号的类型<br />
<br />
disc:实心圆,默认值。<br />
circle:空心圆。<br />
square:实心矩形。<br />
<ul type="circle"><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>北京市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>上海市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>重庆市</li><br />
</ul><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gCwhGGdG-1578023422188)(HTML+CSS_pic/1530684771419.png)]<br />
<br />
2、有序列表<br />
2.1 定义有序列表<br />
<ol><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>北京市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>上海市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>重庆市</li><br />
</ol><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofA5U8WE-1578023422190)(HTML.assets/1530684878880.png)]<br />
<br />
2.2 type属性<br />
1:数字值,默认值。<br />
a 或 A:小写或大写字母。<br />
i 或 I:小写或大写罗马数字。<br />
<ol type="a"><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>北京市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>上海市</li><span style="white-space:pre;"> </span><br />
<span style="white-space:pre;"> </span><li>重庆市</li><br />
</ol><br />
1<br />
2<br />
3<br />
4<br />
5<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3l1LPm9P-1578023422191)(HTML.assets/1530685009075.png)]<br />
<br />
3、自定义列表<br />
<dl><br />
<dt>北京</dt><br />
<dd>海淀</dd><br />
<dd>昌平</dd><br />
<dd>朝阳</dd><br />
<dt>广东</dt><br />
<dd>广州</dd><br />
<dd>深圳</dd><br />
<dd>东莞</dd><br />
</dl><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
八、表格<br />
1、表格使用<br />
表格由 < table > 标签来定义。每个表格均有若干行(由 标签定义),每行被分割为若干单元格(由 标签定义)。<br />
<br />
<table><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第1行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第1行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第2行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第2行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JL9Sjv2t-1578023422196)(HTML.assets/1530685462072.png)]<br />
<br />
2、表格属性<br />
属性名称<span style="white-space:pre;"> </span>描述<br />
width 和 height<span style="white-space:pre;"> </span>设置表格的宽度和高度<br />
align<span style="white-space:pre;"> </span>设置表格的对齐方式<br />
border<span style="white-space:pre;"> </span>设置表格的边框宽度<br />
bgcolor<span style="white-space:pre;"> </span>设置表格的背景颜色<br />
cellpadding<span style="white-space:pre;"> </span>设置内边距(单元格边框与内容之间的距离)<br />
cellspacing<span style="white-space:pre;"> </span>设置外边距(单元格之间的距离)<br />
bordercolor<span style="white-space:pre;"> </span>边框颜色<br />
<table border="1" cellspacing="0" bgcolor="gray" bordercolor="red" width="300px" height="100px" align="left"><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第1行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第1行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第2行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第2行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3bucqAYt-1578023422198)(HTML.assets/1530685943196.png)]<br />
<br />
3、tr元素<br />
属性名称<span style="white-space:pre;"> </span>值<span style="white-space:pre;"> </span>描述<br />
align<span style="white-space:pre;"> </span>right、left、center<span style="white-space:pre;"> </span>左右对齐方式<br />
valign<span style="white-space:pre;"> </span>top 、middle 、bottom<span style="white-space:pre;"> </span>垂直对齐方式<br />
bgcolor<span style="white-space:pre;"> </span>rgb(xxx,xxx,xxx)、colorName<span style="white-space:pre;"> </span>背景颜色<br />
<table border="1" cellspacing="0" width="500px" height="100px"><br />
<span style="white-space:pre;"> </span><tr align="center"><br />
<span style="white-space:pre;"> </span><td>第1行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第1行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr align="right" valign="top" bgcolor="blue"><br />
<span style="white-space:pre;"> </span><td>第2行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第2行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-737Gkc1r-1578023422199)(HTML.assets/1530695272576.png)]<br />
<br />
4、td元素<br />
元素是定义表格的数据单元格。<br />
属性名称<span style="white-space:pre;"> </span>值<span style="white-space:pre;"> </span>描述<br />
align<span style="white-space:pre;"> </span>right、center、left<span style="white-space:pre;"> </span>设置水平对齐方式<br />
valign<span style="white-space:pre;"> </span>top、middle、bottom<span style="white-space:pre;"> </span>设置垂直对齐方式<br />
width和height<span style="white-space:pre;"> </span>pixels 、%<span style="white-space:pre;"> </span>设置单元格的宽和高<br />
colspan和rowspan<span style="white-space:pre;"> </span>number<span style="white-space:pre;"> </span>设置单元格的跨列和跨行数量<br />
bgcolor<span style="white-space:pre;"> </span>rbg()、colorName<span style="white-space:pre;"> </span>单元格背景色<br />
<table border="1" cellspacing="0" width="500px" height="100px"><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td align="center">第1行,第1列</td><br />
<span style="white-space:pre;"> </span><td valign="top">第1行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td width="300px">第2行,第1列</td><br />
<span style="white-space:pre;"> </span><td bgcolor='red'>第2行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IcLpE6Ii-1578023422201)(HTML.assets/1530697152946.png)]<br />
<br />
合并行和列<br />
<br />
<table border="1" cellspacing="0" width="500px" height="200px"><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第1行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第1行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td colspan="2">第2行,第1列</td><span style="white-space:pre;"> </span> <br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第3行,第1列</td><br />
<span style="white-space:pre;"> </span><td rowspan="2">第3行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第4行,第1列</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z6ythYQ4-1578023422203)(HTML.assets/1530697074613.png)]<br />
<br />
5、表格标题caption<br />
元素用于定义表格的标题,必须紧随 元素之后,且只能对每个表格定义一个标题。<br />
<table border="1" cellspacing="0" width="500px" height="100px"><br />
<span style="white-space:pre;"> </span><caption>表格标题</caption><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第1行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第1行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>第2行,第1列</td><br />
<span style="white-space:pre;"> </span><td>第2行,第2列</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3X7gcxe-1578023422204)(HTML.assets/1530697414224.png)]<br />
<br />
6、表头thead、tbody表主体、tfoot表脚注<br />
标签定义表格的表头。<br />
<table border="1" cellspacing="0" width="500px" height="100px"><br />
<span style="white-space:pre;"> </span><caption>信息</caption><br />
<span style="white-space:pre;"> </span><thead><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><th>姓名</th> <!-- 定义表头单元格 会加粗显示 --> <br />
<span style="white-space:pre;"> </span><th>性别</th><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span></thead><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>Tom</td><br />
<span style="white-space:pre;"> </span><td>boy</td><br />
<span style="white-space:pre;"> </span></tr><br />
<span style="white-space:pre;"> </span><tr><br />
<span style="white-space:pre;"> </span><td>Linda</td><br />
<span style="white-space:pre;"> </span><td>girl</td><br />
<span style="white-space:pre;"> </span></tr><br />
</table><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
tfoot 元素应该与 thead 和 tbody 元素结合起来使用。 (比较少用)<br />
<br />
九、表单<br />
1、form 元素<br />
表单用标签描述,表单内部可以有多个子标签,用来完成用户信息的收集,并发送请求给服务器。<br />
<br />
属性:action=“xxx” method=“get/post”<br />
<br />
请求地址 请求方式<br />
<br />
http://www.baidu.com?uname=abc&passwd=123<br />
<form action="http://www.baidu.com" method="get"><br />
<span style="white-space:pre;"> </span>username:<input type="text" name="uname" id="uname115"/><br/> # abc<br />
<span style="white-space:pre;"> </span>password:<input type="text" name="passwd" id="pwd115"/><br/> # 123<br />
<span style="white-space:pre;"> </span><input type="submit" value="提交" id="sub115"/><br />
</form><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
2、表单元素<br />
元素有很多不同类型,根据不同的 type 属性来决定。<br />
<br />
用户名:<input type="text" name="txt" /> <!-- text表示文本框--><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nLWfznhF-1578023422206)(HTML.assets/1530757524606.png)]<br />
<br />
type属性:<br />
类型名称<span style="white-space:pre;"> </span>描述<br />
text<span style="white-space:pre;"> </span>文本输入框<br />
password<span style="white-space:pre;"> </span>密码框<br />
radio<span style="white-space:pre;"> </span>单选按钮<br />
checkbox<span style="white-space:pre;"> </span>复选框<br />
button<span style="white-space:pre;"> </span>按钮<br />
submit<span style="white-space:pre;"> </span>提交按钮<br />
reset<span style="white-space:pre;"> </span>重置按钮<br />
file<span style="white-space:pre;"> </span>文件域<br />
name属性 :标签的普通的属性,相当于别名,是每个输入控件的重要属性==请求参数名。<br />
<br />
id属性 : 标签的唯一标识名,不能重复。<br />
<br />
value属性 :标签的普通属性,是中药属性==请求参数值。<br />
<br />
2.1 文本框<br />
用户名:<input type="text" name="txt" /> <!-- text表示文本框--><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H6IYvY3p-1578023422207)(HTML.assets/1530758139189.png)]<br />
<br />
用户名:<input type="text" name="pwd" value="Mr_lee" maxlength="10" readonly="readonly" /><br />
1<br />
2.2 密码框<br />
密码:<input type="password" name="pwd" value="123456" /><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Nk9Lys0-1578023422208)(HTML.assets/1530758213655.png)]<br />
<br />
2.3 单选按钮<br />
<!-- name:值必须一样,value:表示提交表单时的值 checked:默认选中--><br />
<input type="radio" name="sex" value="1">男 <br />
<input type="radio" name="sex" value="0" checked="checked">女<br />
1<br />
2<br />
3<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XP3i844U-1578023422210)(HTML.assets/1530758647865.png)]<br />
<br />
2.4 复选框<br />
<input type="checkbox" name="course" value="Mysql">Mysql<br />
<input type="checkbox" name="course" value="HTML">HTML<br />
<input type="checkbox" name="course" value="Linux">Linux<br />
<input type="checkbox" name="course" value="Django">Django<br />
1<br />
2<br />
3<br />
4<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r5mPRrZ3-1578023422211)(HTML.assets/1530758924865.png)]<br />
<br />
2.5 按钮<br />
<input type="button" name="btn" value="点我"><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ozchiqAW-1578023422214)(HTML.assets/1530759170832.png)]<br />
<br />
2.6 提交按钮<br />
<input type="submit" name="sub_btn" value="提交"><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kIOKVxLo-1578023422215)(HTML.assets/1530759206331.png)]<br />
<br />
2.7 重置按钮<br />
<input type="reset" name="set_btn" value="重置"><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cG06duKx-1578023422217)(HTML.assets/1530759252821.png)]<br />
<br />
2.8 文件域<br />
<br />
<input type="file"><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mHkQp3fZ-1578023422219)(HTML.assets/1530759404657.png)]<br />
<br />
2.9 文本域<br />
<textarea name="txtInfo" rows="4" cols="20">aa</textarea><br />
1<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-406qSTUX-1578023422221)(HTML.assets/1530759866508.png)]<br />
<br />
3、下拉选框<br />
选择课程:<br />
<select name="course"><br />
<span style="white-space:pre;"> </span><option value="1">Java</option><br />
<span style="white-space:pre;"> </span><option value="2" selected="selected">C++</option><br />
<span style="white-space:pre;"> </span><option value="3">PHP</option><br />
</select><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b9rrRffX-1578023422222)(HTML.assets/1530759604602.png)]<br />
<br />
4、表单综合实例<br />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9sgjtXvT-1578023422223)(HTML.assets/1530759682014.png)]<br />
<br />
十、特殊符号<br />
显示结果<span style="white-space:pre;"> </span>描述<span style="white-space:pre;"> </span>实体名称<br />
空格<span style="white-space:pre;"> </span> <br />
<<span style="white-space:pre;"> </span>小于号<span style="white-space:pre;"> </span><<br />
><span style="white-space:pre;"> </span>大于号<span style="white-space:pre;"> </span>><br />
©<span style="white-space:pre;"> </span>版权(copyright)<span style="white-space:pre;"> </span>©<br />
®<span style="white-space:pre;"> </span>注册商标<span style="white-space:pre;"> </span>®<br />
™<span style="white-space:pre;"> </span>商标<span style="white-space:pre;"> </span>™<br />
ile"><br />
<br />
<br />
[外链图片转存中...(img-mHkQp3fZ-1578023422219)]<br />
<br />
##### 2.9 文本域<br />
<br />
```html<br />
<textarea name="txtInfo" rows="4" cols="20">aa</textarea><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
[外链图片转存中…(img-406qSTUX-1578023422221)]<br />
<br />
3、下拉选框<br />
选择课程:<br />
<select name="course"><br />
<span style="white-space:pre;"> </span><option value="1">Java</option><br />
<span style="white-space:pre;"> </span><option value="2" selected="selected">C++</option><br />
<span style="white-space:pre;"> </span><option value="3">PHP</option><br />
</select><br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
[外链图片转存中…(img-b9rrRffX-1578023422222)]<br />
<br />
4、表单综合实例<br />
[外链图片转存中…(img-9sgjtXvT-1578023422223)]<br />
<br />
十、特殊符号<br />
显示结果<span style="white-space:pre;"> </span>描述<span style="white-space:pre;"> </span>实体名称<br />
空格<span style="white-space:pre;"> </span> <br />
<<span style="white-space:pre;"> </span>小于号<span style="white-space:pre;"> </span><<br />
><span style="white-space:pre;"> </span>大于号<span style="white-space:pre;"> </span>><br />
©<span style="white-space:pre;"> </span>版权(copyright)<span style="white-space:pre;"> </span>©<br />
®<span style="white-space:pre;"> </span>注册商标<span style="white-space:pre;"> </span>®<br />
™<span style="white-space:pre;"> </span>商标<span style="white-space:pre;"> </span>™<br />
<br />
<br />
方法一:使用 localStorage 存储数据
window.localStorage.setItem(key,value)
方法二:使用 vuex-persistedstate插件
vuex 存在一个痛点,就是刷新以后vuex里面存储的state就会被浏览器释放掉(state都是存储在内存中的)。
办法:
通过vuex-persistedstate插件,实现将数据存储到本地。
1.实现
import createPersistedState from 'vuex-persistedstate'
export default new Vuex.Store({
state:{},
getters:{},
actions:{},
mutations:{},
modules:{},
plugins: [createPersistedState()] //加上这个就可以了 //里面设置需要缓存的内容
})
API: https://www.npmjs.com/package/vuex-persistedstate
方法三: 使用vue-cookie插件
cookie 可以设置过期时间
import Vue from 'vue';首先编写一个简单的容器:
<style>
width: 600px;
height: 100vh;
overflow-y: auto;
}
width: 100%;
}
width: 50%;
float: left;
margin: 20px 0;
list-style: none;
}
width: 200px;
height: 200px;
overflow: hidden;
margin: 0 auto;
border: 1px solid #999999;
}
width: 100%;
display: block;
position: relative;
top: 50%;
transform: translateY(-50%);
}
</style>
<div id="content">
<ul>
</ul>
</div>
然后,编写js代码:
let imageArr = [{
img_url: "http://www.lexilisi.com/Uploadpth/c45cc952-dcb7-493c-a171-357d1b820b37.png",
}, {
img_url: "http://xiaobanyou.com/static/images/xby_user_3.jpg",
}, {
img_url: "http://xiaobanyou.com/static/images/xby_user_4.jpg",
}, {
img_url: "http://xiaobanyou.com/static/images/xby_user_5.jpg",
}, {
img_url: "http://xiaobanyou.com/static/images/xby_user_6.jpg",
}, {
img_url: "http://xiaobanyou.com/static/images/xby_user_799.jpg",
}];
const lazyLoad = (src) => {
//加载loading动画
let _image = new Image();
_image.src = './loading.gif';
//加载需要展示的图片
let image = new Image();
image.src = src;
//加载成功,将loading图片路径改成对应的真实路径
image.onload = _ => image.src = .currentTarget.src;
//加载失败,将loading图片路径改成默认图片路径
image.onerror = _ => _image.src = './error.png';
return _image;
}
let _content = document.getElementById('content');
let _ul = _content.getElementsByTagName('ul');
imageArr.forEach(value => {
let _li = document.createElement('li');
let _p = document.createElement('p');
let _image = lazyLoad(value.img_url);
_p.appendChild(_image);
_li.appendChild(_p);
_ul[0].appendChild(_li);
})
展示效果如图:
每个图片都是异步加载,加载完成后:
一. 通过router-link进行跳转
<router-link
:to="{
path: 'yourPath',
params: {
name: 'name',
dataObj: data
},
query: {
name: 'name',
dataObj: data
}
}">
</router-link>
二. 通过编程导航 $router进行路由跳转
1.路径后拼接参数
通过路径后直接拼接来传递参数
getDescribe(id) {
// 直接调用$router.push 实现携带参数的跳转
this.$router.push({
path: /describe/${id}
,
})
对应路由配置
注意:此方法需要修改对应路由配置,需要在path中添加/:id来对应 $router.push 中path携带的参数。
{
path: '/describe/:id',
name: 'Describe',
component: Describe
}
获取传递的参数值
this.$route.params.id
岁月不居,时节如流。转眼之间2019悄然而过,回首2019,我们豪情满怀,漫天风雪风景好;展望2020,我们重任在肩,阳光普照写佳绩。舟至中流需奋进,风好正是扬帆时。
在2019最后一天里,可能你还想做这么的一件事,给客户发一份精美的邮件祝福,但却无从下手,怎么办?拉易网能帮到你,准备好素材后,只需一分钟就能生成精美的HTML邮件格式。话不多说,直接上视频。
一分钟制作精美HTML邮件格式的元旦祝福邮件
走着走着…
2019已接近尾声
一眨眼就是一天
一回头就是一年
一转身就是一辈子
人生总有太多的来不及
微信小程序跳转方式
1.navigator 跳转
最常见的跳转方法就是运用<navigator url="../../.."></navigator>进行跳转,只要在url中添加跳转页面的路径即可。
代码
<navigator url="../skill/skill">
........//跳转涵盖内部所有代码形成的页面
</navigator>
1
2
3
2.运用 bindtap在js中实现页面的跳转
比起navigator的跳转,个人更喜欢用bindtap跳转,运用更灵活,也不用去除点击样式。
bindtap='home'(home位置随便替换)
代码
//wxml
<view bindtap='home'>
</view>
//js
home: function (e) {
wx.navigateTo({
url: '../../..' //跳转链接
})
}
**重点
在开发的过程中,突然遇到以上两种方式都无法实现跳转,也不会报错的情况,经过查询资料,发现内部调用wx.switchTab可以很好的解决这一现象
代码
home: function (e) {
wx.switchTab({
url: '../../..'
})
}
一、前言
我们都知道,vue组件中通信是用props进行父子通信,或者用provide和inject注入的方法,后者类似与redux的porvider,父组件使用,包含在里面的子组件都可以使用,provide/inject用法看我的博客(provide/inject用法),provide/indect官方文档,不过provide/indect一般用的不多,都是用前者,但是props有一个问题,父传子没问题,但是子后面还有子,子后面还有子,子子孙孙无穷尽也,所以这就要一层层的传下去,太麻烦了,所以vuex就派上用场了,vuex作为一个很轻量的状态管理器,有着简单易用的的API接口,在任意组件里面都能使用,获取全局状态,统一获取改变,今天,就看一下源码怎么实现的。
二、准备
1)先去github上将vuex源码下载下来。
2)打开项目,找到examples目录,在终端,cd进入examples,执行npm i,安装完成之后,执行node server.js
3)执行上述之后,会得到下方的结果,表示编译完成,打开浏览器 输入 localhost:8080
4) 得到页面,点击counter
5)最终,我们就从这里出发调试吧。
三、调试
找到counter目录下的store.js 写一个debugger,浏览器打开F12,刷新页面,调试开始。
1.Vue.use()
先进入Vue.use(Vuex),这是Vue使用插件时的用法,官方文档也说了,Vue.use,会调用插件的install方法,所以如果你要写插件的话,你就要暴露一个install方法,详情请看vue官方文档之use的用法
即use会调用下方的方法(debugger会进入)
function initUse (Vue) {
Vue.use = function (plugin) {
var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
var args = toArray(arguments, 1);
args.unshift(this);
if (typeof plugin.install === 'function') {
// 如果插件的install是一个function,调用install,将 this指向插件,并将Vue作为第一个参数传入
// 所以调用vuex吧this指向vuex,并吧vue当参数传入
plugin.install.apply(plugin, args);
} else if (typeof plugin === 'function') {
plugin.apply(null, args);
}
installedPlugins.push(plugin);
return this
};
}
1.1 vuex的install方法
在源码目录的src目录下的store.js文件里最下方有个install函数,会调用它
debugger进入后
export function install (_Vue) { // _Vue是上面说的Vue作为第一个参数 ,指针this指向Vuex
if (Vue && _Vue === Vue) {
// 如果你在开发环节,你使用了两次Vue.use(Vuex) 就会报下方的错误,提醒你vue只能被use一次,可以自行试试
if (process.env.NODE_ENV !== 'production') {
console.error(
'[vuex] already installed. Vue.use(Vuex) should be called only once.'
)
}
return
}
Vue = _Vue
applyMixin(Vue) // 调用applyMixin方法
}
1.2 vuex的applyMixin方法
applyMixin方法在mixin.js文件里 同样在src目录下
export default function (Vue) {
const version = Number(Vue.version.split('.')[0]) // 获取vue的版本
if (version >= 2) { // vue的版本是2.xx以上 执行vue的mixin混入,该函数不懂用法请查看官方文档,
// mixin合并混入操作,将vuexInit 方法混入到beforeCreate生命周期,意思就是当执行beforeCreate周期的时候
// 会执行vuexInit 方法
Vue.mixin({ beforeCreate: vuexInit })
} else { // 1.xxx版本太老了 现在基本不用,暂不讲解,可以自行了解
// override init and inject vuex init procedure
// for 1.x backwards compatibility.
const _init = Vue.prototype._init
Vue.prototype._init = function (options = {}) {
options.init = options.init
? [vuexInit].concat(options.init)
: vuexInit
_init.call(this, options)
}
}
/*
Vuex init hook, injected into each instances init hooks list.
/
function vuexInit () {
// 因为该方法是在beforeCreate下执行,而beforeCreate的this指向为Vue 所以this === Vue
// 获得vue里面的option配置,这里涉及到vue的源码,以后再讲vue ,
//所以这就是我们为什么要在new Vue的时候,传递一个store进去的原因,
//因为只有传进去,才能在options中获取到store
/
var vm = new Vue({
el: "#app",
data() {return{}},
store
})
*/
const options = this.$options
// store injection
if (options.store) {
// 如果options对象中store有,代表是root ,如果options.store是函数,执行调用options.store()
// 如果是对象直接options.store 赋值给this.$stroe
// 这也就是我们为什么能够在Vue项目中直接this.$store.disptach('xxx')的原因,从这里获取
this.$store = typeof options.store === 'function'
? options.store()
: options.store
} else if (options.parent && options.parent.$store) {
// 如果options.store为空,则判断options.parent.$store有没有 从父元素判断有没有store,
//从而保证子元素父元素公用一个store实例
this.$store = options.parent.$store
}
}
}
1.3 Vue.use(Vuex)总结
至此,Vue.use(Vuex)全部分析完成,总结,就是Vue.use调用Vuex的install的方法,然后install使用mixin混入beforecreate生命周期中混入一个函数,当执行生命周期beforecreate的时候回执行vuexInit 。你可以慢慢调试,所以要好好利用下方的调试按钮,第二个按钮执行下一步,第三个进入方法,两个配合使用。
2.new Vuex.Store
Vue.use(Vuex)已经结束,再回到counter目录下的store.js文件
export default new Vuex.Store({
state,
getters,
actions,
mutations
})
debugger进入,Vuex.Store方法在src目录下的store.js文件下
export class Store {
constructor (options = {}) {
// 这里的options是在counter定义的 state,getters,actions,mutations当做参数传进来
// Auto install if it is not done yet and window
has Vue
.
// To allow users to avoid auto-installation in some cases,
// this code should be placed here. See #731
if (!Vue && typeof window !== 'undefined' && window.Vue) {
// 挂载在window上的自动安装,也就是通过script标签引入时不需要手动调用Vue.use(Vuex)
install(window.Vue)
}
if (process.env.NODE_ENV !== 'production') {
// 开发环境 断言,如果不符合条件 会警告,这里自行看
assert(Vue, must call Vue.use(Vuex) before creating a store instance.
)
assert(typeof Promise !== 'undefined', vuex requires a Promise polyfill in this browser.
)
assert(this instanceof Store, store must be called with the new operator.
)
}
const {
plugins = [],
strict = false
} = options
// store internal state
//下方是在Vuex的this上挂载一些对象,这里暂且不要知道他们要来干什么
// 因为是源码分析,不要所有的代码都清除,第一次源码分析,你就只当他们是挂载对象,往下看
this._committing = false
this._actions = Object.create(null)
this._actionSubscribers = []
this._mutations = Object.create(null)
this._wrappedGetters = Object.create(null)
// ModuleCollection代表模块收集,形成模块树
this._modules = new ModuleCollection(options) //碰到第一个不是定义空对象,debugger进去,分析在下面
this._modulesNamespaceMap = Object.create(null)
this._subscribers = []
this._watcherVM = new Vue()
this._makeLocalGettersCache = Object.create(null)
// bind commit and dispatch to self
const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) { // 绑定dispatch的指针为store
return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) { // 绑定commit的指针为store
return commit.call(store, type, payload, options)
}
// strict mode
this.strict = strict
const state = this._modules.root.state // 获取到用户定义的state
// init root module.
// this also recursively registers all sub-modules
// and collects all module getters inside this._wrappedGetters
// 初始化root模块 注册getters,actions,mutations 子模块
installModule(this, state, [], this._modules.root)
// initialize the store vm, which is responsible for the reactivity
// (also registers _wrappedGetters as computed properties)
// 初始化vm 用来监听state getter
resetStoreVM(this, state)
// apply plugins
// 插件的注册
plugins.forEach(plugin => plugin(this))
// 下方的是开发工具方面的 暂不提
const useDevtools = options.devtools !== undefined ? options.devtools : Vue.config.devtools
if (useDevtools) {
devtoolPlugin(this)
}
}
}
2.1 new ModuleCollection
ModuleCollection函数在src目录下的module目录下的module-collection.js文件下
export default class ModuleCollection {
constructor (rawRootModule) { // rawRootModule === options
// register root module (Vuex.Store options)
this.register([], rawRootModule, false)
}
}
2.1.1 register()
register (path, rawModule, runtime = true) {
// register([],options,false)
if (process.env.NODE_ENV !== 'production') {
assertRawModule(path, rawModule) // 开发环境断言,暂忽略
}
const newModule = new Module(rawModule, runtime)
if (path.length === 0) { // path长度为0,为根节点,将newModule 赋值为root
this.root = newModule
} else {
const parent = this.get(path.slice(0, -1))
parent.addChild(path[path.length - 1], newModule)
}
// register nested modules
if (rawModule.modules) { // 如果存在子模块,递归调用register,形成一棵树
forEachValue(rawModule.modules, (rawChildModule, key) => {
this.register(path.concat(key), rawChildModule, runtime)
})
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2.1.2 new Module()
Module函数在同目录下的modele.js文件下
export default class Module {
// new Module(options,false)
constructor (rawModule, runtime) {
this.runtime = runtime
// Store some children item
this._children = Object.create(null)
// Store the origin module object which passed by programmer
this._rawModule = rawModule // 将options放到Module上 用_raModele上
const rawState = rawModule.state // 将你定义的state取出
// Store the origin module's state
// 如果你定义的state为函数,调用函数,为对象,则取对象 赋值为module上的state上
this.state = (typeof rawState === 'function' ? rawState() : rawState) || {}
}
}
所以Module的this内容为如下:
2.1.3 installModule
function installModule (store, rootState, path, module, hot) {
// installModule(Vuex,state,[],module) module是前面 new ModuleCollection产生的对象
const isRoot = !path.length
const namespace = store._modules.getNamespace(path)
// register in namespace map
if (module.namespaced) {
if (store._modulesNamespaceMap[namespace] && process.env.NODE_ENV !== 'production') {
console.error([vuex] duplicate namespace ${namespace} for the namespaced module ${path.join('/')}
)
}
store._modulesNamespaceMap[namespace] = module
}
// set state
if (!isRoot && !hot) {
const parentState = getNestedState(rootState, path.slice(0, -1))
const moduleName = path[path.length - 1]
store._withCommit(() => {
if (process.env.NODE_ENV !== 'production') {
if (moduleName in parentState) {
console.warn(
[vuex] state field "${moduleName}" was overridden by a module with the same name at "${path.join('.')}"
)
}
}
Vue.set(parentState, moduleName, module.state)
})
}
// 设置当前上下文
const local = module.context = makeLocalContext(store, namespace, path)
// 注册mutation
module.forEachMutation((mutation, key) => {
const namespacedType = namespace + key
registerMutation(store, namespacedType, mutation, local)
})
// 注册action
module.forEachAction((action, key) => {
const type = action.root ? key : namespace + key
const handler = action.handler || action
registerAction(store, type, handler, local)
})
// 注册getter
module.forEachGetter((getter, key) => {
const namespacedType = namespace + key
registerGetter(store, namespacedType, getter, local)
})
// 逐一注册子module
module.forEachChild((child, key) => {
installModule(store, rootState, path.concat(key), child, hot)
})
}
2.1.4 makeLocalContext
// 设置module的上下文,绑定对应的dispatch、commit、getters、state
function makeLocalContext (store, namespace, path) {
const noNamespace = namespace === ''
const local = {
//noNamespace 为true 使用原先的 至于后面的 不知道干啥用的 后面继续研究
dispatch: noNamespace ? store.dispatch : (_type, _payload, _options) => {
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
if (process.env.NODE_ENV !== 'production' && !store._actions[type]) {
console.error([vuex] unknown local action type: ${args.type}, global type: ${type}
)
return
}
}
return store.dispatch(type, payload)
},
commit: noNamespace ? store.commit : (_type, _payload, _options) => {
//noNamespace 为true 使用原先的
const args = unifyObjectStyle(_type, _payload, _options)
const { payload, options } = args
let { type } = args
if (!options || !options.root) {
type = namespace + type
if (process.env.NODE_ENV !== 'production' && !store._mutations[type]) {
console.error([vuex] unknown local mutation type: ${args.type}, global type: ${type}
)
return
}
}
store.commit(type, payload, options)
}
}
// getters and state object must be gotten lazily
// because they will be changed by vm update
Object.defineProperties(local, {
getters: {
get: noNamespace
? () => store.getters
: () => makeLocalGetters(store, namespace)
},
state: {
get: () => getNestedState(store.state, path)
}
})
return local
}
function getNestedState (state, path) {
return path.reduce((state, key) => state[key], state)
}
2.1.5 registerMutation
mutation的注册,会调用下方方法,将wrappedMutationHandler函数放入到entry中
function registerMutation(store, type, handler, local) {
// entry和store._mutations[type] 指向同一个地址
var entry = store._mutations[type] || (store._mutations[type] = []);
entry.push(function wrappedMutationHandler(payload) {
handler.call(store, local.state, payload);
});
}
2.1.6 forEachAction
action的注册,会调用下方方法,将wrappedActionHandler函数放入到entry中
function registerAction(store, type, handler, local) {
var entry = store._actions[type] || (store._actions[type] = []);
// entry和store._actions[type]指向同一个地址
entry.push(function wrappedActionHandler(payload) {
var res = handler.call(store, {
dispatch: local.dispatch,
commit: local.commit,
getters: local.getters,
state: local.state,
rootGetters: store.getters,
rootState: store.state
}, payload);
if (!(0, _util.isPromise)(res)) {
res = Promise.resolve(res);
}
if (store._devtoolHook) {
return res.catch(function (err) {
store._devtoolHook.emit('vuex:error', err);
throw err;
});
} else {
return res;
}
});
}
因为entry和上面的_action[type],_mutations[type] 指向同一个地址,所以:
2.1.7 forEachGetter
getter的注册,会调用下方方法
function registerGetter(store, type, rawGetter, local) {
if (store._wrappedGetters[type]) {
if (true) {
console.error('[vuex] duplicate getter key: ' + type);
}
return;
}
store._wrappedGetters[type] = function wrappedGetter(store) {
return rawGetter(local.state, // local state
local.getters, // local getters
store.state, // root state
store.getters // root getters
);
};
}
2.1.8 resetStoreVM
function resetStoreVM (store, state, hot) {
const oldVm = store._vm //将_vm用变量保存
// bind store public getters
store.getters = {}
// reset local getters cache
store._makeLocalGettersCache = Object.create(null)
const wrappedGetters = store._wrappedGetters // 获取installModule方法完成的_wrappedGetters内容
const computed = {}
forEachValue(wrappedGetters, (fn, key) => {
// use computed to leverage its lazy-caching mechanism
// direct inline function use will lead to closure preserving oldVm.
// using partial to return function with only arguments preserved in closure environment.
computed[key] = partial(fn, store)
Object.defineProperty(store.getters, key, {
// 拦截get返回store._vm[key]中的值,即可以通过 this.$store.getters.xxx访问值
get: () => store._vm[key],
enumerable: true // for local getters
})
})
// use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
const silent = Vue.config.silent
// silent设置为true,取消所有日志警告等
Vue.config.silent = true
store._vm = new Vue({ // 将state,getter的值进行监听,从这里就可以看出getter其实就是采用的vue的computed
data: {
$$state: state
},
computed
})
// 恢复原先配置
Vue.config.silent = silent
// enable strict mode for new vm
if (store.strict) {
enableStrictMode(store)
}
// 若存在旧的实例,解除对state的引用,等dom更新后把旧的vue实例销毁
if (oldVm) {
if (hot) {
// dispatch changes in all subscribed watchers
// to force getter re-evaluation for hot reloading.
store._withCommit(() => {
oldVm._data.$$state = null
})
}
Vue.nextTick(() => oldVm.$destroy())
}
}
看到这里,你应该对vuex有初步的了解
// 这也是我们为什么能用访问到state,getter的原因
//this.store.dispatch('xxx') ,this.$store.dispatch('xxx')
1
2
相信你也有点乱,其实上面很多我没讲到的不是我不想讲,是具体我也不知道干啥的,看源码学习呢,看主要就行,后面理解多了,其他的就慢慢都会,你不可能刚开始看,就每一行,他写的每一句的用途都知道是干什么的,只能先看主要方法,在慢慢琢磨,一步步来吧,别急,现在我来画一个流程图,更好的去理解吧。
2.1.9 流程图
3.连贯
import Vue from 'vue'
import Counter from './Counter.vue'
import store from './store'
new Vue({
el: '#app',
store,
render: h => h(Counter)
})
当运行new Vue的时候,传入了store,前面minix beforecreate,执行到beforecreate钩子时,会调用vueInit函数,就可以在this.$store取到store对象了,因为options.store有值了 ,不为空,这样就连贯到了,所以这就是为什么可以用this.$store取值。
HTML常用meta大全
Meta标签是HTML语言head区的一个辅助性标签,它位于HTML文档头部的head标记和title标记之间,它提供用户不可见的信息。
Meta : 即 元数据(Metadata)是数据的数据信息。
元数据可以被使用浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 Web 服务调用。
用我们的大白话来说,它本身是一个没什么用的标签,但是一旦在它内部通过其他属性设置了某些效果,它就起作用了,所以我们称之为“ 元数据 ”。
Code
<!-- 定义文档的字符编码 -->
<meta charset="utf-8" />
<!-- 强制Chromium内核,作用于360浏览器、QQ浏览器等国产双核浏览器 -->
<meta name="renderer" content="webkit"/>
<!-- 强制Chromium内核,作用于其他双核浏览器 -->
<meta name="force-rendering" content="webkit"/>
<!-- 如果有安装 Google Chrome Frame 插件则强制为Chromium内核,否则强制本机支持的最高版本IE内核,作用于IE浏览器 -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/>
<!--
设置视窗大小
width 设置layout viewport 的宽度,为一个正整数,或字符串"width-device"
initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
shrink-to-fit=no IOS9中要想前面的属性起作用需要加上这个
height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许
-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<!-- 页面描述 -->
<meta name="description" content="不超过150个字符"/>
<!-- 页面关键词 -->
<meta name="keywords" content=""/>
<!-- 网页作者 -->
<meta name="author" content="name, email@gmail.com"/>
<!--
搜索引擎抓取
all:文件将被检索,且页面上的链接可以被查询;
none:文件将不被检索,且页面上的链接不可以被查询;
index:文件将被检索;
follow:页面上的链接可以被查询;
noindex:文件将不被检索;
nofollow:页面上的链接不可以被查询。
-->
<meta name="robots" content="index,follow"/>
<!-- 忽略页面中的数字识别为电话,忽略email识别-->
<meta name="format-detection" content="telphone=no, email=no"/>
<!-- IOS begin -->
<!-- 添加到主屏后的标题(iOS 6 新增) -->
<meta name="apple-mobile-web-app-title" content="标题">
<!-- 当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari (ios7.0版本以后,safari上已看不到效果) -->
<meta name="apple-mobile-web-app-capable" content="yes"/>
<!-- 是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏 -->
<meta name="apple-touch-fullscreen" content="yes"/>
<!-- 添加智能 App 广告条 Smart App Banner(iOS 6+ Safari) -->
<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">
<!-- 设置苹果工具栏颜色:默认值为 default(白色),可以定为 black(黑色)和 black-translucent(灰色半透明) -->
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<!-- 不让百度转码 -->
<meta http-equiv="Cache-Control" content="no-siteapp" />
<!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
<meta name="HandheldFriendly" content="true">
<!-- 微软的老式浏览器 -->
<meta name="MobileOptimized" content="320">
<!-- uc强制竖屏 -->
<meta name="screen-orientation" content="portrait">
<!-- QQ强制竖屏 -->
<meta name="x5-orientation" content="portrait">
<!-- UC强制全屏 -->
<meta name="full-screen" content="yes">
<!-- QQ强制全屏 -->
<meta name="x5-fullscreen" content="true">
<!-- UC应用模式 -->
<meta name="browsermode" content="application">
<!-- QQ应用模式 -->
<meta name="x5-page-mode" content="app">
<!-- windows phone 点击无高光 -->
<meta name="msapplication-tap-highlight" content="no">
<!--
iOS 图标 begin
网站添加至ios桌面时的图标
-->
<!-- iPhone 和 iTouch,默认 57x57 像素,必须有 -->
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="table_ico57.png">
<!-- Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有 -->
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="table_ico72.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="table_ico114.png">
<!-- Retina iPad,144x144 像素,可以没有,但推荐有 -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="table_ico144.png">
<!-- iOS 启动画面 begin -->
<!-- iPad 竖屏 768 x 1004(标准分辨率) -->
<link rel="apple-touch-startup-image" sizes="768x1004" href="/splash-screen-768x1004.png"/>
<!-- iPad 横屏 1024x748(标准分辨率) -->
<link rel="apple-touch-startup-image" sizes="1024x748" href="/Default-Portrait-1024x748.png"/>
<!-- iPad 竖屏 1536x2008(Retina) -->
<link rel="apple-touch-startup-image" sizes="1536x2008" href="/splash-screen-1536x2008.png"/>
<!-- iPad 横屏 2048x1496(Retina) -->
<link rel="apple-touch-startup-image" sizes="2048x1496" href="/splash-screen-2048x1496.png"/>
<!-- iPhone/iPod Touch 竖屏 320x480 (标准分辨率) -->
<link rel="apple-touch-startup-image" href="/splash-screen-320x480.png"/>
<!-- iPhone/iPod Touch 竖屏 640x960 (Retina) -->
<link rel="apple-touch-startup-image" sizes="640x960" href="/splash-screen-640x960.png"/>
<!-- iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina) -->
<link rel="apple-touch-startup-image" sizes="640x1136" href="/splash-screen-640x1136.png"/>
<!-- IOS end -->
<!-- Windows 8 磁贴颜色 -->
<meta name="msapplication-TileColor" content="#000"/>
<!-- Windows 8 磁贴图标 -->
<meta name="msapplication-TileImage" content="icon.png"/>
<!-- 添加 RSS 订阅 -->
<link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/>
<!-- sns 社交标签 begin -->
<!-- 参考微博API -->
<meta property="og:type" content="类型" />
<meta property="og:url" content="URL地址" />
<meta property="og:title" content="标题" />
<meta property="og:image" content="图片" />
<meta property="og:description" content="描述" />
<!-- sns 社交标签 end -->
低版本IE浏览器访问问题
添加好强制Webkit内核的代码,使用国产浏览器访问网站已经不存在IE兼容问题了,IE访客量将大大减少。但仍然不可避免会有一些老旧电脑通过低版本IE浏览器访问,如果我们专门为了这极小部分用户进行 CSS HACK ,将严重加重我们的工作量。
更何况自2016年1月起微软已经停止为IE11以下版本提供支持和更新,已经这么久没有更新,低版本IE不仅对CSS3和HTML5支持有问题,更有安全问题。
那么,我们不去支持低版本IE,这小部分用户怎么办呢?
我们可以使用 if IE 语句给网站添加IE升级提示,提示用户进行浏览器升级,或者切换更先进的浏览器再访问。
我们可以在刚刚的meta标签下添加一段跳转到IE升级提示页的代码(当IE版本低于IE11时跳转),实现低版本IE用户访问时提示他们进行升级或者更换浏览器。
强制Webkit内核和提示低版本IE访问用户升级完整代码如下所示,把这段代码添加到头部模板文件标签下即可:
<meta name="renderer" content="webkit"/>
<meta name="force-rendering" content="webkit"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<script>/@cc_on window.location.href="http://support.dmeng.net/upgrade-your-browser.html?referrer="+encodeURIComponent(window.location.href); @/</script>
1
2
3
4
(@cc_on 是 IE10 及更旧版IE特有的条件编译语句,因此可以用来判断是否除 IE11 以外的其他IE版本。)
因为低版本IE访问时因为不兼容CSS3和HTML5网站往往是错版的,添加了上面这段代码,当低版本IE用户访问时就会跳转到升级提示页,避免不必要的资源加载,降低网站服务器开销。
测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<meta name="renderer" content="webkit"/>
<meta name="force-rendering" content="webkit"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<script>/@cc_on window.location.href="http://support.dmeng.net/upgrade-your-browser.html?referrer="+encodeURIComponent(window.location.href); @/</script>
</head>
<body>
<h1>Hello world</h1>
</body>
</html>
IE 11 会正常输出
IE 10 将会看到以下页面
参考
前端 Meta 用法大汇总 - MR_LIXP
通过meta代码强制浏览器使用WebKit内核极速模式(解决 meta name=“renderer” content=“webkit” 不起作用)- 艾欢欢
蓝蓝设计的小编 http://www.lanlanwork.com