1.VUE vuex的五大属性和工作原理
state, getters, mutations, actions, modules。
- state:vuex的基本数据,用来存储变量
在vue中使用 this.$store.state.userId
- geeter:从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法
在vue中使用 this.$store.getters.userIdDouble
- mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
commit 同步操作,写法: this.$store.commit(‘mutations方法名’,值)
- action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
dispatch:异步操作,写法: this.$store.dispatch(‘mutations方法名’,值)
- modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
简单来说就是可以把以上的 state、mutation、action、getters 整合成一个user.js,然后放到store.js里面
2.vue生命周期之间的差别
生命周期:每一个vue实例从创建到销毁的过程就是vue这个实例的生命周期
生命周期过程:开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程
- beforeCreate(创建前)在实例初始化之后执行此时对象还未创建,el 和data并未初始化,因此无法访问 methods,data ,computed等方法和数据。
使用场景:可以在此时加一些 loading 效果,在 created 时进行移除。
- create(创建后) 最早开始使用data和methods中的数据的钩子函数,这个阶段可以数据请求,但是不能dom操作。
使用场景:需要异步请求数据的方法可以在此时执行,完成数据的初始化。
- beforeMounted(挂在前)挂载开始之前被调用,把data里面的数据和模板生成html,完成了el和data初始化,注意此时还没有挂载到html页面上。
mounted(挂载后)挂载完成,HTML已经被渲染到了页面上,这个阶段可以执行dom操作,可以进行数据请求。
使用场景: 当需要操作 dom 的时候执行,可以配合$.nextTick 使用进行单一事件对数据的更新后更新dom。
- beforeUpdate(更新前)数据更新前调用,当data的数据发生改变会执行这个钩子 内存中数据是新的 页面是旧的。
- update(更新后) 由于数据更改导致的虚拟 DOM 重新渲染,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。注意 updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick。
使用场景: 当数据更新需要做统一业务处理的时候使用。
- beforeDestory(销毁前)实例销毁之前调用,在这一步还可以做一些释放内存的操作
destory(销毁后)实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有.的事件监听器被移除,所有的子实例也都被销毁。 - errorCaptured 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
- activated keep-alive 缓存的组件激活时调用。
- deactivated keep-alive 缓存的组件停用时调用。
- $ nextTick
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。(Vue 在更新 DOM 时是异步执行的)
vue响应式的改变一个值以后,此时的dom并不会立即更新,如果需要在数据改变以后立即通过dom做一些操作,可以使用$nextTick获得更新后的dom。(根据异步请求获取后的数据从而渲染DOM结构,可以结合wacth监听属性配合)
$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM。
补充
VUE数据请求放在created还是mounted?
如果在mounted钩子函数中请求数据可能导致页面闪屏问题
其实就是加载时机问题,放在created里会比mounted触发早一点,如果在页面挂载完之前请求完成的话就不会看到闪屏了
3.HTMLmeta标签的作用
meta标签用来描述一个HTML网页文档的属性
有四种属性:1.charset、2.name、3.content、4.http-equiv
- charset: 页面中的必须标签,说明页面是UTF-8格式,防止乱码。
unicode UTF-8详情http://t.csdn.cn/P8WaN - name: name属性主要用于描述网页,content中为属性对应的属性值,content中的属性值主要是便于搜索引擎机器人查找信息和分类信息用的。
name的参数有:
keywords(关键字)为搜索引擎提供网站的关键字
description(网站内容描述)为搜索引擎提供网站主要内容。
application-name(应用程序名称)
viewport(用于移动端页面控制)指定页面控制及缩放比例。
content内容如下:
width:设置layout viewport 的宽度,为一个正整数,或字符串"width-device"
initial-scale:设置页面的初始缩放值,为一个数字,可以带小数,通常为1.0(1.0为正常大小)
minimum-scale:允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale:允许用户的最大缩放值,为一个数字,可以带小数
- http-equiv:指示服务器在发送实际的文档之前先在要传送给浏览器的 MIME 文档头部包含名称/值对。
http-equiv的参数有:refresh重定向,在规定的时间之后跳转到另一页面
<meta http-equiv="refresh" content="5;url=http://www.w3school.com.cn" />
4.Doctype有什么作用
DOCTYPE是document type (文档类型) 的缩写。声明位于文档的最前面,处于标签之前,它不是html标签。主要作用是告诉浏览器的解析器使用哪种HTML规范或者XHTML规范来解析页面。
5.本地存储
把数据存到用户的浏览器里面
设置方便,易于读取,甚至刷新页面也不会丢失数据
只能储存字符串,可以将对象JSON.stringify()编码后存储
6.用户注册登录实现大概步骤
登录页面、用户点击登录过程,从前端拿数据和后台拿数据以及从数据库拿数据
用户点击页面登录—前端页面vue组件获取表单的值—判断是登录还是注册,处理请求—后端—返回成功或失败数据
- 注册–通过数据库存储用户信息(名字,密码)接口post
- 登录–登录成功的时候,后台为了区分用户是谁,下发令牌token,用户前台持久化localStorage.setItem存储token。(组件派发action:userLogin通过Vuex的异步操作action,执行dispatch操作—执行异步操作,发送post请求(此处因为是前后端分离项目,通过webpack的proxy解决跨域问题)—请求发送到后端后,),路由在进行跳转。
- 登录过后用户信息页展示,在首页中的mounted中派发action
- 退出登录,清除token,action不能直接操作state,commit提交给mutation修改state
注意:
vuex仓库存储数据—不是持久化
配置路由守卫:router.beforeEach((to,from,next)=》{}) //进行条件判断然后跳转路由
7.CSS盒子居中显示
1.定位 子绝父相
- 1.1 margin设置为auto
.child {
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
margin: auto; }
- 1.2 transform使子盒子往“回”移动自己宽高的一半
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
2.flex布局
将父盒子设置成弹性盒容器
让子元素水平居中,垂直居中
.parent {
display: flex;
justify-content: center;
align-items: center;
}
3.inline-block行内块元素
text-align: center; 只对行内元素和行内块元素有用
.parent {
text-align: center;
line-height: 500px;
}
.child {
display: inline-block;
vertical-align: middle; vertical-align 属性设置一个元素的垂直对齐方式。middle把此元素放置在父元素的中部。
}
CSS盒子右边固定,左边自适应
1.固定盒子浮动+ 自适应盒子width: 100%;//宽度等于百分之百
.left {
float: left;
width: 200px;
height: 400px;
background: red;
}
.right {
width: 100%;//宽度等于百分之百
height: 400px;
margin-left: 200px;
background: blue;
}
2.flex布局父容器设置 display:flex;Right部分设置 flex:1
.box{ display: flex;}
.left{width:200px;background: red;}
.right{width:%;flex:1;background: blue;}/等于左边栏宽度/
3.左右两边都绝对定位
.left{width:200px;background: red; position: absolute;left:;}
.right{width:100%;background: blue;position: absolute;left:200px;}/等于左边栏宽度/
8.Flex布局
Flex布局后,子元素的float、clear和vertical-align属性将失效
(父)容器的一些属性:
-
flex-direction 属性设置容器主轴的方向
-
flex-wrap 置当项目在容器中一行无法显示的时候如何处理
-
flex-flow 属性是flex-deriction和flex-wrap属性的简写,默认值为[row nowrap]
-
justify-content 设置项目在容器中的对齐方式
-
align-items 项目在交叉轴上是如何对齐显示的
(子)项目上的属性: -
order 设置项目排序的位置,默认值为0,数值越小越靠前
-
flex flex-grow属性、flex-shrink属性、flex-basis属性的简写。默认值为:0 1 auto;
-
align-self 当前项目可以和其他项目拥有不一样的对齐方式
9.MVVM模式
MVVM分为Model、View、ViewModel三者。
- Model:代表数据模型,数据和业务逻辑都在Model层中定义;
- View:代表UI视图,负责数据的展示;
- ViewModel:负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作;
- Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步。
这种模式实现了Model和View的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作dom。
补充
MVC:原生JS方法
10.节流和防抖
节流:一定的间隔时间内只执行一次,如果这个单位时间内触发多次函数,只有一次生效。 滚动事件,鼠标点击事件
防抖:事件被触发n秒后再执行回调,n秒内又被触发则重新计时
11.懒加载
懒加载也叫延迟加载
- 图像懒加载:指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。
首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在 data-original 属性中,当页面滚动的时候需要去监听 scroll 事件,在 scroll 事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内则将图片的 src 属性设置为 data-original 的值,这样就可以实现延迟加载。
- 路由懒加载:整个网页默认是刚打开就去加载所有页面,路由懒加载就是只加载你当前点击的那个模块。按需去加载路由对应的资源
将路由相关的组件,不再直接导入了,而是改写成异步组件的写法,只有当函数被调用的时候,才去加载对应的组件内容。
routes: [
{ path: '/login', component: () => import('@/views/login/index.vue') },
{ path: '/home', component: () => import('@/views/home/home.vue') }
]
12.预编译、作用域、变量提升、事件委派
预编译
-
Js引擎会在正式执行之前先进行一次预编译,在这个过程中,首先将变量声明及函数声明提升至当前作用域的顶端,然后进行接下来的处理
作用域 -
变量作用域:变量起作用的范围。函数以外的变量都称之为全局变量,以内的称为局部变量,局部变量和全局变量同名时,局部变量优先。
-
函数作用域:也称为局部作用域,函数声明时就形成,在函数内声明的所有变量在函数体内始终有定义。函数内部的变量不会被函数外部访问,函数内部可以访问全局的变量。
变量提升
- 变量提升:只会提升变量的声明,不会提升变量的赋值初始化
- 函数提升:一般使用函数声明和函数表达式(var a = function (){})声明函数,将函数声明整个都提升到当前作用域的顶部。函数提升优先于变量提升
事件委派
- 事件的委派也叫事件代理,简单理解就是:原本是某个元素需要绑定的事件,现在将这个事件交给别的元素去做,正常我们把它交给父级元素,比如:原本是给li绑定点击事件,现在交给它父级ul绑定,利用冒泡原理,点击li的时候会触发ul的事件;
- 好处:提升性能, 比如要给100个li安装点击事件,正常我们会用for循环去个每个li安装,这样与访问dom的次数多,性能也比较低;利用冒泡原理,给ul安装点击事件(就是委派ul代理这个事件),点击li的事件由ul去执行,这样就只访问一次dom,性能就提升了;
13.JS执行机制
js最大特点是单线程的,单线程意味着所有任务需要排队
- JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事
- JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。如果多个线程一起操作同一个DOM就会引发很多问题。
- 多核CPU的计算能力,HTML5提出Web Worker标准,允许javascript脚本创建多个线程,于是js出现了同步和异步。
- JS解决单线程的弊端:同步任务和异步任务,异步任务放在任务队列中,同步任务是主线程上执行的任务。只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入”任务队列”(task queue)的任务,只有”任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
同步异步任务执行机制
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。 事件循环:主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
15.定时器的秒数为0是不是立即执行函数
回答:不是
setTimeout(fn, 0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,当前代码执行完(执行栈清空)以后,尽可能的早执行。它在“任务队列”的尾部添加一个事件,因此要等到同步任务和“任务队列”现有的事件都处理完,才会得到执行。
HTML5标准setTimeout()的第二个参数的最小值不得小于4毫秒,如果低于这个值,则默认是4毫秒。在此之前。老版本的浏览器都将最短时间设为10毫秒。另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常是间隔16毫秒执行。
16.Es6的常用的新特性
- 箭头函数
- 解构赋值
- 剩余参数
- let,const
- symbol,bigInt
- class类继承
补充面试题:
- 箭头函数与普通函数区别
- 箭头函数没有this,所以需要通过查找作用域链来确定this的值
- 箭头函数没有自己的arguments对象,但是可以访问外围函数的arguments对象
- 不能通过 new 关键字调用,同样也没有 new.target值和原型
- let,const解决什么问题
解决:变量污染问题 引入块级声明:声明在指定块的作用域之外无法访问的变量
- Var:定义一个变量,可以重复赋值,重复定义;有变量提升,变量可以在声明之前使用,值为undefined;在浏览器环境下声明变量会挂载到window上。
- Let:定义一个变量,可以重复赋值,不可以重复定义;块级作用域,也称词法作用域,没有变量提升,存在暂时性死区;全局作用域下创建一个新的绑定,该绑定不会添加为全局对象的属性。
- Const:定义一个常量,声明时必须赋值,也就是必须初始化,不可以重复赋值,不可以重复定义,常量如果是对象,对象中的值可以修改;块级作用域,也称词法作用域,没有变量提升,存在暂时性死区
- 暂时性死区( temporal dead zone,简称TDZ
ES6新增的let、const关键字声明的变量会产生块级作用域,如果变量在当前作用域中被创建之前被创建出来,由于此时还未完成语法绑定,如果我们访问或使用该变量,就会产生暂时性死区的问题,由此我们可以得知,从变量的创建到语法绑定之间这一段空间,我们就可以理解为‘暂时性死区’
其他方面也会出现暂时性死区域吗?
let/const关键字未出现之前,typeof运算符是百分之百安全的,现在也会引发暂时性死区的发生,像import关键字引入公共模块、使用new
class创建类的方式,也会引发暂时性死区,究其原因还是变量的声明先与使用
18.跨域的方法
- CORS:
- JSONP:
可跨域标签
<img src=""> //图片
<link href=""> //css
<script src=""> //程序
配置代理服务器:
19.v-if v-show
V-show不会对DOM进行操作,而是操作display值
V-if对DOM进行操作,对其进行增加和删除
V-if相对消耗浏览器的性能,若频繁的切换,使用v-show较好
20.nodejs的express
- 定义:最小且灵活的web应用程序框架,为web和移动应用程序提供了一组强大的功能,它的行为就像是一个中间件,可以帮助管理服务器和路由。
- 优点:简单、灵活、简约和可扩展;提供快速生成工具express-generator,快速开发web应用。
其他框架
- Koa:是一个新的web框架,由Express幕后的原班人马打造,致力于成为web应用和API开发领域中的一个更小、更富有表现力、更健壮的基石。用async函数代替回调函数。优点:集成大量webAPI,没有绑定中间件;非常轻量;try/catch更好处理错误;代码可读性和维护性相对较高。
- Hapi:基础功能相对丰富的框架,开发人员专注于业务而不是项目构建。优点:提供了缓存、身份验证和输入验证;提供众多企业插件。