1、行内元素
(a)—— 标签定义链接
(b)—— 字体加粗
(br)—— 换行
(i)—— 斜体文本效果
(img)—— 在网页中嵌入图片
(input)—— 输入框
(span)—— 组合文档中的行内元素
(small)——呈现小号字体效果
(big)——呈现大号字体效果
(sub)—— 定义下标文本
(sup)—— 定义上标文本
2、块级元素
(div)—— 定义文档中的分区或节
(dl)—— 定义列表
(dt)—— 定义列表中的项目
(dd)—— 定义列表中定义条目
(h1 - h6)—— 定义标题
(hr)创建一条水平线
(ol)—— 定义有序列表
(ul)—— 定义无序列表
(li)—— 定义列表中的项目
(p)—— 定义段落
(table)—— 标签定义 HTML 表格
(tbody)—— 标签表格主体(正文)
(td)—— 表格中的标准单元格
(th)—— 定义表头单元格
(tr)—— 定义表格中的行
(tfoot)—— 定义表格的页脚(脚注或表注)
(thead)—— 标签定义表格的表头
把所有的网页元素都看成一个盒子,它具有: content,padding,border,margin 四个属性,这就是盒子模型
块级元素:块级大多为结构性标记
...
... 地址文字
...
标题一级
...
标题二级
...
标题三级
...
标题四级
...
标题五级
...
标题六级
水平分割线
...
段落
...
预格式化
...
段落缩进 前后5个字符
滚动文本
...
无序列表
...
有序列表
...
定义列表
...
表格
表单
...
行内元素:行内大多为描述性标记
...
... 链接
换行
... 加粗
... 加粗
图片
... 上标
... 下标
... 斜体
... 斜体
... 删除线
... 下划线
... 文本框
多行文本
下拉列表
·块级元素
1.总是从新的一行开始
2.高度、宽度都是可控的
3.宽度没有设置时,默认为100%
4.块级元素中可以包含块级元素和行内元素
·行内元素
1.和其他元素都在一行
2.高度、宽度以及内边距都是不可控的
3.宽高就是内容的高度,不可以改变
4.行内元素只能包含行内元素,不能包含块级元素
行内元素: text-align: center
块级元素: margin: 0 auto
position:absolute +left:50%+ transform:translateX(-50%)
display:flex + justify-content: center
外边距塌陷共有两种情况:
第一种情况:两个同级元素,垂直排列,上面的盒子给 margin-bottom 下面的盒子给margin-top,那么他们两个的间距会重叠,以大的那个计算。解决这种情况的方法为:两个外边距不同时出现
第二种情况:两个父子元素,内部的盒子给 margin-top,其父级也会受到影响,同时产生上边距,父子元素会进行粘连,解决这种情况的方法为:父级添加一个 css 属性,overflow:hidden,禁止超出外边距重叠就是 margin-collapse
解决方案:
1、为父盒子设置 border,为外层添加 border 后父子盒子就不是真正意义上的贴合(可以设置成透明:border:1px solid transparent);
2、为父盒子添加 overflow:hidden;
3、为父盒子设定 padding 值;
4、为父盒子添加 position:fixed;
5、为父盒子添加 display:table;
6、利用伪元素给父元素的前面添加一个空元素
一、css3的新选择器
E:nth-child(n) 选择器匹配其父元素的第n个子元素,不论元素类型,n可以使数字,关键字,或公式
E:nth-of-type(n) 选择与之其匹配的父元素的第N个子元素
E:frist-child 相对于父级做参考,“所有”子元素的第一个子元素,并且“位置”要对应
E:frist-of-type 相对于父级做参考,“特定类型”(E)的第一个子元素
E:empty 选择没有子元素的每个E元素
E:target 选择当前活动的E元素
::selection 选择被用户选取的元素部分
属性选择器
E[abc*=“def”] 选择adc属性值中包含子串"def"的所有元素
二、文本
text-shadow:2px 2px 8px #000;参数1为向右的偏移量,参数2为向左的偏移量,参数3为渐变的像素,参数4为渐变的颜色
text-overflow:规定当文本溢出包含元素时发生的事情 text-overflow:ellipsis(省略)
text-wrap:规定文本换行的规则
word-break 规定非中日韩文本的换行规则
word-wrap:对长的不可分割的单词进行分割并换行到下一行
white-space:规定如何处理元素中的空白 white-space:nowrap 规定段落中的文本不进行换行
三、边框
border-raduis 边框的圆角
border-image 边框图片
.border-image {
border-image-source:url(images/border.png);
boder-image-slice:27;
border-image-width:10px;
border-iamge-repeat:round; (round平铺) 平铺效果不作用于四角,只适应与四边
}
四、背景
rgba
backgrounnd-size:cover/contain,其中background-size:cover,会使“最大”边进行缩放,另一边同比缩放,铺满容器,超出部分会溢出。background-size:contain,会使“最小”边进行缩放,另一边同比缩放,不一定铺满容器,会完整显示图片
五、渐变
linear-gradient
background-image:linear-gradient(90deg,yellow 20%,green 80%)
radial-gradient
background-iamge:radial-gradient(120px at center center,yellow,green)
六、多列布局
column-count
column-width
column-gap
column-rule
七、过渡
transition
transition-property:width //property为定义过渡的css属性列表,列表以逗号分隔
transition-duration:2s; //过渡持续的时间
transition-timing-function:ease;
transition-delay:5s //过渡延迟5s进行
八、动画、旋转
animation
transform :translate(x,y) rotate(deg) scale(x,y)
translate
scale
rotate
skew(倾斜)
九、flex布局
十、@media媒体查询
伪类表示状态 ==> 单冒号 :
伪元素是真的有元素 ==> 双冒号 ::
定义
BFC(Block formatting context)直译为**“块级格式化上下文”**。它是一个独立的渲染区域,
只有 Block-level box 参与,它规定了内部的 Block-level Box 如何布局,并且与这个区
域外部毫不相干
布局规则
1、内部的 Box 会在垂直方向,一个接一个地放置
2、Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin
会发生重叠
3、每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往
右的格式化,否则相反)。即使存在浮动也是如此
4、BFC 的区域不会与 float box 重叠
5、BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反
之也如此
6、计算 BFC 的高度时,浮动元素也参与计算
哪些元素会生成 BFC:
1、根元素
2、float 属性不为 none
3、position 为 absolute 或 fixed
4、display 为 inline-block, table-cell, table-caption, flex, inline-flex
5、overflow 不为 visible
BFC全称是Block Formatting Context,即块格式化上下文。它是CSS2.1规范定义的,关于CSS渲染定位的一个概念。BFC是页面CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。BFC的一个最重要的效果是,让处于BFC内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。利用BFC可以闭合浮动(也可以叫清除浮动),防止与浮动元素重叠。
层叠性
继承性
优先级
将一个页面涉及到的所有图片都包含到一张大图中去,然后利用CSS的 background-image,background-repeat,background-position属性的组合进行背景定位。
【优点】
(1) 减少网页的http请求,提高了页面的性能
(2) 减少图片的大小。合并成1张图片总是小于多张图片的。
【缺点】
(1)在图片合并时,要把多张图片有序的、合理的合并成一张图片,还要留好足够的空间,防止板块内出现不必要的背景。
(2) 在开发的时候相对来说有点麻烦 , 需要借助photoshop
或其他工具来对每个背景单元测量其准确的位置。
em相对于父元素
rem相对于根元素
em和rem相对于px更具有灵活性,他们是相对长度单位,意思是长度不是定死了的,更适用于响应式布局。
px是固定像素,一旦设置了就无法因为适应页面大小而改变
1.首先是数据类型不一样
null是object
undefined是undefined
2.null和undefined两者相等,但是当两者做全等比较时,两者又不等。(因为他们的数据类型不一样)
3.转化成数字不同
null转换成数字是0
undefined转换成数字是NaN
4.null代表“空”,代表空指针;undefined是定义了没有赋值
因为js是单线程的,浏览器遇到setTimeout或者setInterval会先执行完当前的代码块,在此之前会把定时器推入浏览器的待执行事件队列里面,等到浏览器执行完当前代码之后会看一下事件队列里面有没有任务,有的话才执行定时器的代码。所以即使把定时器的时间设置为0还是会先执行当前的一些代码。
1、push()
向数组的末尾添加新内容
参数:要添加的项。传递多个用逗号隔开,任何数据类型都可以
返回值:新增后数组的长度
是否改变原数组:改变
2、pop()
删除数组的最后一项
参数:无
返回值:被删除的项
是否改变原数组:改变
3、shift()
删除数组的第一项
参数:无
返回值:被删除的项
是否改变原数组:改变
4、unshift()
向数组首位添加新内容
参数:要添加的项,多项用’,'隔开
返回值:新数组的长度
是否改变原数组:改变
5、slice()
按照条件查找出其中的部分内容
参数:
array.slice(n, m),从索引n开始查找到m处(不包含m)
array.slice(n) 第二个参数省略,则一直查找到末尾
array.slice(0)原样输出内容,可以实现数组克隆
array.slice(-n,-m) slice支持负参数,从最后一项开始算起,-1为最后一项,-2为倒数第二项
返回值:返回一个新数组
是否改变原数组:不改变
6、splice()
对数组进行增删改
增加:ary.splice(n,0,m)从索引n开始删除0项,把m或者更多的内容插入到索引n的前面
返回值:返回空数组
修改:ary.splice(n,x,m)从索引n开始删除x个,m替换删除的部分
把原有内容删除掉,然后用新内容替换掉
删除:ary.splice(n,m) 从索引n开始删除m个内容
(如果第二个参数省略,则从n删除到末尾)
返回值:返回删除的新数组,原有数组改变
7、join()
用指定的分隔符将数组每一项拼接为字符串
参数:指定的分隔符(如果省略该参数,则使用逗号作为分隔符)
返回值:拼接好的字符串
是否改变原数组:不改变
8、sort()
对数组的元素进行排序(默认是从小到大来排序 并且是根据字符串来排序的)
参数:可选(函数) 规定排序规则 默认排序顺序为按字母升序
返回值:排序后新数组
是否改变原数组:改变
sort在不传递参数情况下,只能处理10以内(个位数)数字排序
9、forEach()
循环遍历数组每一项
参数:函数 ary.forEach(function(item,index,ary){})
item:每一项 index:索引 ary:当前数组
返回值:无
是否改变原数组:不改变
forEach中不能使用continue和break,forEach中不能跳出,只能跳过(return跳过)
Split()是把一串字符(根据某个分隔符)分成若干个元素存放在一个数组里 即切割成数组的形式;join() 是把数组中的 字符串 连成一个长串,可以大体上认为是 Split()的逆操作
apply()
使用格式:函数名.apply(this指向的对象,原函数的参数)
apply会让原函数立刻执行,apply第二参数是一个数组
call()
使用格式:函数名.call(this指向的对象,原始函数的参数列表…)
call()也会让原函数立即执行,call方法从第二个参数开始,传入的参数是原函数的参数
bind()
使用格式:函数名.bind(this指向的对象,原始函数的参数列表…)
会返回一个新的函数,这个函数的内容与原函数一模一样,但是里面的this指向已经被修改了
apply/call/bind 这三种方法的区别
1.apply call 方法会立即执行,而bind方法会返回一个新的函数,函数中的this以及被修改了。
2.apply 和 call方法的区别就在于 传参的形式不同, apply的参数是一个数组,call 和 bind 方法是从第二个参数开始为原函数的参数列表
答案1:
1.全局函数中,this指向window
2.对象的函数中,this指向调用者。
3.事件处理函数中,this指向事件源
4.箭头函数中,this指向父作用域中的this
5.构造函数中,this指向新创建的对象。
6.定时器延时器中,this指向window。
答案2:
1、以函数形式调用时,this 永远都是 window
2、以方法的形式调用时,this 是调用方法的对象
3、以构造函数的形式调用时,this 是新创建的那个对象
4、使用 call 和 apply 调用时,this 是指定的那个对象
5、箭头函数:箭头函数的 this 看外层是否有函数,如果有,外层函数的 this 就是内部箭头函数的 this;如果没有,就是 window
6、特殊情况:通常意义上 this 指针指向为最后调用它的对象。这里需要注意的一点就是如果返回值是一个对象,那么 this 指向的就是那个返回的对象,如果返回值不是一个对象那么this 还是指向函数的实例
GET | POST |
---|---|
只能进行url编码 | 支持多种编码方式 |
请求参数会被完整保留在浏览器历史记录里 | 参数不会被保留 |
在URL中传送的参数是有长度限制的 | 传送的参数的长度没有限制 |
因为参数直接暴露在URL上,所以不能用来传递敏感信息 | 较为安全 |
参数通过URL传递 | 放在Request body(请求体)中 |
cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
存储大小:
cookie数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
有效期时间:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除。
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
闭包就是在一个函数里面创建另一个函数,有权访问另一个函数作用域中的变量的函数(能够读取 另外一个函数作用域中的变量 的函数)
闭包就是能够读取其他函数内部变量的函数。在本质上,闭包就是将函数内部和函数外部连接起来的桥梁。
内存泄露是指任何对象在你不再拥有或需要它之后仍然存在
内存泄露指一块被分配的内存既不能使用、又不能回收,直到浏览器进程结束
1.垃圾回收器定期扫描对象,如果一个对象的引用为0,那么该对象的内存即可回收
2.setTimeout的第一个参数使用字符串而非函数的话,就会引发内存泄露
3.闭包、控制台日志、循环
=答案2=
1.意外的全局变量
2.闭包引起的内存泄露
3.没有清理的DOM元素的引用
4.被遗忘的setTimeout和回调函数
5.子元素存在引起的内存泄露
原型链继承
借用构造函数继承
实例继承
组合式继承
寄生组合继承
es6继承extends
1.在es5中,拼接时如果需要换行,则必须使用转义符;在ES6中,使用模板字符串,可以直接使用html结构即可
2.在ES5中,单引号和双引号必须注意嵌套问题,在ES6中,就不需要考虑;
3.模板字符串中,可以写js语句
4.方便简洁,不容易出错;
答案1:
src:指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置。请求时,会将该资源下载并应用到文档内,
href:指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接
答案2:
src和href之间存在区别,能混淆使用。src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。
src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。
当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。
href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,如果我们在文档中添加
那么浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式。
1.const定义的变量不可以修改,而且使用前必须初始化
2.var定义的变量可以修改,如果不初始化会输出undefined,不会报错
3.let是块级作用域,函数内部使用let定义后,对函数外部无影响。let不能变量提升(let 其实存在变量提升,只是let的特性决定不能在它声明某个变量之前使用该变量)。
200 请求成功
201 请求已经被实现
204 无返回内容
400 服务器未能理解请求
404 请求失败
405 服务器找不到请求页面
500 服务器内部错误
504 网关超时
1.外型不同
2.箭头函数都是匿名函数,普通函数可以是匿名函数也可以是具名函数,但是箭头函数都是匿名函数
3.箭头函数不能用构造函数,不能使用new
4.箭头函数中this的执行不同
在普通函数中,this总是指向调用它的对象,如果用作构造函数,this指向创建的对象实例。
4.1 箭头函数本身没有this,但它可以在声明时捕获其所在上下文的this供自己使用
4.2 箭头函数的 this 永远指向其上下文的 this ,任何方法都改变不了其指向,如 call() , bind() , apply()
5.箭头函数不能Generator函数,不能使用yeild关键字。
6.箭头函数不具有prototype原型对象。
7.箭头函数不具有super。
8.箭头函数不具有new.target。
null
undefined
“”
0
NaN
JavaScript代码运行时,需要分配内存空间来储存变量和值。当变量不在参与运行时,就需要系统收回被占用的内存空间,这就是垃圾回收。
基础数据类型
复杂数据类型:
可以判断出’string’,‘number’,‘boolean’,‘undefined’,'symbol’但判断 typeof(null) 时值为 ‘object’; 判断数组和对象时值均为 ‘object’
原理是构造函数的 prototype 属性是否出现在对象的原型链中的任何位置
常用于判断浏览器内置对象,对于所有基本的数据类型都能进行判断,即使是 null 和 undefined
用于判断是否为数组
假如我们有一个 ul 列表,里面有4个li,我们可以在 li 上绑定 click 事件,但是也可以在她们的 父节点 ul上绑定,这种在 父节点上绑定事件来代替子节点事件的方法,就叫做事件委托。
回调函数:将一个函数作为参数传入,在合适的时候调用,这个函数叫做回调函数。
回调函数主要用于同步异步的处理。
同步:只有当前代码执行完,才能继续执行。
异步:当前代码不会阻塞后面代码的执行。
异步代码在所有的同步代码执行完之后才会执行。
每个函数都有一个作用域链,当查找变量或是函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合就叫作用域链
跨域指浏览器不允许当前页面所在的源去请求另一个源得数据。源指协议,端口,域名。只要这三个中有一个不同就是跨域
优点:
通过异步模式,提升了⽤户体验.
优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占⽤.
Ajax 在客户端运⾏,承担了⼀部分本来由服务器承担的⼯作,减少了⼤⽤户量下的服务器负载。
Ajax 可以实现动态不刷新(局部刷新)
缺点:
安全问题 AJAX 暴露了与服务器交互的细节。
对搜索引擎的⽀持⽐较弱。
不容易调试。
深拷贝拷贝的是值,如果你修改了拷贝之后的数据,原数据不会受到影响(相当于剪切)
浅拷贝拷贝的是地址,如果你修改了拷贝之后的数据,原数据会受到影响(就相当于创建一个快捷方式)
1.递归
递归去复制所有层级属性
2.JSON对象的parse和stringify
JSON.parse.stringify()
3.JQ的extend方法
$.extend( [deep ], target, object1 [, objectN ] )
deep:表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target:Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1:objectN可选。 Object类型 第一个以及第N个被合并的对象。
参考资料:https://www.cnblogs.com/shj-com/p/13645276.html
强制
1.转换成字符串 toString() String()
2.转换成数字 Number() parselnt() parseFloat()
3.转换成布尔类型 Boolean()
隐式
1.拼接字符串
var str = "" + 18
-、/、%、=、
== 表示相等 (值相等)
=== 表示恒等**(类型和值都要相等)**
js在比较的时候如果是 == 会先做类型转换,再判断值得大小,如果是===类型和值必须都相等。
window.onscroll onresize onmousemove(拖拽效果) onkeyup(搜索框的按键)这些事件频繁被触发,导致重复执行DOM操作、资源加载等重行为、会导致UI停顿甚至浏览器崩溃。
防抖:当事件快速连续不断触发时,动作只会执行一次
节流: 降低触发的频率。比如:onmousemove原本1s触发100次,现在让它1s触发20次
1、Promise是一种异步编程的解决方案,有三种状态,pending(进行中)、resolved(已完成)、rejected(已失败)。当Promise的状态由pending转变为resolved或reject时,会执行相应的方法
2、Promised的特点是只有异步操作的结果,可以决定当前是哪一种状态,任务其他操作都无法改变这个状态,也是“Promise”的名称的由来,同时,状态一旦改变,就无法再次改变状态
e.stopPropagation(); // 阻止冒泡
e.preventDefault(); // 阻止默认事件
navigator 对象存储了与浏览器相关的基本信息,如名称、版本和系统等。通过 window.navigator 可以引用该对象,并利用它的属性来读取客户端基本信息。
如何检测浏览器?
检测浏览器类型的方法有多种,常用的方法包括两种:特征检测法和字符串检测法。这两种方法都存在各自的优点和缺点
参考资料:http://c.biancheng.net/view/5850.html
回调地狱
①let const
②模板字符串
③解构赋值
④扩展运算符
⑤箭头函数
⑥class类
⑦promise
⑧导入import、导出export default
⑨async/await
参考资料:https://www.cnblogs.com/wang–chao/p/14656871.html
参考资料:https://www.jianshu.com/p/ac1787f6c50f
合并数组
合并对象
函数传值
配合解构使用
当url地址的hash值改变时,就会去路由表中进行匹配,进而找到路由对应的组件,将组件的模板渲染在
对应的位置。
computed
1.支持缓存,只有依赖的数据发生改变才会重新计算;
2.不支持异步,当computed内有异步操作时无效
3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
4.如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
watch
1.不支持缓存,数据一旦发生变化,直接会触发相应的操作;
2.watch支持异步;
3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4.当一个属性发生变化时,需要执行对应的操作;一对多;
5.监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
immediate:组件加载立即触发回调函数执行,
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
Computed watch 区别就是computed的缓存功能,当无关数据数据改变时,不会重新计算,
直接使用缓存中的值。只有它依赖的属性值发生改变,在下一次获取 computed 的值时才会重新计算 computed 的值。
Watch监听的是在data中定义的变量,当该变量变化时,会触发watch中的方法
运用场景:
① 当我们需要进行数值计算,并且依赖于其它数据时,可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。
② 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch。使用watch可以在得到结果前设置一个中间状态、操作异步等这些计算属性是做不到的
data的值更新的时候,DOM并不会立即更新,如果你把代码放在nextTick中执行,那么当data数据更新的时候DOM也会跟着更新。
如果data是一个函数的话,这样每复用一次组件,就会返回一个新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据,而单纯的写成对象形式,就使得所有的组件实例共用了一份data,就会造成一个变了全都会变得结果。
所以说vue组件中的data必须是函数,这都是因为js的特性带来的。
js本身的面对对象变成也是基于原型链和构造函数应该会注意原型链上添加一般都是一个函数方法而不会去添加一个对象了。
每个实例可以维护一份被返回对象的独立拷贝
props / $emit
$emit / $on
vuex
$attrs / $listeners
**$provide / $inject *祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。其主要解决了跨级组件间的通信问题
$parent / $children & $ref
常见使用场景可以分为三类:
父子通信: 父向子传递数据是通过 props,子向父是通过 events( $emit);通过父链 / 子链也可以通信( $parent / $children);ref 也可以访问组件实例;provide / inject API; a t t r s / attrs/ attrs/listeners
兄弟通信: Bus;Vuex
跨级通信: Bus;Vuex;provide / inject API、 a t t r s / attrs/ attrs/listeners
state, getters, mutations, actions, modules。
1. state:vuex的基本数据,用来存储变量
2. geeter:从基本数据(state)派生的数据,相当于state的计算属性
3. **mutation:**提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
4. **action:**和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
5. **modules:**模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
===============================================================
有五种,分别是 State、 Getter、Mutation 、Action、 Module
state = 基本数据(数据源存放地)
getters = 从基本数据派生出来的数据
mutations = 提交更改数据的方法,同步!
actions = 像一个装饰器,包裹mutations,使之可以异步。
modules = 模块化Vuex
共同点:
v-if 和 v-show 都能实现元素的显示隐藏
区别:
1. v-show 只是简单的控制元素的 display 属性,而 v-if 才是条件渲染(条件为真,元素将会被渲染,条件为假,元素会被销毁);
2. v-show 有更高的首次渲染开销,而 v-if 的首次渲染开销要小的多;
3. v-if 有更高的切换开销,v-show 切换开销小;
4. v-if 有配套的 v-else-if 和 v-else,而 v-show 没有
5. v-if 可以搭配 template 使用,而 v-show 不行
**用法:**query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this. r o u t e . q u e r y . n a m e 和 t h i s . route.query.name和this. route.query.name和this.route.params.name。
**url地址显示:**query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
注意点:
query刷新 不会 丢失query里面的数据
params刷新 会 丢失 params里面的数据。
v-show 则是不管值为 true 还是 false ,html 元素都会存在,只是 CSS 中的 display 显示或隐藏
mounted
全局前置守卫
全局解析守卫
全局后置守卫
路由独享守卫
组件内守卫
beforeRouterEnter
beforeRouterUpdate
beforeRouterLeave
1,this. r o u t e r . p u s h ( ) 路 由 跳 转 2. t h i s . router.push()路由跳转 2.this. router.push()路由跳转2.this.router.replace()路由替换
3.this. r o u t e r . b a c k ( ) 返 回 4. t h i s . router.back()返回 4.this. router.back()返回4.this.router.forword()前进
.prevent: 提交事件不再重载页面;
.stop: 阻止单击事件冒泡;
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用
v-bind用来绑定数据和属性以及表达式
v-model使用在表单中,实现双向数据绑定的,在表单元素外不起使用。
v-model原理:我们在vue项目中主要使用v-model指令在表单 input、textarea、select、等表单元素上创建双向数据绑定, v-model本质
Router
路由对象,用来进行路由跳转
Route
路由记录对象,只读,存储了与路由相关的信息
的作用是什么?1.keep-alive组件
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染,提升页面性能
从缓存中调用出来
2.举例
在tab切换中,切换三个组件,不用keep-alive,每个组件在重新显示时,都会再执行created,并重复发起请求。如果在外面包裹keep-alive, 则初次创建后会缓存组件,再次显示,不会再执行created,而是直接显示缓存的内容,不会再重复发起请求。
1.什么是动态路由
能够传递参数的路由就是动态路由
2.具体实现
2.1 路由配置中设置path选项为/url/:属性名
2.2 传递参数:在url后加/加参数
3.在组件中接收参数
this.$route.params.属性名
如果组件会被销毁,则再created中接受参数
如果组件复用,但传参不同时,则用watch来监听路由的变化
v-html
v-text
v-bind:title :title
v-if
v-else
v-show
v-cloak
v-model
v-on
v-for
v-once:只渲染一次,数据改变,视图更新,但v-once对应的元素不会再更新
v-slot
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。
用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue3中用ES6的proxy对象替换了Object.defineProperty(), 因为Object.defineProperty()只能劫持一个属性,而proxy可以劫持对象的所有属性
pop()
push()
shift()
unshift()
sort()
splice()
reverse()
//===数据更新
数组、索引、新值
//===对象的更新检测
对象、属性、新值
需要使用key值来给每一个节点做一个唯一的标识,Diff算法就可以正确的识别该节点,找到正确的位置区域插入节点。简单的来说,key值的作用主要是为了高效的更新虚拟DOM
另外,vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果
@click.修饰符
1. @click.stop 阻止冒泡
2. @click.prevent 阻止浏览器默认行为
3. @click.once 只执行一次
4. @keyup.键名 (13,enter都是指回车键, 38: 上箭头)
5. @click.self 当事件发生在该元素本身而不是子元素的时候会触发;
6. @click.capture 在事件捕获阶段触发事件处理程序
1.获取数据
2.根据数据创建VDOM (相当于给对象赋值)
3.根据VDOM渲染生成真实DOM ( 根据createElement(‘DIV’) )
4.当数据发生改变后,又会生成新的VDOM
5.通过 diff 算法 比对 多次生成的 VDOM, 将不同的内容比对出来,然后再进行真实DOM渲染,
一样的内容是不会进行渲染的,这就是VDOM 的 ‘就地复用’ | ‘惰性原则’
计算属性computed和方法methods的区别
计算属性和方法都是函数,计算属性一定有返回值,它通过对数据进行处理,返回一个结果
在模板中调用时,计算属性不加(),而methods必须需要加()
计算属性和方法最主要的区别是计算属性有缓存功能。
方法被调用时每次都要重复执行函数
计算属性初次调用时执行函数,然后会缓存结果。当再次被调用时,如果依赖的响应式数据没有发生改变,则直接返回之前缓存的结果 。如果依赖发生了改变,则会再次执行函数并缓存结果
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
watch:
computed的应用场景: 过滤后台数据,只显示男生信息
watch的应用场景 : 楼层导航,切换楼层时,监听楼层索引的变化,调整滚动条位置
1、父传子:父组件中通过v-bind绑定一个属性,子组件中通过props接收父组件中的绑定的属性
2、子传父:子组件通过广播的方式$emit发送自定义事件,将值传递给父组件,父组件监听事件,触发一个函数去接收子组件中传递过来的值
3、兄弟间传值:
(1) 通过父组件中转来传值,即A和B是兄弟组件,可以A传给父组件,由父组件再传给B
(2) new一个Bus实例,通过$emit传递数据,通过$on监听获取数据
(3) vuex
4、使用vuex状态管理,可以实现数据的随意存储和获取
如果应用比较简单,就不需要使用Vuex,直接使用父子组件传值及其它传值方式即可,使用Vuex就要额外的引入vuex的框架,可能是繁琐冗余的
如果需要构建一个中大型单页应用,就可以使用vuex更好地在组件外部管理状态
大型项目中如果使用bus总线,会使代码逻辑非常混乱
- {{item}}
这是一个段落
普通组件
路由组件
在vue.config.js中通过proxy代理,实现跨域
module.exports = {
......
devServer: {
// 代理
proxy: {
'/api': {
target: 'http://localhost:3000/',
changeOrigin: true,
//根据具体需求可选择把url中的/api部分替换为空
//pathRewrite: {
// '^/api': ''
//}
}
}
}
}
在线上环境使用nginx实现服务器代理
单页Web应用(single page web application,SPA): SPA 是一种特殊的 Web 应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的。它将所有的活动局限于一个 Web 页面中,仅在该 Web 页面初始化时加载相应的 HTML 、 JavaScript 、 CSS 。一旦页面加载完成, SPA 不会因为用户的操作而进行页面的重新加载或跳转,而是利用 JavaScript 动态的变换 HTML(采用的是 div 切换显示和隐藏),从而实现UI与用户的交互。在 SPA 应用中,应用加载之后就不会再有整页刷新。相反,展示逻辑预先加载,并有赖于内容Region(区域)中的视图切换来展示内容。
vue.js
vue-router.js
vue-cli
axios
vuex
声明式导航: 通过
的to属性来声明要跳转的路由
编程式导航: 通过this.$router
的相应方法来实现跳转 push
replace
go()
1.用户填写登录信息,发起请求,服务端收到请求,去验证用户名与密码
2.验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
3.客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
4.客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
5.服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
实现步骤:
在路由配置中,需要给登录进入的路由添加meta元信息
{
path: '/cart',
component: cart,
meta: {
title: '购物车',
Auth: true //购物车需要授权
}
}
在全局前置导航守卫中实现授权验证
to: 即将进入的路由 ($route路由记录)
from: 来自哪个路由
next: 是一个函数,可以控制路由是否跳转
router.beforeEach((to,from,next)=>{
let token = localStorage.getItem("token")
if (to.matched.some(record=>record.meta.Auth)){
if (token){
next()
}else{
next("/login")
}
}else{
next()
}
})
调用后端接口携带token
//添加请求拦截器,会在发起请求之前执行相应的需求
axios1.interceptors.request.use(function (config) {
let token = localStorage.getItem("token")
if (token){
config.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem("token");
}
return config;
}, function (error) {
return Promise.reject(error);
});
//添加响应拦截器,会在返回数据后先执行相应的需求
axios1.interceptors.response.use(function (response) {
return response;
}, function (error) {
return Promise.reject(error);
});
hash: 地址栏中有#
history: 地址栏没有#,更好看一些
改变模式,添加mode选项,默认是hash
hash: 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
history: 如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
在路由配置中,一级路由中添加children选项,来配置嵌套路由
const routes = [
{
path: '/home',
component: ()=> import(路由组件的地址),
children: [
{
path: 'star',
component: Star
}
]
}
]
在父组件中,通过
跳转到该嵌套路由
该嵌套路由对应的出口
是在它的父级路由组件中定义的
应用场景 : 在一个路由组件中滚动页面,切换到另一个组件中时,滚动条自动恢复到页面顶端的位置
下面的代码要加在router对象的配置中
//创建路由对象
const router = new VueRouter({
routes,
scrollBehavior(to, from) {
return { x: 0, y: 0 }
}
})
具名插槽
匿名插槽
作用域插槽
使当前组件的样式不会和其他组件冲突,因为它会给每个组件相关的选择器添加不会重复的属性
登录(login,所有人均可见)--------->登录成功,获取权限-------->权限不同,侧边栏的数据展示不同
先定义一份公共的路由表,里面仅有一些公共的路由,如 login
获取到权限后,我们根据权限,得到需要动态添加的路由表,把这份路由表动态添加到router中即可。
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 (opens new window)就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
1.Vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
2.Vuex怎么使用
在main.js引入store,注入。新建了一个store目录,然后…… export
在哪种功能场景下使用
state
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
mutations
mutations定义的方法动态修改Vuex 的 store 中的状态或数据。
getters
类似vue的计算属性,主要用来过滤一些数据。
action
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。
modules
项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
五个核心概念
如何在页面中使用
1.new一个Vuex.Store()
2.在state中存储共享的数据
// 集中存储的整个应用中共享的数据
state: {
msg: '共享的数据',
city: '郑州',
flowerList: []
},
3.在action中请求数据,请求数据的时候会传递两个参数,一个参数ctx是上下文,一个是index.vue传进来的参数,commit需要通过第一个参数(上下文)来触发,commit中第一个参数是在mutation中定义的方法,第二个是数据
actions:{
getData(ctx,payload){
let { page }= payload
axios.get(`http://localhost:3000/flowerList?_page=${page}&_limit=30`)
.then(res=>{
ctx.commit("updateFlowerList",res.data)
})
}
},
4.所有的方法都需要在mutation中配置
mutations: {
updateCity(state,city){
state.city = city
},
updateFlowerList(state,data){
state.flowerList = data;
}
},
5.如果需要对state中的数据进行过滤时,就需要用到getters
getters: {
flowerList(state){
return state.flowerList.filter(item=>item.sales>10000)
}
}
mapState
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键
mapGetters
仅仅是将 store 中的 getter 映射到局部计算属性
mapActions
mapMutations
1.如何使用辅助函数
在当前组件中引入Vuex
通过Vuex来调用辅助函数
2.辅助函数具体使用方法
**mapState:**把state属性映射到computed身上
**mapAcions:**把actions里面的方法映射到methods中
**mapMutations:**把mutations里面的方法映射到methods中
**mapGetters:**把getters属性映射到computed身上
参考资料:https://www.cnblogs.com/xixinhua/p/10421673.html
一、在项目创建store文件夹,及index.js
定义相关的vuex的state, getters actions mutations
二、在入口文件main.js中引入store,并在根实例注册
三、在任一组件中,通过this.$store.state就可以访问到共享数据
四、当通过组件要修改store中的数据时,
如果该操作是同步的,可以用this.$store.commit()来触发mutations, 只有mutations才可以直接更改state共享数据
mutations中只能有同步操作,不能有异步操作
如果修改数据的操作是异步的,通过this.$store.dispatch()触发actions, actions中可以发起异步请求,获取数据后,再调用 commit触发mutations,通过mutations修改共享数据
Git | SVN |
---|---|
1. Git是一个分布式的版本控制工具 | 1. SVN 是集中版本控制工具 |
2.它属于第3代版本控制工具 | 2.它属于第2代版本控制工具 |
3.客户端可以在其本地系统上克隆整个存储库 | 3.版本历史记录存储在服务器端存储库中 |
4.即使离线也可以提交 | 4.只允许在线提交 |
5.Push/pull 操作更快 | 5.Push/pull 操作较慢 |
6.工程可以用 commit 自动共享 | 6.没有任何东西自动共享 |
我建议你先通过了解 git 的架构再来回答这个问题,如下图所示,试着解释一下这个图:
方式一:
.normal-field /deep/ .el-form-item {
margin-bottom: 0px;
}
方式二:
.normal-field ::v-deep .el-form-item {
margin-bottom: 0px;
}
可以进行文件合并、文件压缩使文件最小化
可以使用CDN托管文件、让用户更快速的访问;
可以使用多个域名来缓存静态文件
1.react中点击表单中编辑按钮的时候,浏览器报date.clone错误。开始觉得是日期没有格式化,但是格式化之后依然报错。后来发现是moment后面不能加format。
tions才可以直接更改state共享数据
mutations中只能有同步操作,不能有异步操作
如果修改数据的操作是异步的,通过this.$store.dispatch()触发actions, actions中可以发起异步请求,获取数据后,再调用 commit触发mutations,通过mutations修改共享数据
Git | SVN |
---|---|
1. Git是一个分布式的版本控制工具 | 1. SVN 是集中版本控制工具 |
2.它属于第3代版本控制工具 | 2.它属于第2代版本控制工具 |
3.客户端可以在其本地系统上克隆整个存储库 | 3.版本历史记录存储在服务器端存储库中 |
4.即使离线也可以提交 | 4.只允许在线提交 |
5.Push/pull 操作更快 | 5.Push/pull 操作较慢 |
6.工程可以用 commit 自动共享 | 6.没有任何东西自动共享 |
我建议你先通过了解 git 的架构再来回答这个问题,如下图所示,试着解释一下这个图:
[外链图片转存中…(img-SNX7PMqb-1637237304696)]
方式一:
.normal-field /deep/ .el-form-item {
margin-bottom: 0px;
}
方式二:
.normal-field ::v-deep .el-form-item {
margin-bottom: 0px;
}
可以进行文件合并、文件压缩使文件最小化
可以使用CDN托管文件、让用户更快速的访问;
可以使用多个域名来缓存静态文件
1.react中点击表单中编辑按钮的时候,浏览器报date.clone错误。开始觉得是日期没有格式化,但是格式化之后依然报错。后来发现是moment后面不能加format。