web前端面试题HTML+CSS+CSS3 综合前端面试题知识点附答案

1.Doctype作用?标准模式与兼容模式各有什么区别?

(1)、<!DOCTYPE>声明位于位于HTML文档中的第一行,处于 <html> 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。

(2)、标准模式的排版 和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。

2.行内元素有哪些?块级元素有哪些? 空(void)元素有那些?

首先:CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,如div的display默认值为“block”,则为“块级”元素;span默认display属性值为“inline”,是“行内”元素。

(1)行内元素有:a b span img input select strong(强调的语气)
(2)块级元素有:div ul ol li dl dt dd h1 h2 h3 h4…p

(3)常见的空元素:

<br> <hr> <img> <input> <link> <meta>
鲜为人知的是:
 <area> <base> <col> <command> <embed> <keygen> <param> <source> <track> <wbr>

3. Xhtml 与 Html 有什么区别? ?

一个是功能上的差别
主要是 XHTML 可兼容各大浏览器、手机以及 PDA ,并且浏览器也能快速正确地编译网页
另外是书写习惯的差别
XHTML 元素必须被正确地嵌套,闭合,区分大小写,文档必须拥有根素

4.页面导入样式时,使用link和@import有什么区别?

(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;

(2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;

(3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;

5.语义化的理解

用正确的标签做正确的事情!
HTML 语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;
在没有样式 CSS 情况下也以一种文档格式显示,并且是容易阅读的。
搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,利 SEO 。
使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解

6.简述一下 src 与 href 的区别

src 用于替换当前元素,href 用于在当前文档和引用资源之间确立联系。
src 是 source 的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在
位置;在请求 src 资源时会将其指向的资源下载并应用到文档内,例如 js 脚本, img 图片和
frame 等元素
href 是 Hypertext Reference 的缩写,指向网络资源所在位置,建立和当前元素(锚点)
或当前文档(链接)之间的链接,如果我们在文档中添加

那么浏览器会识别该文档为 css 文件,就 会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用 link 方式来加 载 css ,而不是使用 @import 方式

7.WEB 标准和 W3C 标准是什么?

标签闭合、标签小写、不乱嵌套、使用外链 css 和 js 结构行为表现的分离

8.请描述一下 cookies,sessionStorage 和 localStorage 的区别?

cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

存储大小:
cookie数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

有期时间:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除。
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

9.px和em,rem的区别?

px 实际上就是像素,用PX设置字体大小时,比较稳定和精确。px是固定长度单位,不随其它元素的变化而变化
em 就是根据基准来缩放字体的大小。em 是相对长度单位。em是相对于父级元素的单位,会随父级元素的属性(font-size或其它属性)变化而变化
rem是CSS3新增的一个相对单位,rem是相对于根目录(HTML元素)的,所有它会随HTML元素的属性(font-size)变化而变化
例如: ==屏幕宽度/设计宽度 = 1rem的值/预设定rem的值。
1920/1920=100/100 ;
所以 1rem=1920/1920*100 ;
document.documentElement 是html节点
document.documentElement.style.fontSize = ((windowWidth / designWidth) * rem2px) + ‘px’;
假如,用户将屏幕拖小了,变为960。1rem将自动变为50px;960/1920乘以100=50
这里需要判断下,当屏幕的宽度大于设计稿定义的宽度,用设计稿的宽度,如果小于,用屏幕宽度作为变量屏幕宽度。

10.什么是BFC?BFC的原理?

块级格式化上下文。是一种边距重叠解决方案。
应用场景: 1. 解决margin叠加的问题
2. 用于布局(overflow: hidden)
3.BFC不会与浮动盒子叠加。
3. 用于清除浮动,计算BFC高度。

11.SEO 优化

合理的 title 、 description 、 keywords :搜索对着三项的权重逐个减小, titl 值强调重点即可,重要关键词出现不要超过 2 次,而且要靠前,不同页面 title 要有所不同;
description 把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页 description有所不同; keywords 列举出重要关键词即可。
语义化的 HTML 代码,符合 W3C 规范:语义化代码让搜索引擎容易理解网页
重要内容 HTML 代码放在最前:搜索引擎抓取 HTML 顺序是从上到下,有的搜索引擎对抓取长
度有限制,保证重要内容一定会被抓取。
重要内容不要用 js 输出:爬虫不会执行 js 取内容
少用 iframe :搜索引擎不会抓取 iframe 中的内容
非装饰性图片必须加 alt
提高网站速度:网站速度是搜索引擎排序的一个重要指标

12.渲染优化

禁止使用 iframe 阻塞父文档 onload 事件)
iframe 会阻塞主页面的 Onload 事件
搜索引擎的检索程序无法解读这种页面,不利于 SEO
iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载
使用 iframe 之前需要考虑这两个缺点。如果需要使用 iframe ,最好是通过 javascript
动态给 iframe 添加 src 属性值,这样可以绕开以上两个问题
禁止使用 gif 图片实现 loading 效果(降低 CPU 消耗,提升渲染性能)
使用 CSS3 代码代替 JS 动画(尽可能避免重绘重排以及回流)
对于一些小图标,可以使用 base64 位编码,以减少网络请求。但不建议大图使用,比较耗费 CPU
页面头部的 会阻塞页面;(因为 Renderer 进程中 JS 线程和渲染线程是互斥的)
页面中空的 href 和 src 会阻塞页面其他资源的加载 (阻塞下载进程)
网页 gzip , CDN 托管, data 缓存 ,图片服务器
前端模板 JS+数据,减少由于 HTML 标签导致的带宽浪费,前端用变量保存 AJAX 请求结
果,每次操作本地变量,不用请求,减少请求次数
用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能
当需要设置的样式很多时设置 className 而不是直接操作 style
少用全局变量、缓存 DOM 节点查找的结果。减少 IO 读取操作
图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳
对普通的网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘 IO

13.iframe有那些缺点?

*iframe会阻塞主页面的Onload事件;
*搜索引擎的检索程序无法解读这种页面,不利于SEO;

*iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。

使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript
动态给iframe添加src属性值,这样可以绕开以上两个问题。

CSS

1.介绍一下标准的 CSS 的盒子模型?与低版本 IE 的盒子模型有什么不同的?

标准盒子模型:宽度=内容的宽度( content )+ border + padding + margin 。
低版本 IE 盒子模型:宽度=内容宽度( content + border + padding )+ margin。

2.CSS是如何设置这两种模型,那么二者怎么转化呢?

content-box: 指的是W3C标准盒模型,也是默认的设置属性。
border-box:指的是IE盒模型,width和height包含了padding和border。

3.CSS选择符有哪些?哪些属性可以继承?

  • 1.id选择器( # myid)
    2.类选择器(.myclassname)
    3.标签选择器(div, h1, p)
    4.相邻选择器(h1 + p)
    5.子选择器(ul > li)
    6.后代选择器(li a)
    7.通配符选择器( * )
    8.属性选择器(a[rel = “external”])
    9.伪类选择器(a:hover, li:nth-child)

  • 可继承的样式: font-size font-family color, UL LI DL DD DT;

  • 不可继承的样式:border padding margin width height ;

4.CSS优先级算法如何计算?

  • 优先级就近原则,同权重情况下样式定义最近者为准;

  • 载入样式以最后载入的定位为准;

优先级为:
!important > id > class > tag
important 比 内联优先级高

5.CSS3新增伪类有那些?

举例:
p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。
p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。

:after          在元素之前添加内容,也可以用来做清除浮动。
:before         在元素之后添加内容
:enabled        
:disabled       控制表单控件的禁用状态。
:checked        单选框或复选框被选中。

6.什么是伪类选择器和伪元素?列举3个CSS3中引入的伪类选择器和伪元素!

伪类用一个冒号来表示,而伪元素则用两个冒号来表示。
伪元素选择器:dom中不存在的元素,仅仅是css中用来渲染,添加一些特殊效果的,比如p::before,选择p标签(真元素)前面的假元素(伪元素,p标签前面没有元素,只是假设有)
::first-line选择元素的第一行,比如说改变每个段落的第一行文本的样式
::before和::after这两个主要用来给元素的前面或后面插入内容,这两个常用"content"配合使用,见过最多的就是清除浮动
::selection用来改变浏览网页选中文的默认效果

伪类选择器:一个概念上的类,不是我们定义的,是抽象的。如a:hover,选择a标签(元素选择器)中具有鼠标悬停类的所有元素,这个类是抽象的,不是我们自己定义的,再如first-child,选择第一个,选择具有这个类性质的所有元素,“第一个”,这个类就抽象了,我们没必要定义一个第一个这样的类
列举::root()选择器,根选择器,匹配元素E所在文档的根元素。在HTML文档中,根元素始终是(html)。:root选择器等同于(html)元素。
:not()选择器称为否定选择器,和jQuery中的:not选择器一模一样,可以选择除某个元素之外的所有元素。
:empty()选择器表示的就是空。用来选择没有任何内容的元素,这里没有内容指的是一点内容都没有,哪怕是一个空格。

7.px和em,rem的区别?

px 实际上就是像素,用PX设置字体大小时,比较稳定和精确。px是固定长度单位,不随其它元素的变化而变化
em 就是根据基准来缩放字体的大小。em 是相对长度单位。em是相对于父级元素的单位,会随父级元素的属性(font-size或其它属性)变化而变化
rem是CSS3新增的一个相对单位,rem是相对于根目录(HTML元素)的,所有它会随HTML元素的属性(font-size)变化而变化
例如: ==屏幕宽度/设计宽度 = 1rem的值/预设定rem的值。
1920/1920=100/100 ;
所以 1rem=1920/1920*100 ;
document.documentElement 是html节点
document.documentElement.style.fontSize = ((windowWidth / designWidth) * rem2px) + ‘px’;
假如,用户将屏幕拖小了,变为960。1rem将自动变为50px;960/1920乘以100=50
这里需要判断下,当屏幕的宽度大于设计稿定义的宽度,用设计稿的宽度,如果小于,用屏幕宽度作为变量屏幕宽度。

8.position 的值,relative 和 absolute 的区别

absolut :生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位
fixed :生成绝对定位的元素,相对于浏览器窗口进行定位
relative :生成相对定位的元素,相对于其正常位置进行定位
static 默认值。没有定位,元素出现在正常的流中
inherit 规定从父元素继承 position 属性的值

9.display 有哪些值?说明他们的作用?

block 转换成块状元素。
inline 转换成行内元素。
none 设置元素不可见。
inline-block 象行内元素一样显示,但其内容象块类型元素一样显示。
list-item 象块类型元素一样显示,并添加样式列表标记。
table 此元素会作为块级表格来显示
inherit 规定应该从父元素继承 display 属性的值

10.解释下浮动和它的工作原理?清除浮动的技巧

由于浮动元素不再占用原文档流的位置,所以它会对后面的元素排版产生影响,清除浮动的本质:主要为了解决父级元素因为子级浮动引起内部高度为0的问题。

1.使用空标签清除浮动。
这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。
2.使用overflow。
给包含浮动元素的父标签添加css属性 overflow:auto; zoom:1; zoom:1用于兼容IE6。
3.使用after伪对象清除浮动。
该方法只适用于非IE浏览器。
该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;

#parent:after{
 
    content:".";

    height:0;

    visibility:hidden;

    display:block;

    clear:both;

}
#parent{
    zoom:1;
}

4.可以给父元素设置overflow:auto或者hidden

11.CSS3有哪些新特性?

新增各种CSS选择器 (: not(.input):所有 class 不是“input”的节点)
圆角 (border-radius:8px)
多列布局 (multi-column layout)
阴影和反射 (Shadow\Reflect)
文字特效 (text-shadow、)
文字渲染 (Text-decoration)
线性渐变 (gradient)
旋转 (transform)
增加了旋转,缩放,定位,倾斜,动画,多背景
transform:\scale(0.85,0.90)\ translate(0px,-30px)\ skew(-9deg,0deg)\Animation:

12.水平居中的方法?

元素为行内元素,设置父元素 text-align:center
如果元素宽度固定,可以设置左右 margin 为 auto ;
如果元素为绝对定位,设置父元素 position 为 relative ,元素
left:0;right:0;margin:auto;
使用 flex-box 布局,指定 justify-content 属性为 center
splay 设置为 tabel-ceil

13.两种以上方式实现已知或者未知宽度的垂直水平居中?

 第一种:
 .wraper {
 position: relative;
 .box {
 position: absolute;
 top: 50%;
 left: 50%;
 width: 100px;
 height: 100px;
margin: -50px 0 0 -50px;
 }
 }
 第二种:
 .wraper {
 position: relative;
 .box {
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 }
 }

 第三种:
 .wraper {
 .box {
display: flex;
 justify-content: center;
 align-items: center;
 height: 100px;
 }
 }
 第四种:
.wraper {
 display: table;
 .box {
 display: table-cell;
 vertical-align: middle;
 }
 }

JS

介绍js有哪些内置对象?

Object 是 JavaScript 中所有对象的父对象

数据封装类对象:Object、Array、Boolean、Number 和 String

其他对象:Function、Arguments、Math、Date、RegExp、Error

null,undefined 的区别?

null是一个表示"无"的对象,转为数值时为0
undefined是一个表示"无"的原始值,转为数值时为NaN
当声明的变量还未被初始化时,变量的默认值为undefined
null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象
undefined表示 “缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:

1.变量被声明了,但没有赋值时,就等于 undefined
2. 调用函数时,应该提供的参数没有提供,该参数等于 undefined
3. 对象没有赋值的属性,该属性的值为 undefined
4. 函数没有返回值时,默认返回 undefined
null表示“没有对象”,即该处不应该有值。典型用法是:
5. 作为函数的参数,表示该函数的参数不是对象
6. 作为对象原型链的终点

说说你对作用域链的理解

作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向
上访问,变量访问到 window 对象即被终止,作用域链向下访问变量是不被允许的
作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期

JavaScript 原型,原型链 ? 有什么特点?

每个对象都在其内部初始化一个属性,就是 prototype (原型),当我们访问一个对象的属性时如果这个对象内部不存在这个属性,那么他就会去 prototype 里找这个属性,这个prototype 又会有自己的 prototype ,于是就这样一直找下去,也就是我们平时所说的原型链的概念
关系: instance.constructor.prototype = instance.proto
JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的
原型副本。当我们修改原型时,与之相关的对象也会继承这一改变
当我们需要一个属性的时, Javascript 引擎会先看当前对象中是否有这个属性,如果没有的
就会查找他的 Prototype 对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象

如何判断一个变量是对象还是数组?

1、我们能够使用typeof判断变量的身份,判断字符串得到string,数字和NaN得到number,函数会得到function等,但是判断数组,对象和null时都会得到object,这就是typeof的局限性,
2、使用instanceof(比较运算符)可以用来判断一个变量是数组还是对象
3、constructor(构造函数)
4、Object.prototype.toString.call()
总结:判断简单数据类型可以用typeof,判断数组,对象使用instanceof,constructor和 Object.prototype.toString.call(),最好使用Object.prototype.toString.call(),更加精准

谈谈This对象的理解。

this总是指向函数的直接调用者(而非间接调用者);
如果有new关键字,this指向new出来的那个对象;
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window;

数组去重的方法

1.ES6 Set去重
var arr = [1,2,3,3,2,1,5,1];
var arr2 = Array.from(new Set(arr))
console.log(arr2)
var arr = [1,2,3,3,2,1,5,1];
let a = [...new Set(arr)]
console.log(a)

2.利用for嵌套for,然后splice去重

function unique(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) { //第一个等同于第二个,splice 方法删除第二个
arr.splice(j, 1);
j–;
}
}
}
return arr;
}

3.利用indexOf去重

var arr = [1,3,4,5,6,7,4,3,2,4,5,6,7,3,2];
function find(){
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) == -1 ) { //也可以换成if(newArr.indexOf(arr[i])<0)
newArr.push(arr[i]);
  }
}
consoloe.log(newArr); // [1, 3, 4, 5, 6, 7, 2]
}
find(arr); //调用这个方法  indexOf对大小写敏感

4.利用filter

filter(x,index,self)可以为数组提供过滤功能,其中x代表元素,index是与X一同传入元素的索引,而self代表数组本身。

var arr = [1, 2, 2, 3, 4, 5, 5, 6, 7, 7];
var arr2 = arr.filter(function(x, index,self) {
return self.indexOf(x)===index;
}); 
console.log(arr2); //[1, 2, 3, 4, 5, 6 ,7]

事件委托

简介:事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同的响应。
举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。
好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。

虚拟dom和实体dom的区别?

DOM的本质:
浏览器概念,浏览器从服务器端读取html页面,浏览器将html解析成一棵元素嵌套关系的dom树,用对象来表示页面上的元素,并提供操作dom对象的api。
虚拟DOM:
框架概念,程序员用js对象来模拟页面上dom元素的嵌套关系( 本质 ),为了实现页面元素的高效更新( 目的 )
区别:1、虚拟DOM不会进行重排与重绘操作;
2、虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要修改的部分,最后进行重排和重绘,减少过多DOM节点重排和重绘损耗。
3、虚拟DOM有效降低大面积(真实DOM节点)的重排和重绘,因为最终与真实DOM比较差异,可以局部渲染

js阻止事件冒泡的两种方法

event.stopPropagation( )
event.target

DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。

事件捕获(event capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。
事件冒泡(dubbed bubbling):与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点。
无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播,
dom标准事件流的触发的先后顺序为:先捕获再冒泡,即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。

DOM操作——怎样添加、移除、移动、复制、创建和查找节点。

1.访问/获取节点

document.getElementById(id);           //返回对拥有指定id的第一个对象进行访问

document.getElementsByName(name);      //返回带有指定名称的节点集合   注意拼写:Elements

document.getElementsByTagName(tagname);   //返回带有指定标签名的对象集合  注意拼写:Elements

document.getElementsByClassName(classname); //返回带有指定class名称的对象集合 注意拼写:Elements

2.创建节点/属性

document.createElement(eName);  //创建一个节点

document.createAttribute(attrName); //对某个节点创建属性

document.createTextNode(text);   //创建文本节点

3.添加节点

document.insertBefore(newNode,referenceNode);  //在某个节点前插入节点

parentNode.appendChild(newNode);        //给某个节点添加子节点

4.复制节点

cloneNode(true | false);  //复制某个节点 参数:是否复制原节点的所有属性

5.删除节点

parentNode.removeChild(node);  //删除某个节点的子节点 node是要删除的节点

注意:为了保证兼容性,要判断元素节点的节点类型(nodeType),若nodeType==1,再执行删除操作。通过这个方法,就可以在 IE和 Mozilla 完成正确的操作。

ES6

var、let、const之间的区别

var声明变量可以重复声明,而let不可以重复声明
var是不受限于块级的,而let是受限于块级
var会与window相映射(会挂一个属性),而let不与window相映射
var可以在声明的上面访问变量,而let有暂存死区,在声明的上面访问变量会报错
const声明之后必须赋值,否则会报错
const定义不可变的量,改变了就会报错
const和let一样不会与window相映射、支持块级作用域、在声明的上面访问变量会报错

介绍下 Set、Map的区别?

应用场景Set用于数据重组,Map用于数据储存Set: 
(1)成员不能重复
(2)只有键值没有键名,类似数组
(3)可以遍历,方法有add, delete,has
Map:
(1)本质上是健值对的集合,类似集合
(2)可以遍历,可以跟各种数据格式转换

forEach、for in、for of三者区别

forEach更多的用来遍历数组

var myArr=[
{id:1,name:“sdf”},
{id:2,name:“dfsdf”},
{id:3,name:“fff”}
]
myArr.forEach((item,index)=>{
console.log(item.id);
//1,2,3
})

for in 一般常用来遍历对象或json

   //对象本身没有length,所以不能用for循环遍历
11     //要用for。。。in...循环
12 //    var aaa = {"name":"拴住","age":18,"arr":[1,2,3]};
13 //
14 //    for(var k in aaa){
15 //        console.log(k);
16 //        //aaa.k代表aaa这个对象的k属性的值,并不是k对应的变量值的属性。
17         console.log(aaa.k);
18 //        //aaa[k],代表的是aaa这个对象中k这个变量值对应的属性值。
19 //        console.log(aaa[k]);
20 //    }
21 
22 //    var arr = [1,2,3];
23 //    for(var k in arr){
24 //        console.log(arr[k])
25 //    }
26 
27 
28     //制作一个json,然后
29 //    var json = {};
30 //    console.log(json);
31 //    for(var i=1;i<10;i++){
32 //        json[i] = i*10;
33 //    }
34 //    console.log(json);
35 
36 //    for(var k in json){
37 //        console.log(json[k]);
38 //    }

for of数组对象都可以遍历,遍历对象需要通过和Object.keys()

let obj = {
        a: 1
        , b: 2
        , c: 3
        , d: 4
    }
    ;

for( let k in obj ){
    console.log(k, obj[k]);
}

for in循环出的是key,for of循环出的是value

对象的拷贝 对象的拷贝? ?

深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。

// 当b复制了a,a发生变换的时候b也会发生变化 ---- 浅拷贝
        //浅拷贝
        var a =[1,2,3,4,5]
        b=a
        console.log(a===b)
        a[0] = 6
        console.log(a,b)
        function copy(arr){
            var arry = []
            for(var i=0;i<arr.length;i++){
                arry.push(arr[i])
            }
            return arry
        }
        var c = copy(a)
        console.log(c)
        var obj={
            name:'zhangsan',
            age:18
        }
        function copyobj(obj){
            var res={}
            for(var key in obj){
                res[key] = obj[key]
            }
            return res
        }
        var obb = copyobj(obj)
        console.log(obb)
        // 浅拷贝
深拷贝
var obj={
            a:1,
            arr:[1,2],
            nation:'中国',
            city:['广东','深圳','上海']
        }
        var obj2={
            name:'张三'
        }
        obj2 = deepcopy(obj,obj2)
        console.log(obj2)
        function deepcopy(o,c){
            var c = c || {}
            for (var i in o){
                if(typeof o[i] === 'object'){
                    if(o[i].constructor === Array){
                        c[i] = []
                    }else {
                        c[i] = {}
                    }
                    deepcopy (o[i],c[i])
                }else {
                    c[i] = o[i]
                }
            }
            return c
        }

        function deepclone (obj){
            var newobj = obj instanceof Array ? [] : {};
            if(typeof obj !== 'object'){
                return obj
            }else {
                for (var i in obj){
                    newobj[i] = typeof obj[i] === 'object' ? deepclone( obj[i]) : obj[i];
                }
            }
            return newobj
        }

        var a =[1,2,3,4,'a','b',[1,2,3,4]]
        var  b = deepclone(a)
        a[3] = 9
        console.log(b)
        console.log(a)

说一下什么是Http协议

对客户端和服务器端之间数据传输的格式规范,格式简称为“超文本传输协议”

Http协议由什么组成?

请求报文包括三部分:
(1).请求行:包含请求方法,URI,HTTP版本协议 (2).请求首部字段 (3).请求内容实体
响应报文包含三部分:
(1).状态行:包含HTTP版本,状态码,状态码原因短语 (2).响应首部字段 (3).响应内容实体

HTTP协议的工作原理?

HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息,通常情况下会配合数字证书实现。

什么是Http协议无状态协议?怎么解决Http协议无状态协议?

(1)、无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息
(2)、无状态协议解决办法: 通过1、Cookie 2、通过Session会话保存。

Http协议中有哪些请求方式?

GET:用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器,从指定的资源请求数据
POST:用于传输信息给服务器, 向指定的资源提交要处理的数据
PUT:传输文件,报文主体中包含文件内容,保存到对应URI位置
HEAD:获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效
DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件
OPTIONS:查询响应URI支持的HTTP方法

get和post的区别

GET在浏览器回退时是无害的,而POST会再次提交请求。

GET产生的URL地址可以被Bookmark,而POST不可以。

GET请求会被浏览器主动cache,而POST不会,除非手动设置。

GET请求只能进行url编码,而POST支持多种编码方式。

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

GET请求在URL中传送的参数是有长度限制的,而POST么有。

对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

GET参数通过URL传递,POST放在Request body中。

跨域? ?

理解跨域的概念:协议、域名、端口都相同才同域,否则都是跨域

什么情况下会碰到跨域问题?有哪些解决方法?

跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
解决方法:1. JSONP方法:JSONP是服务器与客户端跨源通信的常用方法,Jsonp 需要目标服务器配合一个callback函数网页通过添加一个(script)元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
首先,网页动态插入(script)元素,由它向跨源网址发出请求。
2.通过修改document.domain来跨子域
3.使用window.name来进行跨域
4.通过CORS解决AJAX跨域

VUE

谈谈你对MVVM开发模式的理解

Vue是一个 MVVM框架,其各层的对应关系如下:
View层:在Vue中是绑定dom对象的HTML(代表UI视图,负责数据的展示;)
ViewModel层:在Vue中是实例的vm对象 (负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;)
Model层:在Vue中是data、computed、methods等中的数据(代表数据模型,数据和业务逻辑都在Model层中定义;)
在 Model 层的数据变化时,View层会在ViewModel的作用下,实现自动更新

Vue的响应式原理?

Vue响应式底层实现方法是 Object.defineProperty() 方法,该方法中存在一个getter和setter的可选项,可以对属性值的获取和设置造成影响
Vue中编写了一个wather来处理数据,在使用getter方法时,总会通知wather实例对view层渲染页面,同样的,在使用setter方法时,总会在变更值的同时,通知wather实例对view层进行更新

Vue的生命周期

Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂
载 Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

创建前/后: 在 beforeCreate 阶段, vue 实例的挂载元素 el 和数据对象 data 都为
undefined ,还未初始化。在 created 阶段, vue 实例的数据对象 data 有了,el 还没有。

载入前/后:在 beforeMount 阶段, vue 实例的 $el 和 data 都初始化了,但还是挂载之前为
虚拟的 dom 节点, data.message 还未替换。在 mounted 阶段, vue 实例挂载完成,data.message 成功渲染

更新前/后:当 data 变化时,会触发 beforeUpdate 和 updated 方法

属销毁前/后:在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 vue实例已经解除了事件监听以及和 dom 的绑定,但是 dom 结构依然存在

1.beforeCreate --创建前

触发的行为:vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
在此阶段可以做的事情:加loading事件

2.created --创建后

触发的行为:vue实例的数据对象data有了,$el还没有
在此阶段可以做的事情:解决loading,请求ajax数据为mounted渲染做准备

3.beforeMount --渲染前

触发的行为:vue实例的$el和data都初始化了,但还是虚拟的dom节点,具体的data.filter还未替换
在此阶段可以做的事情:。。。

4.mounted --渲染后

触发的行为:vue实例挂载完成,data.filter成功渲染
在此阶段可以做的事情:配合路由钩子使用

5.beforeUpdate --更新前

触发的行为:data更新时触发
在此阶段可以做的事情:。。。

6.updated —更新后

触发的行为:data更新时触发
在此阶段可以做的事情:数据更新时,做一些处理(此处也可以用watch进行观测)

7.beforeDestroy —销毁前

触发的行为:组件销毁时触发
在此阶段可以做的事情:可向用户询问是否销毁

8.destroyed —销毁后

触发的行为:组件销毁时触发,vue实例解除了事件监听以及和dom的绑定(无响应了),但DOM节点依旧存在
在此阶段可以做的事情:组件销毁时进行提示

请详细说下你对vue生命周期的理解?

答:总共分为8个阶段:创建前 / 后,载入前 / 后,更新前 / 后,销毁前 / 后。
创建前/后: 在beforeCreated阶段,vue实例的挂载元素e l 和 数 据 对 象 d a t a 都 为 u n d e f i n e d , 还 未 初 始 化 。 载 入 前 / 后 : 在 b e f o r e M o u n t 阶 段 , v u e 实 例 的 el和数据对象data都为undefined,还未初始化。 载入前/后:在beforeMount阶段,vue实例的el和数据对象data都为undefined,还未初始化。载入前/后:在beforeMount阶段,vue实例的el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

vue生命周期在真实场景下的业务应用

created: 进行ajax请求异步数据的获取、初始化数据
mounted: 挂载元素内dom节点的获取
nextTick: 针对单一事件更新数据后立即操作dom
updated: 任何数据的更新,如果要做统一的业务逻辑处理
watch: 监听具体数据变化,并做相应的处理

vue 的优点,缺点是什么

低耦合。
视图( View )可以独立于 Model 变化和修改,一个 ViewModel 可以绑定到不同的"
View "上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候 View 也可以不变。

可重用性。
你可以把一些视图逻辑放在一个 ViewModel 里面,让很多 View 重用这段视图逻辑。独立开发。开发人员可以专注于业务逻辑和数据的开发( ViewModel ),设计人员可以专注于页面设计。

可测试。
界面素来是比较难于测试的,而现在测试可以针对 ViewModel 来写。

vue核心是一个响应的数据绑定系统,mvvm,数据驱动,组件化,轻量,简洁,高效,快速,模块好。

缺点:不支持低版本浏览器,最低到IE9,不利于SEO的优化,首页加载时间较长,不可以使用浏览器的导航按钮需要自行实现前进后退。

为什么说 vue 是一个渐进式框架?

原首先我们需要理解什么是框架。在最初的前端开发中,为了完成一些功能,我们需要通过原生 js 获取 html 中的 DOM 节点,随后插入内容或添加事件,进行一系列操作。但是,一般需求的业务逻辑都是比较复杂的,这对原生 js 处理起来就很吃力,代码的可维护性也就随时间慢慢降低。这个时候我们需要把视图( View )、数据( Model )、逻辑控制( VM )分离。这就是 MVVM 模式的雏形。
在核心库的基础上,vue 现在已经有了一套完整的生态系统,我们可以添加 Vuex,可以添加 vue-router,可以添加任何你想添加的第三方库,这些都是互相独立的。可以说 vue 是轻量型的,是渐进型的
Vue 与 React、Angular 的不同是,但它是渐进的:
你可以在原有大系统的上面,把一两个组件改用它实现,当 jQuery 用
也可以整个用它全家桶开发,当 Angular 用
可以用它的视图,搭配你自己设计的整个下层用
可以在底层数据逻辑的地方用 OO 和设计模式的那套理念
也可以函数式,都可以,它只是个轻量视图而已,只做了最核心的东西

vue 父组件如何向子组件中传递数据?

组件传给子组件:子组件通过 props 方法接受数据
子组件传给父组件: $emit 方法传递参数
计算属性不仅可以依赖当前 Vue 实例的数据,还可以依赖其他实例的数据
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项
目比较小时,用这个比较合适(虽然也有不少人推荐直接用 VUEX,具体来说看需求)

vue 兄弟组件之间如何传值?

可以用过一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,之后通过分别调用Bus事件触发e m i t 和 监 听 emit和监听emit和监听on来实现组件之间的通信和参数传递,类似window的全局自定义事件。类似与子传父,只不过是利用一个新的vue示例作为媒介,而不是当前vue示例(this)

第一次加载页面会触发哪几个钩子

第一次加载会触发 beforeCreate、created、beforeMount、mounted四个钩子

router是什么?

1.router:this.$router 是路由【导航对象】,用它 可以方便的 使用 JS 代码,实现路由的 前进、后退、跳转到新的 URL 地址

2.routes:指创建vue-router路由实例的配置项。用来配置多个route路由对象

3.route:this.$route 是路由【参数对象】,所有路由中的参数, params, query 都属于它

v-if跟v-show的区别

v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;
v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;
v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。
如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

vue 常用的修饰符?

v-model 修饰符:
 .lazy: 输入框改变,这个数据就会改变,这个修饰符会在光标离开 input 框才会更新数据

 <input type="text" v-model.lazy="value">

 .number: 营先输入数字就会限制输入只能是数字,先字符串就相当于没有加 number,注
意,不是输入框不能输入字符串,是这个数据是数字

 <input type="text" v-model.number="value">

 .trim: 输入框过滤首尾的空格

 <input type="text" v-model.trim="value">

 事件修饰符:
 .stop: 阻止事件冒泡,相当于调用了 event.stopPropagation()方法

 <button @click.stop="test"></button>

 .prevent: 阻止默认行为,相当于调用了 event.preventDefault()方法,比如表单的提交、
a 标签的跳转就是默认事件

 <a href="" @click.prevent="test"></a>

 .self: 只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个 div
里面有个按钮,div 和按钮都有事件,我们点击按钮,div 绑定的方法也会触发,如果 div
的 click 加上 self,只有点击到 div 的时候才会触发,变相的算是阻止冒泡

 <div @click.stop="test"></div>

 .once: 事件只能用一次,无论点击几次,执行一次之后都不会再执行

 <div @click.once="test"></div>
 
 .capture: 事件的完整机制是捕获-目标-冒泡,事件触发是目标往外冒泡
 .sync: 对 prop 进行双向绑定
 .keyCode: 监听按键的指令,具体可以查看 vue 的键码对应表
 

vue常用的5个事件修饰符

.stop: 阻止事件冒泡;
.prevent: 阻止默认事件;
.capture: 实现捕获触发事件的机制 ;
.self: 实现只有点击当前元素时候,才会触发事件处理函数 ;
.once: 事件只触发一次;

v-on 可以监听多个方法吗?

关于 v-on 监听多个方法的简写:

 <input type="text" v-on="{ input:onInput, focus:onFocus, blur:onBlur,}" />

 v-on 在 vue2.x 中测试,以下两种均可
 <button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来 1</button>
 <button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来 2</button>

  一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号
 <button @click="a(),b()">点我 ab</button>
 <button @click="one()">点我 onetwothree</button>

 - v-on 修饰符 .stop .prevent .capture .self 以及指定按键.{keyCode|keyAlias} 
这里的.stop 和 .prevent 也可以通过传入&event 进行操作 
全部按键别名有:enter tab delete esc space up down left right 
 <form @keyup.delete="onKeyup" @submit.prevent="onSubmit">
 <input type="text" placeholder="在这里按 delete">
 <button type="submit">点我提交</button>

vue 事件中如何使用 event 对象?

获取事件对象,方法参数传递 $event 。注意在事件中要使用 $ 符号

button @click=“Event($event)”>事件对象</button

$nextTick 的使用?

this.nextTick( ) 将回调延迟到下次 DOM更新循环之后执行。在修改数据之后立即使用它然后等待 DOM 更新 。它跟全局方法 Vue.nextTick 一 样 , 不同的是回调的this自动绑定到调用它的实例上 this.nextTick() 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上 this.nextTick()将回调延迟到下次DOM更新循环之后执行。在修改数据之后立即使用它然后等待DOM更新。它跟全局方法Vue.nextTick一样,不同的是回调的this自动绑定到调用它的实例上this.nextTick() 在页面交互,尤其是从后台获取数据后重新生成 DOM 对象之后的操作有很大的优势

使用:
mounted() {
  this.$nextTick( ()=>{
   需要执行的方法
 })
}

Vue组件通信的六种方法

1.父组件向子组件传值: props/$emit
2.子组件向父组件传值(通过事件形式) $ emit/o n 3. v u e x 4. on 3.vuex 4.on3.vuex4. attrs/$ listeners
$ attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$ attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。
$ listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=“l i s t e n e r s " 传 入 内 部 组 件 5. p r o v i d e / i n j e c t 6. listeners” 传入内部组件 5.provide/inject 6.listeners"传入内部组件5.provide/inject6.parent / $children与 ref
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
$parent / $children:访问父 / 子实例

vue 的路由实现 Hash 模式和 History 模式?

hash 模式:在浏览器中符号 “#” ,#以及#后面的字符称之为 hash ,用window.location.hash 读取。特点: hash 虽然在 URL 中,但不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端安全无用, hash 不会重加载页面

history 式: history 采用 HTML5 的新特性;且提供了两个新方法: pushState() ,
replaceState() 可以对浏览器历史记录栈进行修改,以及 popState 事件的监听到状态变更

vue-router 如何响应路由参数的变化?

当使用路由参数时,例如从 /user/foo 导航到 /user/bar ,原来的组件实例会被复用。因为
两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件
的生命周期钩子不会再被调用。

 监测路由参数变化的方法
 watch 监听:
 watch: { // watch 的第一种写法
 $route (to, from) {
 console.log(to)
 console.log(from)
 }
 },
 // ====
 watch: { // watch 的第二种写法
 $route: {
 handler (to, from){
 console.log(to)
 console.log(from)
 },
 // 深度观察监听
 deep: true
 }
 }

导航守卫

beforeRouteEnter (to, from, next) {
 console.log('beforeRouteEnter 被调用:在渲染该组件的对应路由被 confirm 前调用')
 // 在渲染该组件的对应路由被 confirm 前调用
 // 不!能!获取组件实例 `this` 因为当守卫执行前,组件实例还没被创建
 // 可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实
例作为回调方法的参数。
 next(vm => {
 // 通过 `vm` 访问组件实例
 console.log(vm)
 })
 },
 // beforeRouteEnter 是支持给 next 传递回调的唯一守卫。
 // 对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回
调,因为没有必要了。
 beforeRouteUpdate (to, from, next) {
 // 在当前路由改变,但是该组件被复用时调用
 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时
候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调
用。
 // 可以访问组件实例 `this`
 console.log('beforeRouteUpdate 被调用:在当前路由改变,但是该组件被复用时调用')
 next()
 },
 beforeRouteLeave (to, from, next) {
 // 导航离开该组件的对应路由时调用
 // 可以访问组件实例 `this`
 const answer = window.confirm('是否确认离开当前页面')
 if (answer) {
 console.log('beforeRouteLeave 被调用:导航离开该组件的对应路由时调用')
 next()
 } else {
 next(false)
 }
 },
监听是否登录在router.js中使用
router.beforeEach((to,from,next)=>{
  if (to.name==='login'){
    next()
  }else {
    const token = localStorage.getItem('token')
    if (!token) {
     Message.warning('请先登录')
      router.push({
        name:'login'
      })
      return
    }
    next()
  }
})

vue-router 有哪几种导航钩子?

第一种:全局导航钩子

全局导航钩子主要有两种钩子:前置守卫、后置钩子,

注册一个全局前置守卫:

const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
    // do someting
});
这三个参数 to 、from 、next 分别的作用:
1.to: Route,代表要进入的目标,它是一个路由对象

2.from: Route,代表当前正要离开的路由,同样也是一个路由对象

3.next: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数
3.1.next():进入管道中的下一个钩子,如果全部的钩子执行完了,则导航的状态就是 confirmed(确认的)
3.2.next(false):这代表中断掉当前的导航,即 to 代表的路由对象不会进入,被中断,此时该表 URL 地址会被重置到 from 路由对应的地址
3.3.next(‘/’) 和 next({path: ‘/’}):在中断掉当前导航的同时,跳转到一个不同的地址
3.4.next(error):如果传入参数是一个 Error 实例,那么导航被终止的同时会将错误传递给 router.onError() 注册过的回调

对于全局后置钩子:

router.afterEach((to, from) => {
    // do someting
});

第二种:单独路由独享钩子
第三种:组件内的钩子

created 和 和 mounted 的区别?

created: 在模板渲染成 html 前调用,即通常初始化某些属性值,然后再渲染成视图。

mounted: 在模板渲染成 html 后调用,通常是初始化页面完成后,再对 html 的 dom 节点进行一些需要的操作。

vuex 是什么?怎么使用?哪种功能场景使用它?

只用来读取的状态集中放在 store 中; 改变状态的方式是提交 mutations ,这是个同步的事
物;异步逻辑应该封装在 action 中。
在 main.js 引入 store ,注入。新建了一个目录 store , … export
场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车

vuex 有哪几种属性?

分别是 State、 Getter、Mutation 、Action、 Module
state :Vuex 使用单一状态树,即每个应用将仅仅包含一个 store 实例,但单一状态树和模
块化并不冲突。存放的数据状态,不可以直接修改里面的数据
mutations : mutations 定义的方法动态修改 Vuex 的 store 中的状态或数据
getters :类似 vue 的计算属性,主要用来过滤一些数据
action : actions 可以理解为通过将 mutations 里面处里数据的方法变成可异步的处理数据
的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action
Module :项目特别复杂的时候,可以让每一个模块拥有自己的 state、mutation、action、
getters,使得结构非常清晰,方便管理

vuex 的核心概念和使用方法?

state :数据源,载体
 getters :用于改变 state 的值,派生出多个数据源
 mutation :唯一可以提交可以改变 state 的状态,也就是数据的属性值
 actions :提交的是 mutation,用 commit 提交 而不是直接变更状态,可以包含任意异步出
操作
 modules :拆分成多个模块
 // vuex 核心概念
 // state
 // 通过计算属性改变值
 computed:{
 count(){
 //定义语法
 return this.$store.state.count
 }
 }
 // 通过 getters 可以派生出一些新的状态
 const store =new Vuex.Store({
 state:{
 todos:[
 {id:1,text;'...',done:true}
 ]
 },
 //通过此方法对 todos 数据源进行过滤,拿到新的数据源赋值给 doneTodos
 getters:{
 doneTodos:state=>{
 return state.todos.filter(tod0=>todo.done)
 }
 },
 })
 // mutations
 // 更改 Vuex 的 store 中的状态的唯一方法,也只能通过 mutations 去改变值
 const store=new Vux.Store({
 state:{
 count:1
 },
 mutations:{
 //随便自定义一个函数,参数是默认 state
 add(state){
 //通过 state.count 拿到 count 属性值在进行自增
 state.count++
 }
 },
 actions:{
 add(context){
 //通过 commit 的方法提交一个 add,这时就会调用 mutation 中的 add 方法就会加加 1
 context.commit("add")
 }
 }
 })

vue插槽

我们在构建页面过程中一般会把用的比较多的公共的部分抽取出来作为一个单独的组件,但是在实际使用这个组件的时候却又不能完全的满足需求,我希望在这个组件中添加一点东西,这时候我们就需要用到插槽来分发内容。

父组件
<template>
  <section>
          <h2>定制内容</h2> 
          <Chca>
             <p>能否显示</p>
          </Chca>
  </section>
    
</template>
<script>
import Chca from '../iview/chaca'
export default {
     components: {
    Chca
   },
}
</script>
<style scoped>

</style>
子组件

<template>
    <div>
         我是子组件
    </div>
</template>
<script>

export default {
    name:'chaca',
    
}
</script>
<style scoped>

</style>
目前在父组件中的p标签是没有显示出来,想要父组件中的p标签也显示出来的话我们需要更改下子组件的代码
<template>
    <div>
        <div>我是子组件</div> 
        <slot></slot>
    </div>
</template>
<script>

export default {
    name:'chaca',
    
}
</script>
<style scoped>

</style>
结合上面的例子来理解就是这样的:

1.父组件在引用子组件时希望向子组价传递模板内容<p>测试一下吧内容写在这里了能否显示</p>

2.子组件让父组件传过来的模板内容在所在的位置显示

3.子组件中的<slot>就是一个槽,可以接收父组件传过来的模板内容,<slot> 元素自身将被替换

4.<Chca></Chca>组件没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃

2.具名插槽

父组件
<template>
  <section>
          <h2>定制内容</h2> 
          <Chca>
            <p>能否显示</p>
            <template v-slot:header>
              <h1>具名插槽</h1>
            </template>
          </Chca>
  </section>
    
</template>
<script>
import Chca from '../iview/chaca'
export default {
     components: {
    Chca
   },
}
</script>
<style scoped>

</style>
子组件
<template>
    <div>
        <div>我是子组件</div> 
        <slot></slot>
        <slot name="header"></slot>
    </div>
</template>
<script>

export default {
    name:'chaca',
    
}
</script>
<style scoped>

</style>

作用域插槽

子组件
<template>
    <div>
        <!-- <div>我是子组件</div> 
        <slot></slot>
        <slot name="header"></slot> -->

        <!-- 作用域 -->
        <span>
            <!-- 为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 <slot> 元素的一个 attribute 绑定上去: -->
         <slot v-bind:user="user">
             {{user.firs}}
         </slot>
        </span>
    </div>
</template>
<script>

export default {
    name:'chaca',
    data(){
        return{
            user:{
                firs:'作用域插槽'
            }
        }
    }
}
</script>
<style scoped>

</style>
父组件
<template>
  <section>
          <h2>定制内容</h2> 
          <Chca>
            <p>能否显示</p>
            <template v-slot:header>
              <h1>具名插槽</h1>
            </template>
           <!-- 作用域插槽: 绑定在 <slot> 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字 -->
              <template v-slot="slotshow">
                {{ slotshow.user.firs }}
              </template>
          </Chca>
  </section>
    
</template>
<script>
import Chca from '../iview/chaca'
export default {
     components: {
    Chca
   },
}
</script>
<style scoped>

</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值