一阶段
- 1.网络中使用最多的图片格式有哪些
- gif 支持动画,只有全透明和不透明两种模式,只有256种颜色
- jpg 采用有损压缩算法,体积较小,不支持透明,不支持动画
- png 采用有损压缩算法,体积也相对较小,支持透明背景,不支持动画
- svg 一般会保存颜色及形状相对简单的图片,可任意放大图形显示,边缘异常清晰
- BMP 无损压缩格式,画质最好,文件太大,不利于网络传输
- 2.请简述css盒子模型
- 在网页中,一个元素占有空间的大小由几个部分构成,其中包括元素的内容(content),元素的内边距(padding),元素的边框(border),元素的外边距(margin)四个部分,这就是盒子模型。
- 3.视频/音频标签的使用
- 视频
<video src="课堂示例/qr.ogg" controls height="300" autoplay loop muted></video>
- 属性: controls 控件、autoplay: 自动播放 谷歌和火狐静音下支持 ie支持、muted 静音播放、loop 循环、poster 未播放前显示的内容
- 音频
<audio src="课堂示例/梦然-少年.mp3" controls autoplay loop muted></audio>
- 属性: controls 控件、autoplay 自动播放 谷歌不支持,火狐静音下支持 ie支持、loop 循环播放、muted 静音播放
- 视频
- 4.HTML5新增的内容有哪些
- h5的语法
- DOCTYPE可以使用小写
- 单标签没有结束标签
- 可以省略结束的标签: li、dt、dd、p、option、colgroup(用于对表格中的列进行组合,以便对其进行格式化)、thead、tbody、tfoot、tr、td、th
- 可以省略的标签 html head body tbody
- 新增标签 特点:语义化,ie8及以下不生效
- header标签 头部
- section 划分板块
- article 与上下文无关的内容
- aside 可以放侧边工具栏
- nav 导航
- figure和figcaption 类似于dl标签
- footer 底部
- main 比较重要的部分
- mark 标记 默认是黄色的高亮,可以修改样式 内联
- 多媒体标签
- 音频
<audio src="课堂示例/梦然-少年.mp3" controls autoplay loop muted></audio> 内联 <audio controls> <source src="课堂示例/梦然-少年.ogg" type="audio/ogg"></source> <source src="课堂示例/梦然-少年.mp3" type="audio/mpeg"></source> 你的浏览器不支持此文件,换个电脑吧 </audio>
- controls 控件
- autoplay 自动播放 谷歌不支持,火狐静音下支持 ie支持
- loop 循环播放
- muted 静音播放
- 视频
<video src="课堂示例/qr.ogg" controls height="300" autoplay loop muted> </video> <video controls> <source src="课堂示例/wje.mp4" type="video/mp4"></source> <source src="课堂示例/wje.ogg" type="video/ogg"></source> <source src="课堂示例/wje.webm" type="video/webm"></source> </video>
- controls 控件
- autoplay: 自动播放 谷歌和火狐静音下支持 ie支持
- muted 静音播放
- loop 循环
- poster 未播放前显示的内容
- 音频
- 表单新增
- type类型
- email 邮件格式
- number 限制输入是数字 min最小值 max最大值 step 每次增加的数
- url 地址 路径或者网址都可以
- color 色块
- time 时间
- range 滑动条
- 属性
- required 必填
<input type="text" required autofocus>
- placeholder 提示信息
- autocomplete 自动提示 on提示 off不提示
<input type="text" name="test" autocomplete="on" >
- autofocus 自动聚焦 只能写一个
- multiple 多选
<input type="file" multiple>
- pattern 正则 限制输入的内容类型
<input type="text" pattern="[0-9]"> 限制输入0-9之间的数
- required 必填
- type类型
- h5的语法
- 5.HTML5 新增的语义化标签有哪些
- header 头部
- section 划分板块
- article 与上下文无关的内容
- aside 可以放侧边工具栏
- nav 导航
- figure和figcaption 类似于dl标签
- footer 底部
- main 比较重要的部分
- mark 标记 默认是黄色的高亮,可以修改样式 内联
- 6.Css3新增的特性
- css3选择器
- 属性选择器
- [属性名] 可以选择到官方或者自定义的属性
- [属性名=“属性值”] 匹配属性值
- [属性名~=""] 包含该值 必须单独出现的
- [属性名*=""] 只要包含该值就行
- [属性名^=""] 以该值开头
- [属性名$=""] 以该值结尾
- 伪类选择器
- 结构性伪类选择器(child系列)
- E:first-child E必须是父元素里面的第一个孩子
- E:last-child E必须是父元素里面的最后一个孩子
- E:nth-child(n) 不匹配前面的元素类型,如果对应的位置是该元素才匹配
- E:only-child 必须只有他自己一个孩子
- 结构性的伪类选择(type系列)
- E:first-of-type 匹配到该元素中的第一个孩子
- E:last-of-type 匹配到该元素的最后一个孩子
- E:nth-of-type(n) 匹配到该元素的第几个孩子
n可以是表达式 2n 3n 2n+1 even(偶数) odd(奇数) - E:nth-last-of-type(n) 匹配到该元素的倒数第几个
- 目标伪类:结合锚点使用
- 状态伪类选择器
- :enabled 元素可编辑
- :disabled 元素不可编辑
- :checked 选中
- ::selection 高亮状态 一般修改字体颜色和背景色
- 动态伪类选择器
- :link 未访问前
- :visited 访问过后
- :hover 鼠标滑过
- :active 鼠标点击之后
- 结构性伪类选择器(child系列)
- 层级选择器
- 后代选择器 选择器 选择器
- 子项选择器 选择器>选择器
- 相邻的兄弟 选择器+选择器 紧挨着的兄弟
- 相邻的兄弟们 选择器~选择器 紧挨着的弟弟们
- 属性选择器
- css3属性
- 阴影
- box-shadow:x轴偏移 y轴偏移 模糊距离 阴影的颜色 阴影的位置(outset/inset);
- text-shadow:x轴偏移 y轴偏移 模糊距离 阴影的颜色;
- 透明
- rgba 设置透明度
- 里面的内容不会被模糊
- opacity:0-1; 0完全透明 1不透明
- 里面的内容也会被模糊
- 可以设置图片的模糊
- 过渡效果对display的隐藏和出现没有效果,可以通过设置opacity的值
- rgba 设置透明度
- 背景
- 背景图的原点 background-origin
- padding-box 默认值 背景图从padding区域开始显示
- content-box 背景图从content区域开始显示
- border-box 背景图从border边框区域开始显示
- 背景图的裁切 background-clip
- border-box 边框之外裁切
- padding-box padding之外裁切
- content-box 内容区开始裁切
- 背景图大小的设置 background-size
- 圆角 border-radius
- 一个值 四个角
- 两个值 对角
- 三个值 左上角 右上角/左下角 右下角
- 四个值 左上角 右上角 右下角 左下角(顺时针的角度)
- 正圆 border-radius: 50%/100%;
- 图片边框 border-image
- border-image:图片路径 偏移 重复
- border-image-source:url() 图片的路径
- border-image-slice:数值 图片的裁切 不要加单位
- border-image-repeat:平铺(repeat) 铺满(round) 拉伸(stretch)默认
- 过渡 transition:transition-property transition-duration transition-delay transition-timing-function(顺序不固定,当只有一个时间的时候,表示过渡时间,两个时间第一个表示过渡时间,第二个表示延迟时间)
- transition-property 需要过渡的属性
- transition-duration 过渡所需要的时间 s(秒)/ms(毫秒) 1s=1000ms
- transition-delay 过渡延迟时间 s(秒)/ms(毫秒)
- transition-timing-function 过渡效果
- linear: 匀速
- ease: 逐渐慢下来
- ease-in: 加速
- ease-out: 减速
- ease-in-out 先加速后减速
- 动画 animation:animation
-
使用:animation: 动画名 动画持续时间 延迟时间 动画效果 执行次数
- animation-name: 动画名
- animation-duration: 动画的持续时间 s/ms
- animation-delay: 动画的延迟时间 s/ms
- animation-timing-function: 动画的效果
- animation-iteration-count: 具体的数值/infinite(无限循环)
- anmiation-direction: 动画执行的方向
- normal 正向
- reverse 反向
- alternate 正向和反向交替运动
- animation-play-state 动画是否播放
- running 播放默认值
- paused 暂停
-
定义动画
@keyframes 动画名{ from{} ==>0% to{}==>100% } 关键帧分的是时间 @keyframes 动画名{ 0%{ css属性:css属性值 } 10%{} 0.5s 20%{} 1s 30%{} 100%{} }
-
- 渐变
- 线性渐变
- background-image/background:linear-gradient(方向,颜色1,颜色2……)
- 渐变方向
- to bottom 向下
- to right 向右
- to top 向上
- to left 向左
- to right bottom 向右下角
- to left top 向左上角
- to right top 向右上角
- to left bottom 向左下角
- 数值+deg(角度)
- 设置百分比
/* 0%-40% 是红色的纯色 40%-60% 红色到蓝色渐变 60%-100% ;蓝色的纯色*/ background: linear-gradient(red 40%, blue 60%);
- 重复性的线性渐变
- background:repeating-linear-gradient(red 40%, blue 60%);
- 径向渐变
- bakrgound-image/background:radial-gradient(位置,颜色1,颜色2)
- 位置
- center 中心
- 水平方向:left/center/right
- 垂直方向:top/center/bottom
- 兼容写法
background: radial-gradient(left, red, blue); background: -webkit-radial-gradient(left, red, blue); background: -ms-radial-gradient(left, red, blue);
- 重复性的径向渐变
- background: repeating-radial-gradient(red 20%, yellow 40%);
- 线性渐变
- 阴影
- css3选择器
- 7.清除浮动的方式有哪些?请说出各自的优点
- 额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear:both)不推荐
- 优点:通俗易懂,方便
- 缺点:添加无意义标签,语义化差
- 父级添加overflow属性(overflow:hidden)不推荐
- 优点:代码简洁
- 缺点:内容增多的时候容易造成不会自动换行导致内容被隐蔽掉,无法显示要溢出的元素
- 给父级设置高度
- 优点:简单,代码少,容易掌握
- 缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题
- 父级div定义overflow:auto(必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度)
- 优点:简单,代码少,浏览器支持好
- 缺点:内部宽高超过父级div时,会出现滚动条。
- 使用after伪元素清除浮动 (推荐使用)
.clear:after{ content:""; display:block; clear:both; height:0; overflow:hidden; visibility:hidden }
- 优点:符合闭合浮动思想,结构语义化正确
- 缺点:ie6-7不支持伪元素:after,使用zoom:1触发hasLayout
- 额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear:both)不推荐
- 8.定位的属性值有何区别
- static 默认值
- relative 相对定位,参考自己本身的位置,不会脱离文档流,文字不能被遮挡
- absolute 绝对定位,参考有定位属性(除了static)的祖先元素,定位元素通过一层一层向上找,找到有定位的祖先元素,如果找到body依然没有找到有定位的祖先元素,参考浏览器窗口(子绝父相),脱离文档流,且文字能被遮挡,块级元素设置margin:0 auto;会失效,内联元素设置定位转换成块元素
- fixed 固定定位,参考浏览器的窗口,不会跟随滚动条的滚动而滚动,脱离文档流,
宽度自适应的时候,宽度不显示,可以通过设置width:100% - 粘性定位 sticky,参考浏览器的窗口,没有达到top值之前正常显示,达到top值之后类似于固定定位,不会跟随滚动条滚动而滚动
- 9.子元素如何在父元素中居中
- 定位+margin:auto 父元素position: relative 子元素position: absolute left:0;top:0;right:0;bottom:0;margin: auto;
- 定位+margin-left+margin-top 父元素position: relative 子元素position: absolute left:50%; top:50%; margin-left: -当前盒子宽度的一半; margin-top: -当前盒子高度的一半;
- 定位+transfrom(子元素未知宽高) 父元素 position: relative 子元素 position: absolute left:50%; top:50%; transform: translate(-50%,-50%);
- 弹性盒子 父元素 display: flex; justify-content: center; align-items: center;
- flex+margin: auto 父元素 display: flex; 子元素 margin:auto;
- 10.border-box与content-box的区别
- border-box
- padding和border被包含在定义的width和height之内。
- 对象的实际宽度就等于设置的width值,即使定义有border和padding也不会改变对象的实际宽度;即 ( Element width = width + margin)
- 此属性表现为怪异模式下的盒模型
- content-box
- padding和border不被包含在定义的width和height之内。
- 对象的实际宽度等于设置的width值和border、padding之和;即 ( Element width = width + border + padding + margin)
- 此属性表现为标准模式下的盒模型
- border-box
- 11.元素垂直居中
- 如果是图片,直接设置img的属性vertical-align: middle;前提是需要设置父级元素为块级元素并且设置高度
- 如果是单行文本,可以通过设置子元素的line-height值等于父元素的height,这种方法适用于子元素为单行文本的情况。
- 通过定位父元素 position: relative 子元素 position: absolute top:50%; transform: translateY(-50%);
- 通过伪元素:before实现CSS垂直居中
父元素:before{ content:""; display:inline-block; vertical-align:middle; height:100%; }
- 通过display:table实现,给父元素设置display:table,子元素display:table-cell的方式实现CSS垂直居中
- 通过display:flex实现,给父元素设置display:flex; 子元素 align-self:center
- 12.如何让chrome浏览器显示小于12px的文字
- -webkit-transform:scale(0.833); 0.833 是缩放比例
- 13.Css选择器有哪些,哪些属性可以继承,优先级如何计算?css3新增的伪类有哪些
- css选择器
- id 选择器( # myid)
- 类选择器(.myclassname)
- 标签选择器(div, h1, p)
- 相邻选择器(h1 + p)
- 子选择器(ul > li)
- 后代选择器(li a)
- 通配符选择器( * )
- 属性选择器(a[rel = “external”])
- 伪类选择器(a: hover, li: nth - child)
- 可以继承
- 字体类:
- font-family:字体类型;
- font-weight:字体加粗;
- font-size:字体大小
- font-style: 字体样式
- 文本类:
- color:颜色
- text-indent: 缩进(只对块级元素生效)
- text-align:对齐方式
- line-height:行高
- word-spacing:字之间的距离;
- letter-spacing:字符之间的距离;
- text-decoration:文本修饰
- 列表:
- list-style-type:列表类型
- list-style-image:图标路径
- list-style-position:图标的位置
- list-style:none;去掉列表符号
- 字体类:
- 优先级就近原则,样式定义最近者为准; 载入样式以最后载入的定位为准;
- 优先级为: !important > id > class > tag(标签选择器) important 比 内联优先级高
- css3新增的伪类
- 结构性伪类选择器(child系列)
- E:first-child E必须是父元素里面的第一个孩子
- E:last-child E必须是父元素里面的最后一个孩子
- E:nth-child(n) 不匹配前面的元素类型,如果对应的位置是该元素才匹配
- E:only-child 必须只有他自己一个孩子
- 结构性的伪类选择(type系列)
- E:first-of-type 匹配到该元素中的第一个孩子
- E:last-of-type 匹配到该元素的最后一个孩子
- E:nth-of-type(n) 匹配到该元素的第几个孩子
n可以是表达式 2n 3n 2n+1 even(偶数) odd(奇数) - E:nth-last-of-type(n) 匹配到该元素的倒数第几个
- 目标伪类:结合锚点使用
- 状态伪类选择器
- :enabled 元素可编辑
- :disabled 元素不可编辑
- :checked 选中
- ::selection 高亮状态 一般修改字体颜色和背景色
- 动态伪类选择器
- :link 未访问前
- :visited 访问过后
- :hover 鼠标滑过
- :active 鼠标点击之后
- css选择器
- 14.网页中有大量图片加载很慢 你有什么办法进行优化?
- 图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载
- 如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载
- 如果图片为css图片,可以使用CSSsprite(精灵图),SVGsprite(精灵图),Iconfont(字体图标)(精灵图,小图标…)
- 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验
- 如果图片展示区域小于图片的真实大小,则应该在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致
- 15.行内元素/块级元素有哪些?
- 行内元素在同一行显示,不可以设置宽高,宽高由内容撑开,padding margin 左右显示准确,上下显示不准确,margin:0 auto,不生效,可以给内联元素添加一个外层的盒子形成一个大的区域,给该盒子设置text-align:center的居中属性,添加浮动可以解决内联元素之间的间歇,也能将内联元素的元素类型转换为块元素,例如span b strong i em a u del img
- 块级元素可以设置宽高,盒模型属性都生效,独占一行,一般作为容器,例如:ES6新增的header footer section等以及常用的div p ul li h1-h6 ol dl dt dd
- 16.浏览器的标准模式和怪异模式区别?
- 盒模型:
- 在怪异模式下,盒模型为IE模型。盒子所占区域宽度=width(宽)+margin(左右),高度等同
- 在标准模式下,盒模型为W3C模型。盒子所占区域宽度=width(宽)+padding(左右)+border(左右)+margin(左右),高度等同
- 行内元素的垂直对齐方式:标准模式下vertical-align属性默认取值是baseline;怪异模式下vertical-align属性默认取值是bottom。
- 字体样式:标准模式下,表格中的字体样式会被继承;怪异模式下,表格中的字体样式不会被继承。
- 元素溢出的处理:标准模式下,overflow取值默认为visible;怪异模式下,当内容超出容器高度时,会把容器拉伸。
- !important:标准模式下,IE7+认识 !important声明;怪异模式下,IE6/7/8都不认识 !important声明。
- 行内元素的宽高:标准模式下,给行内元素设置wdith和height都不会生效;怪异模式下会生效。
- 水平居中:使用margin:0 auto在标准模式下可以使元素水平居中,但在怪异模式下却会失效。
- 怪异模式下,颜色值必须用十六进制标记法。
- 盒模型:
- 17.margin和padding在什么场合下使用
- margin:用来调整盒子到盒子之间的距离,不会撑大显示的区域,但是会影响到别的盒子
- 使用场景:需要在border外侧添加空白时;空白处不需要背景(色)时;上下相连的两个盒子之间的空白,需要相互抵消时;
- padding:用来调整子元素(内容)在父元素(盒子)内的位置,会把盒子撑大,如果不想被撑大,要在原来宽高的基础上减去对应方向的padding值
- 使用场景:需要在border内测添加空白时;空白处需要背景(色)时;上下相连的两个盒子之间的空白,希望等于两者之和时;
- margin:用来调整盒子到盒子之间的距离,不会撑大显示的区域,但是会影响到别的盒子
- 18.弹性盒子布局属性有哪些请简述?
- 父元素:
- 主轴方向 flex-direction
- row 主轴从左向右 默认值
- row-revese 主轴从右向左
- column 主轴从上到下
- column-reverse 主轴从下到上
- 主轴方向排列方式 justify-content
- flex-start 主轴起点 默认值
- flex-end 主轴终点
- center 居中
- space-between 两端对齐
- space-around 中间的留白是两边的2倍
- space-evenly 平均分配留白
- 交叉轴排列方式 align-items
- stretch 拉伸 默认值 去掉子元素的高度
- flex-start 交叉轴的起点
- flex-end 交叉轴的终点
- center 居中
- 换行 flex-wrap
- nowrap 不换行,默认值,会将子元素压缩
- wrap 换行
- wrap-reverse 反向换行
- 多行之间的排列方式 align-content
- stretch 拉伸 默认值 需要去掉子元素的高
- flex-start 主轴起点依次排列
- flex-end 主轴终点依次排列
- center 居中
- space-between 两端对齐
- space-around 中间的两端的2倍
- space-evenly 平均分配
- 主轴方向 flex-direction
- 子元素:
- 重写子项对应的交叉轴的对齐方式 align-self
- stretch 拉伸 默认值 去掉子元素的高度
- flex-start 交叉轴的起点
- flex-end 交叉轴的终点
- center 居中
- 放大 flex-grow
- 0 不放大
- 数值 填充剩余的空间
- 压缩 flex-shrink
- 1 压缩
- 0 不压缩
- 实现导航的滚动效果
- 子项的宽度超出了父容器的宽度
- 设置子项不压缩 flex-shrink:0;
- 父元素设置溢出显示滚动条 overflow-x:auto;
- 子项的宽度 flex-basis:数值+px 类似于宽度
- 排序 order 数值 值越大越向后,可以设置负数
- 重写子项对应的交叉轴的对齐方式 align-self
- 父元素:
- 19.怎么实现标签的禁用
- style=“pointer-events: none”
- 20.flex布局原理
- flex 是 flexible Box的缩写,意为“弹性布局”,用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为flex布局。当为父盒子设置为flex布局之后,子元素的float、clear、vertical-align属性将失效。
- 采用flex布局的元素,称为flex容器(flex container),简称“容器”。他的所有子元素自动成为容器成员,称为flex项目(flex item),简称“项目”。
- 总结:flex布局就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。
- 21.px与rem的区别
- px:px 实际上就是像素,用px设置字体大小时,比较稳定和精确
- px像素(Pixel),相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
- em:em 就是根据基准来缩放字体的大小 em的值并不是固定的;em会根据父级元素的字体大小变化
- em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
- rem: rem 是根据根元素 字体大小变化,这样就意味着,我们只需要在根元素确定一个参考值。一般情况下将根元素的字体大小设置为html{font-size:100px} rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。
- px:px 实际上就是像素,用px设置字体大小时,比较稳定和精确
- 22.网页的三层结构有哪些
- 网页的结构层:
- 由 HTML 或 XHTML 之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P 标签表达了这样一种语义:“这是一个文本段。”
- 网页的样式层:
- 该层指示结构化HTML文档如何看待网站的访问者,并由CSS(层叠样式表)定义。这些文件包含有关如何在Web浏览器中显示文档的样式说明。样式层通常包括基于屏幕大小和设备更改站点显示的 媒体查询。 网站的所有视觉样式都应位于外部样式表中
- 网页的行为层:
- 行为层使网站具有交互性,允许页面响应用户操作或基于一组条件进行更改。JavaScript是行为层最常用的语言,但CGI和PHP也经常被使用。 当开发人员引用行为层时,大多数都是指在Web浏览器中直接激活的层。
- 网页的结构层:
- 23.请简述媒体查询
- 媒体指的就是各种设备 (移动设备, PC设备),查询指的是要检测属于哪种设备,媒体查询就是通过查询当前属于哪种设备, 让网页能够在不同的设备下正常的预览
- 语法 @media 关键字 设备类型 and (媒体特性){}
- 关键字:all(所有的设备类型)/only(限定某种设备)/not(排除设备)
- 设备类型:
- all(所有的设备)
- screen 显示器 移动设备 笔记本
- print 打印设备
- 媒体类型
- 最小宽度 min-width 大于最小宽度
- 最大宽度 max-width 小于最大宽度
- 书写说明
- and两侧必须有空格
- 媒体特性属性值后面不要加分号
- 多个媒体特性之间用 and 连接
<style> @media all and (min-width:500px) and (max-width:999px) { div { height: 600px; background-color: cadetblue; } } </style>
- viewport视口
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- 视口 viewport
- 布局视口,默认情况下,布局视口的宽是980px,设置css样式的样式是作用在布局视口
- 可视视口 设备的宽度 device-width
- 完美/理想视口 width=device-width 布局视口和设备宽度一样
- initial-scale 初始缩放比例 默认值1
- minimum-scale 最小缩放比例 默认值1
- maximum-scale 最大缩放比例 默认值1
- user-scalable 用户是否可以手动缩放 no/0 不缩放
- 视口 viewport
- 24.rem缺点
- 有局限性,IE8及以下版本不支持
- 对pc页面来讲使用次数不多
- 数据量大:所有的图片、盒子都需要给一个准确的值,才能保证不同机型的适配;
- 25.常见的兼容性一阶段内容中记几个
- 在ie浏览器中,a标签套图片会自带边框 ie10及以下
- 解决:去掉边框 img{border:none}
- 图片自带底部3px的留白
- 解决:
- vertical-align: bottom/middle/top 给图片添加
- display:block; 给图片添加
- font-size:0; 给父元素添加
- 解决:
- 表单元素对齐不一致
- 解决:
- 设置怪异盒模型
- 设置浮动
- 解决:
- 透明度 opacity 在ie浏览器中不支持 0-1
- 解决:
- opacity的值照常设置,适应正常的浏览器
- 单独设置ie中透明属性:filter:alpha(opacity=value);取值范围 value: 1-100(整数)1 完全透明 100不透明
- 解决:
- 在ie浏览器中,a标签套图片会自带边框 ie10及以下
- 26.垂直与水平居中的方式
- 水平居中:
- 行内元素:为该行级元素的父元素设置text-align:center样式
- 块级元素:为其自身设置margin:auto样式
- 垂直居中:
- 行内元素:line-height: 父元素的高度
- 块级元素:
- 父元素 position:relative;子元素:position:absolute;top:50%;left:50%; transform:translate(-50%,-50%);
- 父元素:display:flex;justify-content: center; align-items:center;
- 水平居中:
- 27.三栏布局方式两边固定中间自适应
- 绝对定位法:将左右两边使用绝对定位,绝对定位使其脱离文档流,后面的center会自然流动到他们上面,然后使用margin属性,留出左右元素的宽度,就可以使中间元素自适应屏幕宽度。
- 自身浮动法:对左右分别使用float:left和float:right,浮动使左右两个元素脱离文档流,中间元素正常在文档流中,使用margin指定左右外边距对其进行一个定位。
- margin负值法:左右两栏均左浮动,左右两栏采用负的margin值。中间栏被宽度为100%的浮动元素包起来。
- 28.doctype作用
- 声明叫做文件类型定义(DTD),作用是为了告诉浏览器该文件的类型。让浏览器解析器知道应该用哪个规范来解析文档。
- 29.常见的浏览器内核有哪些
- ie浏览器:Trident
- 火狐:Gecko 代码开源
- 苹果 & 谷歌旧版本: Webkit
- 谷歌 & 欧鹏: Blink
- 30.link和import的区别
- 老祖宗的差别:link属于HTML提供的引用方式,@import是css提供的引用方式,link还可以引入其他文件类型,@import只能引入css文件
- @import url(“图标路径”); 不可以引入
- 加载顺序的区别:link和HTML是同时加载的,@import是当所有html文件加载后再去加载css文件,所以有时候浏览@import加载CSS的页面时开始会没有样式
- 兼容性 @import只有ie5以上才支持
- 老祖宗的差别:link属于HTML提供的引用方式,@import是css提供的引用方式,link还可以引入其他文件类型,@import只能引入css文件
- 32.BFC(块级格式化上下文)触发条件
- float:值为left/right
- position的值为absolute和fixed
- display为inline-block(内联块), table-cell(单元格), table-caption(表格标题), flex(弹性盒), inline-flex(弹性盒)
- overflow的值为hidden/scroll/auto
- 33.css实现边框三角形
<!-- 向下的三角形 --> div { height: 0; border-top: 20px solid pink; border-right: 20px solid transparent; border-bottom: 20px solid transparent; border-left: 20px solid transparent; /*透明*/ width: 0; }
二阶段
- 1.Js基本数据类型有哪些
- 数值类型(number)包含数字
- 字符串类型(string)由单双引号包住的字符串内容会原样输出
- 布尔类型(boolean)只会输出true ,false
- undefined 数值定义但未初始化
- null 空
- Symbol 表示独一无二的值(ES6新增)
- 2.Ajax如何使用
btn.onclick = function(){ // 1. 实例化一个XMLHttpRequest对象 let http = new XMLHttpRequest(); // 2. 规划一个请求(三要素) // 2.1 请求方式 GET || POST // 2.2 请求地址 // 2.3 同步还是异步 可选的参数,如果省略就是异步的请求 //http.open("GET","http://10.35.170.103/data.php"); //带有一个请求参数的请求 http.open("GET",`http://10.35.170.103/data.php?age=${age.value}&sex=${sex.value}`); // 3. 真实的发送请求 http.send(); // 4. 接收来自服务器端的响应 http.onreadystatechange = function(){ //服务器端已将返回的内容交付给客户端手里了 if(http.readyState === 4){ console.log(http.responseText); } } }
- 创建XMLHttpRequest对象
- 浏览器使用XMLHttpRequest对象与服务器进行交互,获取数据。一般现在流行的浏览器均支持XMLHttpRequest对象(IE5 和 IE6 使用 ActiveXObject)。
- 语法:
- var xml=new XMLHttpRequest();
- 老版本的IE浏览器的创建方式为:var xml=new ActiveXObject(“Microsoft.XMLHTTP”);
var xml; if (window.XMLHttpRequest) { xml=new XMLHttpRequest(); }else{ xml=new ActiveXObject("Microsoft.XMLHTTP"); }
- 向服务器发送请求
- get方式提交 使用XMLHttpRequest对象的open()方法向服务器发送请求
- 语法:
- open(请求方式,请求地址(get发送的数据拼接在url后面),true(异步))
xml.open("get","index.json",true); xmlH.send();// get请求send保持为空
- post方式提交 使用XMLHttpRequest对象的open()与send()方法向服务器发送请求
- 语法:
- open(请求方式,请求地址,true(异步))
- send()
xml.open("post","index.json",true); //如果想要使用post提交数据,必须添加此行 xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //将数据通过send方法传递 xhr.send('name=fox&age=18');
- onreadystatechange事件
- 当向服务器发送请求时redyState的值发生改变时触发onreadystatechange事件。
- readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
- status有两种数值,分别表示: 200: “OK” 404: 未找到页面
xml.onreadystatechange(function(){ if(xmlHttp.readyState==4&&xmlHttp.status==200){ console.log(xhr.responseText); } }
- 创建XMLHttpRequest对象
- 3.如何判断一个数据是NaN
- NaN不是一个数字且数据类型为number,而且不等于自身
- 可直接采用内置方法isNaN
function isNaN(n) { if (n !== n) { return true; } else { return false; } }
- 利用NaN是唯一一个不等于任何自身的特点
var a=NaN; a==a; //false
- object.is方法
console.log(Object.is("a", NaN)); console.log(Object.is(1, NaN)); console.log(Object.is(NaN, NaN));
- 可直接采用内置方法isNaN
- NaN不是一个数字且数据类型为number,而且不等于自身
- 4.Js中null与undefined区别
- 相同点:if 判断语句中,两者都会被转换为false
- 不同点:
- Number转换的值不同,Number(null)输出为0, Number(undefined)输出为NaN
- null表示一个值被定义了,但是这个值是空值
- undefined表示缺少值,即此处应该有值,但是还没有定义
- 5.闭包是什么有什么特性,对页面会有什么影响
- 闭包可以简单理解成“定义在一个函数内部的函数“。当其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
let fn = (function(){ //局部变量 var count = 0; return function(){ return ++count; } })()
- 本质:外层函数嵌套一个内层函数,内层函数作为外层函数的return语句的返回值。外层函数是自调用函数,并且将自身的返回值(也就是内层函数本身)赋给一个变量。在JS执行环境上下文中调用该变量就等价于调用了内层函数,并且在内层函数中可以访问到外层函数的局部变量又并且外层函数的局部变量不会被多次声明,此时就形成了一种闭包的写法。
- 特点:
- 函数嵌套函数。
- 函数内部可以引用外部的参数和变量。
- 参数和变量不会被垃圾回收机制回收。
- 用处:
- 常驻内存 会增大内存的使用量;
- 读取函数内部的变量;
- 这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除。
- 优点:
- 变量长期驻扎在内存中;
- 避免全局变量的污染;
- 私有成员的存在;
- 缺点:会造成内存泄露
- 闭包可以简单理解成“定义在一个函数内部的函数“。当其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
- 6.事件委托是什么?如何确定事件源
- 事件委托还有一个名字叫事件代理,JS高程上讲:事件委托就是利用事件冒泡,只制定一个时间处理程序,就可以管理某一类型的所有事件。
- 将子元素的事情委托给它们的祖先级元素来干,然后使用event.target(低版本IE用的是event.srcElement)来代替已经混乱this关键字
- 解决动态元素(刚进入页面时,元素不在页面内)无法绑定事件问题
- 在极端情况下可以提升客户端性能
- 7.本地存储与cookie的区别
- Cookie 是小甜饼的意思。顾名思义,cookie 确实非常小,它的大小限制为4KB左右。它的主要用途有保存登录信息,比如你登录某个网站市场可以看到“记住密码”,这通常就是通过在 Cookie 中存入一段辨别用户身份的数据来实现的。
- localStorage 是 HTML5 标准中新加入的技术,它并不是什么划时代的新东西。早在 IE 6 时代,就有一个叫 userData 的东西用于本地存储,而当时考虑到浏览器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多数浏览器所支持,如果你的网站需要支持 IE6+,那以 userData 作为你方案是种不错的选择。
- sessionStorage 与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同。做过后端开发的同学应该知道 Session 这个词的意思,直译过来是“会话”。而 sessionStorage 是一个前端的概念,它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就会被清空。
- cookie:兼容性很好,可以灵活的设置数据的生命周期,缺点是操作不方便,需要大量的字符串处理
- localStorage:IE67不认识,永久性存储,只要用户不删除或调用clear方法就永远不会删,操作很方便
- sessionStorage:兼容性与localStorage一样,但是存储时间是会话(在当前标签页无论跳转到该网站的哪一个页面都能获取到,但关闭浏览器就会销毁,并且在其他标签页面中是获取不到的)
- 三者的异同
特性 | Cookie | localStorage | sessionStorage |
---|---|---|---|
数据的生命期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 | 除非被清除,否则永久保存 | 仅在当前会话下有效,关闭页面或浏览器后被清除 |
存放数据大小 | 4K左右 | 一般为5MB | 同左 |
与服务器端通信 | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | 同左 |
易用性 | 需要程序员自己封装,源生的Cookie接口不友好 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 | 同左 |
- 8.ES6新特性
- const和let
- 模板字符串
- 箭头函数
- 函数的参数默认值
- 对象和数组解构
- for…of 和 for…in
- ES6中的类
- 9.Let与var与const的区别
- var声明的变量会挂载在window上,而let和const声明的变量不会;
- var声明变量存在变量提升,let和const不存在变量提升;
- let和const声明变量都没有函数作用域的概念,而是遵守块级作用域的概念;
- 同一作用域下let和const不能声明同名变量,而var可以;
- let 有暂存死区(在声明之前就使用变量,就会报错,这就是暂时性死区)
- 【let和const关键字:let和const声明变量都没有函数作用域的概念,而是遵守块级作用域的概念,并且没有变量提升的操作,不能重复声明。const是声明常量版的let,let有暂时性死区的特性。】
- 10.数组方法有哪些请简述
- push(新值) 向数组的尾端插入一个新的元素
- unshift(新值) 向数组的前端插入一个新的元素
- pop() 删掉数组中最后一个元素
- shift() 删掉数组中第一个元素
- splice(删除的下标,1) 从某一个下标上删除一个元素,有副作用
- splice(要插入的下标,0,要插入的数据) 从中间插入一个元素
- concat() 拼接数组,返回值为合并成的新数组,原数组不会改变
- join() 将数组转换为字符串,参数为分隔符,原数组不会改变
- reverse() 颠倒数组中元素的顺序,会改变原数组
- slice(start,end) 通过开始下标和结束下标截取数组元素,原数组不会发生改变
- toString() 将数组转换为字符串 可以被join完美代替
- sort() 通过Unicode进行排序,在原数组上排序,不生成副本
var arr = [1, 5, 6, 1, 3, 4, 11, 2, 5] //排序 固定写法 升序 arr.sort(function(num1, num2) { return num1 - num2; }) console.log(arr); //排序 固定写法 降序 arr.sort(function(num1, num2) { return num2 - num1; }) console.log(arr);
- arr.forEach(callback) 遍历数组,无return 即使有return,也不会返回任何值,并且会影响原来的数组
- arr.map(callback) 映射数组(遍历数组),有return 返回一个新数组 。
- arr.filter(callback) 过滤数组,返回一个满足要求的数组
- 11.Json如何新增/删除键值对
- JSON是什么: JSON (JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。
- JSON规则:
- 1.必须是字符
- 2.基础格式参考js中的对象(array和object)
- 3.对象格式的key部分必须放在双引号中,单引号不行
- 4.不允许出现没有意义的逗号
- 5.不能出现undefined、NaN,可以出现null
- 6.不能出现单引号
- 字符串转JSON(正解析): Var obj = JSON.parse(JSON格式的字符串)
- JSON转字符串(反解析): Var str = JSON.stringify(对象)
- 删除: delete json对象[“属性名”];
- 增加: json对象[“属性名”]=属性值 例如:myObject[age]=10;//即可添加上age属性
- 12.什么是面向对象请简述
- 面向对象就是将问题抽象成若干object对象,然后去对这些对象编程,将对象的属性和操作封装到类中,让它们具有一定的功能。具有抽象性、封装性、继承性、多态性的特点。类是具有相同或相似性质的对象的抽象。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。
- 面向对象是把构成问题的的事物分解成各个对象,建立对象不是为了完成一个步骤,而是为了描述某个事物在整个解决问题的过程中的行为。
- 优点:易维护、复用、扩展
- 缺点:性能低:因为在创建类的实例需要很大的开销。
- 13.普通函数和构造函数的区别
- 返回值类型的区别:
- 构造函数是没有返回值类型的
- 普通函数是有返回值类型的,即使函数没有返回值,返回值类型也要写上void。
- 函数名的区别:
- 构造函数的函数名必须要与类名一致,习惯首字母大写
- 普通函数的函数名只要符合标识符的命名规则即可。
- 调用方式的区别:
- 构造函数是在创建对象的时候由new关键字调用的
- 普通函数是由我们使用对象调用的,一个对象可以调用多次普通函数
- 作用上的区别:
- 构造函数用于初始化一个对象。
- 普通函数是用于描述一类事物的公共行为。
- 返回值类型的区别:
- 14.请简述原型/原型链/继承
- 原型:每一个构造函数都有一个prototype属性,这个属性会在生成实例的时候,成为实例对象的原型对象。javascript的每个对象都继承另一个对象,后者称为“原型”(prototype)对象。
- 原型链:每一个对象都有一个__proto__属性,对象的属性和方法,有可能定义在自身,也有可能定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)。 (“原型链”的作用是:读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。举例来说,如果让某个函数的prototype属性指向一个数组,就意味着该函数可以当作数组的构造函数,因为它生成的实例对象都可以通过prototype属性调用数组方法。)
- 继承:继承就是在子类构造函数中继承父类构造函数的私有属性和原型属性。我们在子类构造函数中使用call或apply方法调用父类构造函数并改变其this指向为子类构造函数的this,此时子类的构造函数就继承了父类的私有属性和私有方法。将父类的实例化对象赋值给子类的原型对象,此时子类就继承了父类的原型属性和原型方法。
- 15.Promise的理解
- Promise是一种异步操作的解决方案,将写法复杂的传统的回调函数和监听事件的异步操作,用同步代码的形式表达出来。避免了多级异步操作的回调函数嵌套。
- 1、主要用于异步计算
- 2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
- 3、可以在对象之间传递和操作promise,帮助我们处理队列
- Promise是一个对象,它的内部其实有三种状态。
- 初始状态( pending )。
- 已完成( resolve): resolve 方法可以使 Promise 对象的状态改变成成功
- 已拒绝( reject ): reject 方法则是将 Promise 对象的状态改变为失败
- Promise常用的三种方法
- 第一种:then 表示异步成功执行后的数据状态变为resolve
- 第二种:catch表示异步失败后执行的数据状态变为reject
- 第三种:all表示把多个没有关系的Promise封装成一个Promise对象使用then返回一个数组数据。
- Promise 构造函数有两个变量 resolve 用于返回异步执行成功的函数 reject 用于返回异步执行失败的函数,配合then与catch一起使用
- Promise是一种异步操作的解决方案,将写法复杂的传统的回调函数和监听事件的异步操作,用同步代码的形式表达出来。避免了多级异步操作的回调函数嵌套。
- 16.Promise在哪里使用过
- 1.Ajax异步请求的时候
- 2.函数嵌套层级多的时候使用promise,优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。
- 17.请简述async的用法
- async 用于声明一个 function 是异步的,而 await 用于等待一个异步方法执行完成,async返回的是一个Promise对象。
- async的主要作用是回调地狱的处理看起来比promise更美观,而且使用async来传参的时候比较方便。
- async函数必须要等到方法体中所有的await声明Promise函数执行完后,async函数才会得到一个resolve状态的Promise对象。
- async/await在遇到异步请求的情况下,能让代码以看似同步的方式来解决异步回调
- 使用步骤:
- 1、定义一个需要进行异步等待的方法,并在方法前加"async"关键字
- 2、在这个内部有异步请求的方法中用await等待相应的请求完成。
- 3、在这个异步请求的方法中返回一个Promise对象,并封装resolve和reject方法
- jQuery相关的知识
- jQuery:类库(工具箱):宗旨是write less do more,功能:DOM操作,DOM获取,动画,数据交互(ajax),链式调用
- jQuery对象到底是啥? 是一个类数组。所有数组成员都是原生JS节点。jQuery和原生js节点的属性和方法互不通用。是一个兼容多浏览器的javascript库(函数库),核心理念是write less,do more(写的更少,做的更多)。
- 特点: 是一个快速的简洁的javascript框架,可以简化查询DOM对象、处理时间、制作动画、处理Ajax交互过程
- 1.提供了强大的功能函数
- 2.解决浏览器兼容性问题
- 3.纠正错误的脚本知识
- 4.体积小,使用灵巧(只需引入一个js文件)
- 5.易扩展、插件丰富
- 作用:
- 程序员角度:简化Javascript和Ajax编程,能够使程序员从设计和书写繁杂的JS应用中解脱出来,将关注点转向功能需求而非实现细节上,从而提高项目的开发速度。
- 用户体验角度: 改善了页面视觉效果,增强了与页面的交互性,体验更绚丽的网页物资 方便地选择页面元素(模仿CSS选择器更精确、灵活) 动态更改页面样式/页面内容(操作DOM,动态添加、移除样式) 控制响应事件(动态添加响应事件) 提供基本网页特效(提供已封装的网页特效方法) 快速实现通信(ajax)。
- jQuery获取方式: jQuery库文件不需要安装,只需使用
三阶段
Vue
- 1.Vue的核心是什么
- 数据驱动和组件化
- 2.请简述你对vue的理解
- 定义:vue是一套构建用户界面的渐进式的自底向上增量开发MVVM框架,Vue的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。通过尽可能简单的API实现响应的数据绑定和组合的视图组件。
- 优点:轻量级、高效率、上手快、简单易学、文档全面而简洁
- 目的:解决数据绑定问题;Vue.js主要的目的是为了开发大型单页面应用;支持组件化,也就是可以把页面封装成为若干个组件,把组件进行拼装,这样是让页面的复用性达到最高
- 核心思想:数据驱动、组件化
- 优势:简洁:HTML模板 + Vue实例 + JSON数据;轻量:17kb,性能好;设计思想:视图与数据分离,无需操作DOM;社区:大量的中文资料和开源案例
- 3.请简述vue的单向数据流
- 数据从父级组件传递给子组件,只能单向绑定。子组件内部不能直接修改从父级传递过来的数据。
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。
- 数据从父级组件传递给子组件,只能单向绑定。子组件内部不能直接修改从父级传递过来的数据。
- 4.Vue常用的修饰符有哪些
- 按键修饰符 .up,.down,.ctrl,.enter,.space等等
- 语法:@click.修饰符=‘fn()’
- 事件修饰符
- prevent修饰符:阻止事件的默认行为(submit提交表单)
- stop修饰符:阻止事件冒泡
- capture修饰符:与事件冒泡的方向相反,事件捕获由外到内
- self:只会触发自己范围内的事件,不包含子元素
- once:只会触发一次
- 注意:修饰符可以串联使用
- 按键修饰符 .up,.down,.ctrl,.enter,.space等等
- 5.v-text与{{}}区别
- v-text是操作网页元素中的纯文本内容,{{}}是它的另外一种写法,v-text与{{}}等价,{{}}叫模板插值,v-text叫指令,有一点区别就是,在渲染的数据比较多的时候,可能会把大括号显示出来,俗称屏幕闪动。
- 解决屏幕闪动的方法:
- 使用v-text渲染数据;
- 使用{{}}语法渲染数据,但是同时使用v-cloak指令(用来保持在元素上直到关联实例结束时候进行编译),v-cloak并不需要添加到每个标签,只要在el挂载的标签上添加就可以,并且为[v-cloak]添加css样式为display:none;
- 6.v-on可以绑定多个方法吗
- 可以绑定多个方法,中间用逗号隔开
- 7.Vue循环的key作用
- vue中循环需加 :key=“唯一标识” ,唯一标识可以指item里面id、index 等,因为vue组件高度复用增加key可以标识组件的唯一性,为了更好地区别各个组件,key的作用主要是为了高效的更新虚拟DOM
- 为遍历数组或元素中的唯一标识,增加或删减元素时,通过这个唯一标识key判断是否是之前的元素,vue会直接对已有的标签进行复用,不会整个的将所有的标签全部重新删除和创建,只会重新渲染数据,然后再创建新的元素直到数据渲染完为止
- 8.什么是计算属性
- 首先它是一种属性,其次它有“计算”这个特殊性质。每次取得它的值的时候,它不像普通属性那样直接返回结果,而是经过一系列的计算之后再返回结果。同时只要在它的当中引用了data中的某个属性,当这个属性发生变化时,计算属性会自动重新执行。
- 9.Vue单页面的优缺点
- 优点:
- 用户体验好,快,内容的改变不需要重新加载整个页面,对服务器压力较小。
- 前后端分离,比如vue项目
- 完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整;
- 缺点:
- 不支持低版本浏览器
- 首次加载页面的时候需要加载大量的静态资源,这个加载时间相对比较长。
- 不利于SEO(搜索引擎)优化,单页页面,数据在前端渲染,就意味着没有 SEO。
- 页面导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
- 优点:
- 10.Vuex是什么?怎么使用?在那种场景下使用
- Vuex是一个专为 Vue.js 应用程序开发中管理的一个模式。通过创建一个集中的数据存储,方便程序中的所有组件进行访问。
- 使用:
- 在store下的index.js中 Vue.use(Vuex)
- 创建store实例
export default new Vuex.Store({ state: {},//存放数据 mutations: {},//修改数据的值 actions: {},//执行异步操作请求数据 modules: {},//让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。 getters:{}//计算属性 })
- vuex只能用于单个页面中不同组件(例如兄弟组件)的数据流通。
- 11.Vue中路由跳转方式(声明式/编程式)
- 使用this.$router全局路由的push()方法进行路由跳转–称之为编程式跳转;
- 使用router-link进行跳转路由–称之为声明式跳转
- 12.跨域的解决方式
- 方法1.后端解决跨域CORS(跨域资源共享)(在server.js中添加)
app.use("/", (req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild'); res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE,OPTIONS'); next() })
- 方法2.使用JQuery提供的jsonp
- 网页中添加一个script元素,向服务器请求json数据,这种做法不受同源策略的限制,服务器接收到请求后,把数据放在一个指定名字的回调函数里传递回来
methods: { getData () { var self = this $.ajax({ url: 'http://f.apiplus.cn/bj11x5.json', type: 'GET', dataType: 'JSONP', success: function (res) { self.data = res.data.slice(0, 3) self.opencode = res.data[0].opencode.split(',') } }) } }
- 方法3.proxyTable解决跨域(项目使用vue-cli脚手架搭建)
- 在vue.config.js中中添写如下代码
proxy: { '/api': { target: 'http://localhost:3000/', //对应自己的接口 changeOrigin: true, ws: true, pathRewrite: { '^/api': '' } } }
- 在vue.config.js中中添写如下代码
- 方法1.后端解决跨域CORS(跨域资源共享)(在server.js中添加)
- 13.Vue的生命周期请简述
- Vue实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是Vue的生命周期。
- 14.Vue生命周期的作用
- 生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易完成指定逻辑。每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做 生命周期钩子 的函数,这给了用户在不同阶段添加自己的代码的机会。(ps:生命周期钩子就是生命周期函数)例如,如果要通过某些插件操作DOM节点,如想在页面渲染完后弹出广告窗, 那我们最早可在mounted 中进行。
- 15.DOM渲染在哪个生命周期阶段内完成
- DOM渲染在mounted中就已经完成了,原因:在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素,而在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点。
- 16.Vue路由的实现
- hash模式 和 history模式
- 17.Vue路由模式hash和history,简单讲一下
- hash模式:hash模式url里面永远带着#号,我们在开发当中默认使用这个模式
- history模式:history模式没有#号,是个正常的url适合推广宣传。
- 区别
- url显示
- hash:有#,很low
- history:无#,好看
- 回车刷新
- hash:可以加载到hash值对应页面
- history:一般就是404刷新掉了
- 支持版本
- hash:支持低版本浏览器和IE浏览器
- history:HTML5新推出的API
- url显示
- 18.Vue路由传参的两种方式,params和query方式与区别
- params方式
- 匹配参数(在路由规则中)
- 动态路径参数
- 使用动态路由匹配中的动态路径参数来进行路由配置
- 注意:动态路径参数以冒号:开头
{ path: '/info:aa',name: 'Info',component: Info} //在router下的index.js中,aa表示随意绑定的参数
- 动态路径参数
- 发送数据(绑定参数)
- 声明式
<router-link :to="{name:'tema',params:{id:'参数1',name:'参数2'}}">index</router-link>
- 编程式(推荐)
this.$router.push({name:'tema',params:{id:'参数1',name:'参数2'}})
- 注意:params只能通过路由配置中的name属性来引用路由
- 声明式
- 接收数据(获取路由传入参数)
{{this.$route.params.id}} //在接收页面添加,id指的是在路由规则里绑定的参数
- 匹配参数(在路由规则中)
- query方式
- 路由参数不需要添加内容
- 发送数据(绑定参数)
- 声明式
<router-link :to="/home?id=参数1&name=参数2">index</router-link> //通过name引用路由 <router-link :to="{name:'tema',query:{id:'参数1',name:'参数2'}}">index</router-link>(推荐) //通过path引用路由 <router-link :to="{path:'/home',query:{id:'参数1',name:'参数2'}}">index</router-link>
- 编程式
this.$router.push("/home?id=参数1&name=参数2"); //通过name引用路由 this.$router.push({name:'tema',query:{id:'参数1',name:'参数2'}}); //通过path引用路由 this.$router.push({path:'/home',query:{id:'参数1',name:'参数2'}});
- 声明式
- 接收数据(获取路由传入参数)
{{this.$route.query.id}} //在接收页面添加,id指的是在路由规则里绑定的参数
- prams和query方式与区别
- 用法上的:query可以用name也可以用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展示上:params类似于post,query更加类似于我们ajax中get传参,说的再简单一点,前者在浏览器地址栏中不显示参数,后者显示,所以params传值相对安全一些。
- params方式
- 19.Vue数据绑定的几种方式
- 普通文本绑定:双大括号法/插值表达式 {{}}或者使用v-text指令绑定,以文本的形式输出
- 解释HTML标签的绑定:使用v-html绑定
- 将数据绑定到标签的属性上:使用v-bind :属性名=“变量”来绑定
- 20.Vue注册一个全局组件
- 全局组件
- 作用域:全局范围内均可使用
- 建议:组件名(字母全小写且必须包含一个连字符)
- 语法
Vue.component('name',{ template:'<div></div>' })
- 位置:创建实例前定义全局组件
- template的设置
- template:‘html代码’
- template:’#template1’ 引用template内容
- 数据的定义:
data:function(){ return {a:1,b:2} }
- 函数的定义:
methods:{ 函数名:function(){} }
- 全局组件
- 21.Vue的路由钩子函数/路由守卫有哪些
- 全局前置守卫
- 当一个导航触发时,全局前置守卫(在进入组件之前)按照创建顺序调用。
- vue-router 提供的 router.beforeEach((to,from,next)=>{})可以方便地实现全局前置导航守卫
- to:即将要进入的目标 路由对象
- from:当前导航正要离开的路由
- next:下一步执行
router.beforeEach((to,from,next)=>{ //根据用户的登录状态限制用户是否能跳转到首页面 if(to.path=="/login"||to.path=="/register"){ next() } else { alert("当前为付费页面 请登录后访问!") next("/login") } })
- 全局后置钩子
- 当一个导航触发时,全局后置钩子(在进入组件之后)调用。
- vue-router提供的router.afterEach((to,from)=>{})实现全局后置守卫
- to:即将要进入的目标 路由对象
- from:当前导航正要离开的路由
router.afterEach((to,from)=>{ console.log("我是全局后置钩子"); })
- 路由独享的守卫
- 与全局前置守卫相比路由独享守卫只是对当前路由进行单一控制参数和全局前置守卫相同
- 在路由配置上直接定义beforeEnter进行路由独享守卫定义
{ path:'/shop', name:'Shop', component:Shop, beforeEnter:(to,from,next)=>{ //判断是否登录过 alert("当前页面是vip页面!请登录") next("/login") } }
- 组件内的守卫(只对当前组件生效)
- beforeRouteEnter在进入组件前调用(不常用)
- 在组件中使用beforeRouteEnter(to,from,next){}来进行进入组建前的钩子
- beforeRouteLeave离开路由之前(常用)
- 在组件中使用beforeRouteLeave(to,from,next){}来进行离开组件的钩子
beforeRouteLeave(to,from,next){ if(confirm("你确定要离开吗")){ next() }else{ //不进行下一步(也就是不从当前路由离开) next(false) } }
- beforeRouteEnter在进入组件前调用(不常用)
- 22.Vue中如何进行动态路由设置?有哪些方式?怎么获取传递过来的数据?
- params方式
- 匹配参数(在路由规则中)
- 动态路径参数
- 使用动态路由匹配中的动态路径参数来进行路由配置
- 注意:动态路径参数以冒号:开头
{ path: '/info:aa',name: 'Info',component: Info} //在router下的index.js中,aa表示随意绑定的参数
- 动态路径参数
- 发送数据(绑定参数)
- 声明式
<router-link :to="{name:'tema',params:{id:'参数1',name:'参数2'}}">index</router-link>
- 编程式(推荐)
this.$router.push({name:'tema',params:{id:'参数1',name:'参数2'}})
- 注意:params只能通过路由配置中的name属性来引用路由
- 声明式
- 接收数据(获取路由传入参数)
{{this.$route.params.id}} //在接收页面添加,id指的是在路由规则里绑定的参数
- 匹配参数(在路由规则中)
- query方式
- 路由参数不需要添加内容
- 发送数据(绑定参数)
- 声明式
<router-link :to="/home?id=参数1&name=参数2">index</router-link> //通过name引用路由 <router-link :to="{name:'tema',query:{id:'参数1',name:'参数2'}}">index</router-link>(推荐) //通过path引用路由 <router-link :to="{path:'/home',query:{id:'参数1',name:'参数2'}}">index</router-link>
- 编程式
this.$router.push("/home?id=参数1&name=参数2"); //通过name引用路由 this.$router.push({name:'tema',query:{id:'参数1',name:'参数2'}}); //通过path引用路由 this.$router.push({path:'/home',query:{id:'参数1',name:'参数2'}});
- 声明式
- 接收数据(获取路由传入参数)
{{this.$route.query.id}} //在接收页面添加,id指的是在路由规则里绑定的参数
- params方式
- 23.Elementui中的常用组件有哪些?请简述你经常使用的并且他们的属性有哪些?
- Container 布局容器:用于布局的容器组件,方便快速搭建页面的基本结构
- <el‐container>:外层容器。当子元素中包含 <el‐header> 或 <el‐footer> 时,全部子元素会垂直上下排列,否则会水平左右排列
- <el‐header>:顶栏容器
- <el‐aside>:侧边栏容器
- <el‐main>:主要区域容器
- <el‐footer>:底栏容器
- Dropdown 下拉菜单:将动作或菜单折叠到下拉菜单中
- :下拉按钮
- 下拉菜单
- 下拉项
- divided分隔
- NavMenu 导航菜单:为网站提供导航功能的菜单
- :导航菜单
- :导航按钮
- 标题和名称
<i class="el-icon-menu">
图标<span slot="title">导航二</span>
导航标题
- 导航项
- Table 表格:用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作
- :表格\数据绑定对象\样式
- :表格行\数据绑定对象属性\表头
- align=“center”:居中
- slot-scope:作用域插槽,可以获取表格数据
- scope:代表表格数据,可以通过scope.row来获取表格当前行数据,scope不是固定写法
- <el-button type=“primary” size=“mini” @click=“handleUpdate(scope.row)”>按钮\类型\大小\事件绑定
- Form 表单
- :表单/绑定数据模板/绑定校验
- 表单项\显示内容\数据模板属性绑定
- 表单输入框/数据绑定
- :下拉框/数据绑定/提示
- :下拉项/数据项
- ref绑定校验信息
- prop对应rules中对应的校验规则字段名
- Container 布局容器:用于布局的容器组件,方便快速搭建页面的基本结构
- 24.Vue-cli中如何自定义指令
- 自定义指令的钩子函数
- bind:绑定指令到元素上,只执行一次
- inserted:绑定了指令的元素插入到页面中展示时调用,基本上都是操作这个钩子函数
- update:所有组件节点更新时调用
- componentUpdated:指令所在组件的节点及其子节点全部更新完成后调用
- unbind:解除指令和元素的绑定,只执行一次
//directives:{ //自定义指令的名字:{ //自定义指令钩子函数(el){ //操作逻辑 //} //} //} <template> <div class="about"> <h1 v-aa>自定义指令</h1> </div> </template> <script> export default { directives:{ "aa":{ // el指向当前绑定的那个元素 inserted(el){ el.style.color="pink" } } } } </script> ```
- 自定义指令的钩子函数
- 25.Vue中指令有哪些
- v-model指令 主要是用于表单上数据的双向绑定
- v-show指令 控制切换一个元素的显示和隐藏
- v-on指令 为HTML元素绑定事件监听
- v-for指令 遍历data中的数据,并在页面进行数据展示
- v-bind指令 绑定HTML元素的属性
- v-if指令 判断是否加载固定的内容
- v-else指令 必须配合v-if使用否则无效,当v-if条件不成立的时候执行
- v-else-if指令 当有一项成立时执行
- v-text指令 操作网页元素中的纯文本内容
- v-html指令 输出真正的HTML
- v-once指令 当数据改变时,插值处的内容不会更新(会影响到该节点上的所有属性)
- 26.Vue如何定义一个过滤器
- 全局过滤器
- 位置:创建实例之前
- 语法
Vue.filter('过滤器名称',function(val){//val表示需要处理的值 return val + 4; //返回处理后的数据 })
- 局部过滤器
- 只能在当前vue注册内容中使用
- 位置:在vue实例中与el属性data属性同级定义
- 语法
filters:{ "过滤器名字":function(val){ return输出内容 } }
- 过滤器的调用方法
- {{msg | 过滤器名称 }}
- 注意事项
- 定义全局过滤器,必须放在vue实例化前面
- 在没有冲突的前提下,过滤器可以串联
- 全局过滤器
- 27.对vue 中keep-alive的理解
- 我们不停的切换两个标签页的内容时候,会发现选择好的内容,切换路由之后会恢复初始化,也就是说之前的状态丢失。原因是每次切换路由的时候,Vue 都创建了一个新的组件实例。解决这个问题,我们可以用一个 元素将其路由出口包裹起来。在切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
- keep-alive属性
- include(包含的组件缓存)
<keep-alive include="Democ"> <component :is="com"></component> </keep-alive>
- exclude(排除的组件不缓存,优先级大于include)
- include(包含的组件缓存)
- keep-alive 的钩子函数(位置:和data,methods同级)
- activated 类型:func 触发时机:keep-alive组件激活时使用;
export default { data(){ return{ text:"demoa" } }, activated() { console.log("进入到被keepalive管理的组件"); }, deactivated() { console.log("离开了被keepalive管理的组件"); } }
- deactivated 类型:func 触发时机:keep-alive组件停用时调用;
- 这两个生命周期函数一定是要在使用了keep-alive组件之上。
- activated 类型:func 触发时机:keep-alive组件激活时使用;
- 28.如何让组件中的css在当前组件生效
- 为组件的style设置scoped属性,表示仅对当前组件设置样式
- 29.Vue生命周期一共几个阶段
- 它可以总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/销毁后。
- beforeCreate:在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法。
- created:data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作。
- beforeMount:执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的。
- mounted:执行到这个钩子的时候,就表示Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在这个阶段中进行。
- beforeUpdate: 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步。
- updated:页面显示的数据和data中的数据已经保持同步了,都是最新的。
- beforeDestory:Vue实例从运行阶段进入到了销毁阶段,这个时候所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁。
- destroyed: 这个时候所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。
- 它可以总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/销毁后。
- 30.Mvvm与mvc的区别
- MVVM分为三部分:分别是M(Model,模型层),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器MVC的C层)
- M:模型层,主要负责业务数据相关
- V:视图层,负责视图相关,细分下来就是html+css层
- VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点;因此开发者只需关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。
- MVC封装与业务无关的重复代码,形成框架,是模型(model)-视图(view)-控制器(controller)的缩写。
- 模型(Model)数据的储存和处理,再传递给视图层相应或者展示
- 视图(View)前端的数据展示
- 控制器(Controller)对数据的接收和触发事件的接收和传递
- MVC 思想:一种将数据层与视图层进行分离的设计思想
- MVVM思想:MVVM的一个重要特性,双向绑定,意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之相同mvc和mvvm都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
- MVVM分为三部分:分别是M(Model,模型层),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器MVC的C层)
- 31.Vue组件中的data为什么是函数
- 组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。
- 32.Vue双向绑定的原理
- 双向绑定原理:vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
- 数据劫持:当我们访问或设置对象的属性的时候,都会触发Object.defineProperty()函数来拦截(劫持),然后再返回(get)或设置(set)对象的属性的值,并且当数据发生改变的时候做出反应
- 发布者-订阅者模式:其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将得到通知
- 双向绑定原理:vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
- 33.Vue中组件怎么传值
- 父组件向子组件传值(正向传值)
- 父组件通过props向子组件传值,props是你可以在组件上注册的一些自定义特性。当一个值传递给一个props特性的时候,它就变成了那个组件实例的一个属性。一个组件默认可以拥有任意数量的 props,任何值都可以传递给任何 props。
- 子组件向父组件传值(逆向传值)
- 子组件通过触发事件给父组件的方式进行传值,调用内部的 $emit 方法并传入事件的名字,来向父级组件触发一个事件
- 首先要有事件触发一个函数(子)
- 函数抛出自定义事件,携带着子组件的数据(子)
- 子组件被调用的时候,使用v-on事件调用父组件的一个函数,但是父组件函数不加()(父)
- 父组件函数有一个形参val,用来接收子组件抛出的数据(父)
- 子组件通过触发事件给父组件的方式进行传值,调用内部的 $emit 方法并传入事件的名字,来向父级组件触发一个事件
- 兄弟组件传值
- 创建一个事件总线,例如demo中的eventBus,用它作为通信桥梁
- 在需要传值的组件中用bus.$emit触发一个自定义事件,并传递参数(emit前加美元符)
- 在需要接收数据的组件中用bus.$on监听自定义事件,并在回调函数中处理传递过来的参数
- 父组件向子组件传值(正向传值)
- 34.Bootstrap的原理
- 通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了强大的响应式网格系统。Bootstrap框架中的网格系统就是将容器平分成12份
- 35.Vue兄弟组件传值
- 传统方法:在需要传值的兄弟组件之上创建一个父组件,A逆向给父组件,父组件再正向给B组件
- 中央事件总线:在src下创建一个文件夹用来存放xxx.js文件,在其中只创建一个新的vue实例,以后它就承担起了组件之间通信的桥梁了,也就是中央事件总线。
- 创建一个事件总线,例如demo中的eventBus,用它作为通信桥梁
- 在需要传值的组件中用bus.emit触发一个自定义事件,并传递参数(emit前加美元符)
- 在需要接收数据的组件中用bus.$on监听自定义事件,并在回调函数中处理传递过来的参数
- 36.如果一个组件在多个项目中使用怎么办
- 方案一:npm发布引用
- 公共组件编写完成后,将其发布到npm。发布流程如下:
在注http://www.npmjs.com册一个账号
进入common的控制台,输入命令npm login,按照提示输入刚注册的账号密码
输入命令 npm publish 即可
需要用该组件的项目通过npm install命令将公共组件以node_module的方式引入。另外,每次改动代码再次发布时,需要修改package.json文件中的版本号,不然发布不成功。
- 公共组件编写完成后,将其发布到npm。发布流程如下:
- 方案二:npm link
- 首先进入公共包,在控制台输入npm link
这会创建一个软连接,并保存到目录C:\Users\Administrator\AppData\Roaming\npm\node_modules下面。
然后进入使用该公共组件的项目,在控制台输入npm link common
- 首先进入公共包,在控制台输入npm link
- 方案三:npm本地file引用(推荐)
- 进入使用该公共项目的文件夹,在控制台输入命令:npm install …/common/
其中…/common/是common的相对路径,这里也可以输入绝对路径
这样就将common这个工程以node_module的方式引入到需要使用的项目中了。可以正常使用公共项目在index.js中导出的组件了。
命令执行完后,package.json里会多一条记录
- 进入使用该公共项目的文件夹,在控制台输入命令:npm install …/common/
- 方案一:npm发布引用
- 37.槽口请简述
- 它是一种内容分发机制,用来混合父组件的内容与子组件自己的模板(给组件设置一个开口,让他在调用的时候可以在里面插入数据)。
- 使用:数量相同、内容不同的时候 组件使用props,数量不同、内容也不相同的时候使用slot。
- 38.Watch请简述
- watch可以监听模型数据,当模型数据改变的时候就会触发。watch初始化的时候不会运行,只有数据被改变之后才会运行。当需要在数据变化时执行异步或开销较大的操作时,watch这个方式是最有用的。
- 39.Vantui请简述下
- Vant 是一个轻量、可靠的移动端 Vue 组件库,通过 Vant,可以快速搭建出风格统一的页面,提升开发效率。作为移动端组件库,Vant 一直将轻量化作为核心开发理念。为了平衡日益丰富的功能和轻量化之间的矛盾关系,Vant 内部使用了很多的优化方式,包括支持组件按需加载、公共模块复用、组件编译流程优化等。Vant 不只是提供基础的UI组件,为了方便开发者快速构建移动商城,Vant 增加了许多移动商城内常用的业务组件。
- 40.计算属性与watch区别
- 当watch监听的值发生改变就会被调用,watch可以在数据变化时做一些异步处理或者开销大的操作;计算属性是计算依赖的值,当依赖的值发生改变才会触发。
- 41.mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?
- 定义:MVVM分为三部分:分别是M(Model,模型层),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器MVC的C层)M:模型层,主要负责业务数据相关,V:视图层,负责视图相关,细分下来就是html+css层,VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点;因此开发者只需关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。
- 区别:vue数据驱动,通过数据来显示视图层而不是节点操作。
- 场景:数据操作比较多的场景,更加便捷
- 42.Vue首屏加载慢的原因,怎么解决的,白屏时间怎么检测,怎么解决白屏问题
- 加载慢的原因:因为路由的项目在第一次加载的时候会默认把所有的组件页面都进行渲染,如果页面多的话,加载太多,造成用户在进入项目的时候等待时间过久,出现白屏。
- 检测白屏:
- 解决:白屏时间指的是浏览器开始显示内容的时间。因此我们只需要知道是浏览器开始显示内容的时间点,即页面白屏结束时间点即可获取到页面的白屏时间。我们通常认为浏览器开始渲染 标签或者解析完 标签的时刻就是页面白屏结束的时间点。因此白屏时间则可以这样计算出:
- 可使用 Performance API 时
- 白屏时间 = firstPaint - performance.timing.navigationStart;
- 不可使用 Performance API 时
- 白屏时间 = firstPaint - pageStartTime;
- 可使用 Performance API 时
- 路由懒加载
- ES中的import(推荐)
{ path: '/', name: 'Home', //路由懒加载 component: () => import ('../views/Home.vue') }
- vue异步组件懒加载-- resolve:主要是使用了Promise.resolve()的异步机制,用require代替了import,实现按需加载
- ES中的import(推荐)
- gzip压缩:方法一:使用Nginx反向代理,配置nginx.conf文件;方法二:使用node压缩,需要使用compression库;
- 使用webpack的externals属性把不需要打包的库文件分离出去,减少打包后文件的大小
- 使用vue的服务端渲染(ssr) ssr优点是seo优化,以及加快首屏加载
- 43.Vue双数据绑定过程中,这边儿数据改变了怎么通知另一边改变
- 使用Object.defineProperty()来定义属性的set函数,属性被赋值的时候,修改Input的value值,然后监听input的keyup事件,修改对象的属性值,即可实现这样的一个简单的数据双向绑定。
- 44.Vuex流程
- 在vue组件里面,通过this.$store.dispatch来触发actions执行异步操作获取数据。
- 然后再通过store.commit来触发mutations来修改数据。
- mutations接收到commit的请求,就会自动修改state(数据中心里面的数据状态)里面的数据。
- 最后由store触发每一个调用它的组件进行更新
- 45.Vuex怎么请求异步数据
- 在store文件中引入import axios from “axios”
- 通过事件触发active
<button @click="fun()">点我发送请求</button> export default { methods: { fun(){ this.$store.dispatch("ajaxdemo") } }, }
- 创建actions 并进行异步请求,并且调用Mutations修改state数据
mutations: { uparr(state, payload) { state.arr = payload } }, actions: { ajaxdemo(store) { axios({ url: "http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187", method: "get" }).then((ok) => { console.log(ok); store.commit("uparr", ok.data.data.commentList) }) } }
- 46.Vuex中action如何提交给mutation的
- vuex的acions创建一个方法进行异步操作,他的形参就是store对象,把请求来的数据通过commit()传递给mutations
actions: { axioslink(store) { demoapi.demo().then((ok) => { console.log(ok.data.data.commentList); // 把请求来的数据给mutations进行state的修改 store.commit("uparr", ok.data.data.commentList) }) } }
- vuex的acions创建一个方法进行异步操作,他的形参就是store对象,把请求来的数据通过commit()传递给mutations
- 47.Route与router区别
- $router是VueRouter的一个对象,router的实例对象,这个对象是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。举例:history对象
- $route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等
- 48.vuex有哪几种状态和属性
- 有五种,分别是State , Getter , Mutation , Action , Module (就是mapAction)
- 49.vuex的State特性是?
- state就是存放数据的地方,类似一个仓库 , 特性就是当mutation修改了state的数据的时候,他会动态的去修改所有的调用这个变量的所有组件里面的值( 若是store中的数据发生改变,依赖这个数据的组件也会发生更新 )
- state:vuex中的数据源state,我们需要保存的数据就保存在这里(用来存储数据)
- 使用:
- 可以使用$store.state.xx调用
{{this.$store.state.name}}
- 使用数据的组件中使用计算属性调用 this.$store.state.xxx
computed:{ obj(){ return this.$store.state.obj } }
- 可以使用$store.state.xx调用
- state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
- 它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
- state就是存放数据的地方,类似一个仓库 , 特性就是当mutation修改了state的数据的时候,他会动态的去修改所有的调用这个变量的所有组件里面的值( 若是store中的数据发生改变,依赖这个数据的组件也会发生更新 )
- 50.vuex的Getter特性是?
- getters:相当于之前组件中学习的计算属性,getters属性主要是对于state中数据的一种过滤
- 使用场景:在项目开发中,有时候希望对state中的某个属性在多个组件中展示出不同状态
- 与使用state相同在组件中的计算属性当中使用 this.$store.getters.xxx来进行调用
- 语法
getters: { nameone(state) { return state.name.toUpperCase() }, nametwo(state) { return state.name.substr(0, 2) } }
<p>{{this.$store.getters.nameone}}</p> <p>{{this.$store.getters.nametwo}}</p>
- getters:相当于之前组件中学习的计算属性,getters属性主要是对于state中数据的一种过滤
- 51.vuex的Mutation特性是?
- mutations:里面装着一些改变数据方法的集合,就是把处理数据逻辑方法全部放在mutations里面,当触发事件的时候想改变state数据的时候使用mutations(在vuex中如果想进行数据的修改,必须在mutations中进行操作)
- 语法
mutations: { upone(state) { //创建一个方法,且必须有一个形参,对应要修改的那个数据state state.name = "haha" } }
- 不能直接调用一个mutations中的处理函数要使用this.$store.commit()来进行调用。
methods:{ fun(){ //调用mutations的commit()函数 this.$store.commit("upone") } }
- 之前的只是一个简单的修改state中的属性,在实际项目中往往会有值传递给mutations,给store.commit传一个附加参数,他就叫做mutation的载荷,一般使用payload
mutations: { uptwo(state, payload) { state.name = payload } }
methods:{ funb(){ // this.$store.commit("uptwo",把要传递给mutations的数据放到这里) this.$store.commit("uptwo",this.inputval) } }
- 如果要传多个参数,可以传递一个对象
this.$store.commit('add',{'name':'lxg','num':20...})
- mutations:里面装着一些改变数据方法的集合,就是把处理数据逻辑方法全部放在mutations里面,当触发事件的时候想改变state数据的时候使用mutations(在vuex中如果想进行数据的修改,必须在mutations中进行操作)
- 52.vuex的actions特性是?
- actions:进行异步操作(异步请求)
- 语法
actions: { axioslink(store) { demoapi.demo().then((ok) => { console.log(ok.data.data.commentList); // 把请求来的数据给mutations进行state的修改 store.commit("uparr", ok.data.data.commentList) }) } },
methods:{ func(){ //调用actions来进行异步请求 this.$store.dispatch("axioslink") } }
mutations: { uparr(state, payload) { state.arr = payload } }
- 语法
- actions:进行异步操作(异步请求)
- 53.Vuex是什么?怎么使用?在那种场景下使用
- Vuex是一个专为 Vue.js 应用程序开发中管理的一个模式。通过创建一个集中的数据存储,方便程序中的所有组件进行访问。
- 使用:
- 在store下的index.js中 Vue.use(Vuex)
- 创建store实例
export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, modules: {} })
- vuex只能用于单个页面中不同组件(例如兄弟组件)的数据流通。
- 54.vuex的优势
- 解决了非父子组件的消息传递(将数据存放在state中)
- 减少了AJAX请求次数,有些情景可以直接从内存中的state获取
- 双向绑定,使用commit修改一处状态后,所有引用的地方自动更新,不需要传值
- 55.Vue路由懒加载(按需加载路由)
- 懒加载简单来说就是延迟加载或按需加载,即在需要的时候进行加载。
为给客户更好的客户体验,首屏组件加载速度更快,解决白屏问题,当构建的项目比较大的时候,懒加载可以分割代码块,提高页面的初始加载效率。 - 使用
- vue异步组件懒加载:主要是使用了Promise.resolve()的异步机制,用require代替了import,实现按需加载
component:resolve=>(require(["引用的组件路径"],resolve))
- ES中的import(推荐):
const HelloWorld = ()=>import('需要加载的模块地址')
- vue异步组件懒加载:主要是使用了Promise.resolve()的异步机制,用require代替了import,实现按需加载
- 懒加载简单来说就是延迟加载或按需加载,即在需要的时候进行加载。
- 56.v-for与v-if优先级
- 首先不要把v-if与v-for用在同一个元素上,原因:v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候,v-for 比 v-if 具有更高的优先级
- 57.为什么要对element-ui进行二次封装
- element-ui组件的部分样式不满足当前项目的需求
- element-ui组件的样式是固定的,比如我们常用的那些组件,table,button,icon,tab等等。当我们需要的样式和element组件有偏差的时候,我们可以通过针对element组件进行二次封装,然后通过Vue.component()方法,定义到全局,来解决我们当前的项目需求
- element-ui组件出现问题的时候,我们有中间键支持,不至于整个项目崩塌。
- 其实这种现象是常有发生的,比如组件由最开始的开源的,突然收费了 (虽然我相信ele团队不会的)。或者element组件库的开发团队停止了维护。组件的二次封装都是有意义的。我们可以手写一个类似的组件,或者引入其它组件,使我们的项目,能够正常使用。综上所述,如果我们基于element做的项目,因为element出现了问题,组件的二次封装,可以有效的防止项目崩塌。
- element-ui组件的部分样式不满足当前项目的需求
- 58.为什么修改了data中的数据,但是视图没有更新?
- 当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。根据官方文档:定义如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
原因:当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 gettertter。 - 受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 gettertter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
解决方案:
可以使用$set()方法,既可以新增属性,又可以触发视图更新
- 当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。根据官方文档:定义如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
- 59.什么是Vue.nextTick以及它的应用场景
- 为了在数据变化之后等待 Vue 完成更新 DOM 可以在数据变化之后立即使用Vue.nextTick(callback)。这样回调函数在 DOM 更新完成后就会调用。在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
- 在Vue生命周期的created()钩子函数进行DOM操作一定要放到Vue.nextTick()的回调函数中。
created()钩子函数执行的时候DOM 其实并未进行任何渲染。所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中
- 60.Vue项目如何性能优化
- 懒加载
- 路由懒加载就是按需加载,不会让项目刚开始运行速度就很慢,能大大的优化用户体验
- 图片懒加载
<img v-lazy="1.jpg">
- 代码优化
- 封装组件和函数,提高代码复用率
- 减少本地存储的使用
- 减少watch使用:watch监听大量状态时会让浏览器出现卡顿
- 使用v-if代替v-show
- 用户体验优化
- 添加loading:当用户需要等待时间较长时,必须添加等待loading
- 路由逻辑
- 样式统一
- 滚动组件的使用
- 懒加载
- 61.v-show和v-if的区别
- 相同点:v-show和v-if都能控制元素的显示和隐藏
- 实现本质方法不同
- v-show本质就是通过设置css中的display设置为none,控制隐藏
- v-if是动态的向DOM树内添加或者删除DOM元素
- 性能
- v-if有更高的切换消耗(安全性高)
- v-show有更高的初始化的渲染消耗(对安全性无要求选择)
- 总结:如果要频繁切换某节点时,使用v-show(无论true或者false初始都会进行渲染,此后通过css来控制显示隐藏,因此切换开销比较小,初始开销较大),如果不需要频繁切换某节点时,使用v-if(因为懒加载,初始为false时,不会渲染,但是因为它是通过添加和删除dom元素来控制显示和隐藏的,因此初始渲染开销较小,切换开销比较大)
React
- 1.请简述你对react的理解
- 定义:React 起源于 Facebook;React是一个用于构建用户界面的javascript库。React拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它
- 特点
- 声明式设计 −React采用声明范式,可以轻松描述应用。(开发者只需要声明显示内容,react就会自动完成)
- 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
- 灵活 −React可以与已知的库或框架很好地配合。
- 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。(把页面的功能拆分成小模块–每个小模块就是组件)
- 单向数据流 -React是单向数据流,数据主要从父节点传递到子节点(通过props)。如果顶层(父级)的某个props改变了,React会重渲染所有的子节点
- 核心:React的核心就是组件:组件的设计目的是提高代码复用率,降低测试难度和代码的复杂程度
- 优点
- 它提高了应用的性能
- 可以方便地在客户端和服务器端使用
- 由于JSX,代码的可读性很好
- React很容易与 Meteor,Angular 等其他框架集成
- 使用React,编写UI测试用例变得非常容易
- React推荐在React中使用JSX来描述用户界面。当遇到<>,JSX就当HTML解析,遇到{}就当JavaScript解析
- 2.State与props区别
- state:
- state就是状态,它只是用来控制这个组件本身自己的状态,我们可以用state来完成对行为的控制、数据的更新、界面的渲染,由于组件不能修改传入的props,所以需要记录自身的数据变化
- 要想修改state中的数据,可以使用setState(),setState()是异步的会自动触发render函数的重新渲染
- props:
- props 是组件对外的接口,使用props就可以从外部向组件内部进行数据传递 完成父组件传值给子组件
- props对于使用它的组件来说,是只读的。一旦赋值不能修改。也就是说props的值是不可变的,只能在渲染的时候传入,无法动态赋值。
- state:
- 3.组件之间的数据传递
- 正向传值–使用props
- 父组件发送数据在子组件中使用this.props.xxx来接收数据,如果父级的某个props改变了,React会重渲染所有的子节点
- 逆向传值—函数传值
- 子组件通过事件调用函数传递
- 在子组件中使用this.props.调用的函数名 绑定发送数据
- 在父组件中进行函数传递
- 父组件中必须要有一个形参 用来接收子组件发送过来的数据
- 同级传值—pubsub-js
- 在第一个要传值的组件中进行数据抛出 PubSub.publish(“事件名”,“数据”)
- 在第二个要接收数据的组件中接收 PubSub.subscribe(“监听的事件”,(事件,数据)=>{})
- 跨组件传值—context
- context上下文对象,无需为每一层组件手动添加props,就能在组件数间进行数据传递的方法
- 使用createContext()方法提供了两个对象
- Provider对象 生产者---->用来生产数据
- Consumer对象 消费者---->用来使用数据
- 正向传值–使用props
- 4.Vue与react区别
- 相似之处
- 他们都是JavaScript的框架,专注于创造前端的数据应用。不同于早期的JavaScript框架“功能齐全”,Reat与Vue只有框架的骨架,其他的功能如路由、状态管理等是框架分离的组件。
- 都使用了虚拟DOM,Virtual DOM是一个映射真实DOM的JavaScript对象,如果需要改变任何元素的状态,那么是先在Virtual DOM上进行改变,而不是直接改变真实的DOM。当有变化产生时,一个新的Virtual DOM对象会被创建并计算新旧Virtual DOM之间的差别,之后这些差别会应用在真实的DOM上。
- 组件化 React与Vue都鼓励组件化应用
- Props React和Vue都有’props’的概念,props在组件中是一个特殊的属性,允许父组件往子组件传送数据。
- 构建工具 React和Vue都有自己的构建工具,你可以使用它快速搭建开发环境。
- 区别
- 数据
- vue:双向数据绑定和单向数据流。双向数据绑定:DOM元素绑定的data值,当发生改变后,vue的响应式机制会自动监听data的变化重新渲染。单向数据流:当父组件给子组件传递数据的时候,子组件只可以读取而不能修改数据。可以用watch监听数据的更改,再赋给父组件的变量。
- react:单向数据流。DOM元素依赖于state,但改变state不会改变渲染好的DOM,通过setState()才能重新渲染。父组件传值到子组件,如果顶级的props变了,会重新渲染所有的子组件。
- 虚拟DOM
- vue:计算出虚拟DOM的差异,在渲染的过程中跟踪每个组件的依赖关系,不会重新渲染整个组件树
- react:当应用的状态改变时,重新渲染全部子组件,可以通过shouldComponentUpdate生命周期进行优化
- 模板和jsx:
- vue:具有单文件组件,可以把html、css、js写在一个vue文件里----MVVM框架
- react:依赖于jsx,在JavaScript中创建DOM----视图层框架
- 数据
- 相似之处
- 5.请简述虚拟dom与diff算法
- 虚拟dom:虚拟dom相当于在js和真实dom中间加了一个缓存。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都首先重新构建整个DOM树(减少页面更新次数),然后React将当前整个DOM树和上一次的DOM树进行对比(DOM Diff算法-最小化页面重绘),得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新
- diff算法:diff算法是调和的具体实现,将Virtual(虚拟)DOM树转换成actual(真实)DOM树的最少操作的过程称为调和,diff算法的作用计算出虚拟DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面
- 6.你对组件的理解
- React的核心就是组件:组件的设计目的是提高代码复用率,降低测试难度和代码的复杂程度。
- 提高代码复用率:组件将数据和逻辑进行封装。
- 降低测试难度:组件高内聚低耦合(各个元素高集成度低关联性),很容易对单个组件进行测试。
- 代码的复杂程度:直观的语法,可以极大提高可读性。
- React的核心就是组件:组件的设计目的是提高代码复用率,降低测试难度和代码的复杂程度。
- 7.调用 setState 之后发生了什么?
- 在代码中调用setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建React元素树并且着手重新渲染整个UI界面。在React得到元素树之后,React 会自动计算出新的树与老树的节点偏差,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。
- 8.react 生命周期函数
- React 生命周期分为三种状态:挂载阶段、更新阶段、卸载阶段
- 初始化阶段:
- getDefaultProps:获取实例的默认属性
- getInitialState:获取每个实例的初始化状态
- componentWillMount: 组件即将被装载、渲染到页面上
- render:组件在这里生成虚拟的DOM节点
- componentDidMount:组件真正在被装载之后
- 运行中状态:
- componentWillReceiveProps:组件将要接收到属性的时候调用
- shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render 调用,后面的函数不会被继续执行了)
- componentWillUpdate:组件即将更新不能修改属性和状态o render:组件重新描绘
- componentDidUpdate:组件已经更新
- 销毁阶段:
- componentWillUnmount:组件即将销毁
- 9.为什么虚拟 dom 会提高性能?(必考)
- 虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom的diff算法避免了没有必要的dom操作,从而提高性能。
- 用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中,当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。
- 10.shouldComponentUpdate 是做什么的
- 判定组件是否要更新html 主要用于性能优化(部分更新)唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
- 11.react diff 原理
- 把树形结构按照层级分解,只比较同级元素。
- 给列表结构的每个单元添加唯一的key 属性,方便比较。
- React只会匹配相同class的component(这里面的class 指的是组件的名字)
- 合并操作,调用component的setstate方法的时候, React将其标记为dirty到每一个事件循环结束, React检查所有标记dirty 的component重新绘制
- 选择性子树渲染。开发人员可以重写shouldComponentUpdate提高diff的性能。
- 12.何为受控组件
- React负责渲染表单的组件,同时仍然控制用户后续输入时所发生的变化,值是来自于state控制的输入表单元素称为“受控组件”
- 13.(组件的)状态(state)和属性(props)之间有何不同
- State是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候为用户事件行为的结果。
- Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的props,但是可以把其子组件的props放在一起(统一管理)。Props 也不仅仅是数据-回调函数也可以通过props传递。
- 14.调用 super(props) 的目的是什么
- super调用父类的构造方法,此时组件才有自己的this,在组件的全局中都可以使用this关键字,否则如果只是constructor 而不执行 super() 那么以后的this都是错的,super()继承父组件的this
- 15.React 中构建组件的方式
- 函数组件/无状态组件
<script type="text/babel"> // 函数名使用大驼峰命名规范 function MyCom(){ return ( <div> <h1>我是一个react无状态组件</h1> </div> ) } ReactDOM.render(<MyCom/>,document.getElementById("demodiv")) </script>
- class类组件
- 一个组件类必须要实现一个render方法。这个方法必须要返回一个jsx元素。必须要用一个外层的jsx元素把所有的内容包裹起来,返回并列的多个元素需要有个父元素包裹
<script type="text/babel"> class MyCom extends React.Component{ render(){ return ( <div> <h1>我是一个react类组件</h1> </div> ) } } class Fu extends React.Component{ render(){ return ( <div> <MyCom/> <MyCom/> <MyCom/> </div> ) } } ReactDOM.render(<Fu/>,document.getElementById("demodiv")) </script>
- 一个组件类必须要实现一个render方法。这个方法必须要返回一个jsx元素。必须要用一个外层的jsx元素把所有的内容包裹起来,返回并列的多个元素需要有个父元素包裹
- 函数组件/无状态组件
- 16.什么是高阶组件HOC
- 参数是组件同时返回值也是组件
- 作用:封装可以在组件中高度复用的代码
- 高阶组件HOC接收props
- 如果组件是被高阶组件导出的 那么在正向传值的时候需要在高阶组件中进行传递
- 反向继承
- 作用:渲染劫持,按照条件选择性的给用户输出想要的内容
- super.render()是调用父类的render()渲染
- 17.什么是Hook
- 作用:让无状态组件可以使用状态和react的其他特性
- useState() React提供最基础、最常用的Hook,主要用来定义和管理本地状态
- useRef() 获取DOM节点
- useEffect() 无状态组件使用生命周期
- useReducer() 防止state里面的数据操作太复杂,减少state的数据操作复杂度
- 18.无状态组件的特点
- 组件不会被实例化,整体渲染性能得到提升
- 因为组件被精简成一个render方法的函数来实现的,无状态组件就不会在有组件实例化的过程,无实例化过程也就不需要分配多余的内存,从而性能得到一定的提升。
- 组件不能访问this对象
- 无状态组件由于没有实例化过程,所以无法访问组件this中的对象,若想访问this就不能使用这种形式来创建组件
- 组件无法访问生命周期的方法
- 19.三种请求方式的区别(ajax、axios、fetch)
- 传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。JQuery ajax 是对原生XHR的封装
- axios 是一个基于Promise ,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,
- fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
- 20.什么是React状态提升
- 定义:多个组件需要反映相同的变化数据,提升到它们最近的父组件上,在父组件上改变这个状态然后通过props分发给子组件
- 使用场景:两个子组件需要利用到对方的状态的话,那么这个时候我们就需要使用到状态提升
- 21.什么是Webpack
- WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
- 22.Webpack的组成
- webpack分成四个部分,其中最核心的就是入口(entry)和出口(output),当然在入口和出口配置的同时我们还需要一些加载器(Loaders)和插件(plugin),这就是我们所谓的webpack配置文件。这个配置文件我们习惯把其命名为webpack.config.js ,还有webpackfile.js
- 23.Webpack打包原理
- webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖的文件,使用loaders来处理它们,最后打包成一个或多个浏览器可识别的js文件
- 24.webpack的工作过程
- 解析配置参数,合并从(npm install 类似的命令)和webpack.config.js文件的配置信息,输出最终的配置信息;
- 注册配置中的插件,做出对应的反应;
- 解析配置文件中的entry入口文件,并找出每个文件依赖的文件,递归下去;
- 在递归每个文件的过程中,根据文件类型和配置文件中的loader找出对应的loader对文件进行转换;
- 递归结束后得到每个文件最终的结果,根据entry 配置生成代码;
- 25.什么是TypeScript
- TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上TypeScript扩展了JavaScript的语法解决JavaScript的“痛点”:弱类型和没有命名空间,导致很难模块化
- 优点:开源、简单、兼容性好
- 与js相比的优势
- TypeScript工具使重构更变的容易、快捷。
- TypeScript 引入了 JavaScript 中没有的“类”概念。
- TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中类型安全功能能在编码期间检测错误,这为开发人员创建了一个更高效的编码和调试过程。
- 26.React中Keys的作用是什么
- Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。因此要给数组中的每一个元素赋予一个确定的标识。
一个元素的key最好是这个元素在列表中拥有的一个独一无二的字符串
- Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。因此要给数组中的每一个元素赋予一个确定的标识。
- 27.React事件处理中如何修改this指向?
- 通过bind方法进行原地绑定,从而改变this指向
funa(){ this.setState({ text:"我变了1" }) } <button onClick={this.funa.bind(this)}>方式1:通过bind方法进行原地绑定,从而改变this指向</button>
- 通过创建箭头函数
funb=()=>{ this.setState({ text:"我变了2" }) } <button onClick={this.funb}>方式2:通过创建箭头函数</button>
- 在constructor中提前对事件进行绑定
func(){ this.setState({ text:"我变了3" }) } <button onClick={this.func}>方式3:在constructor中提前对事件进行绑定</button>
- 将事件调用的写法改为箭头函数的形式
fund(){ this.setState({ text:"我变了4" }) } <button onClick={(e)=>{this.funb("参数1","参数2",e)}}>通过箭头函数传递</button>
- 通过bind方法进行原地绑定,从而改变this指向
- 28.React如何实现组件传值
- 正向传值–使用props(父发送数据,子接收数据)
- 逆向传值—函数传值
- 子组件通过事件调用函数传递
- 在子组件中使用this.props.调用的函数名 绑定发送数据
- 在父组件中进行函数传递
- 同级传值—pubsub-js
- 在第一个要传值的组件中进行数据抛出 PubSub.publish(“事件名”,“数据”)
- 在第二个要接收数据的组件中接收 PubSub.subscribe(“监听的事件”,(事件,数据)=>{})
- 跨组件传值—context
- 在src下创建文件夹与.jsx文件用来容纳context对象
- 创建内容并且引用createContext对象
- 在根组件index.js中使用
- 创建Provider生产者与Consumer消费者对象并且创建数据
- 在需要的组件中进行使用