如何让一个元素水平垂直居中
1、子元素:position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
2、子元素:position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
3、父元素:display:flex;
justify-content: center;
align-items: center;
height:100vh;
Var,let和const的区别
var 声明的变量是全局或者整个函数块的,而
let,const 声明的变量是块级的变量,var 声明的变量存在变量提升,let,const
不存在,let 声明的变量允许重新赋值,const 不允许。Const声明了必须赋值。
普通函数和箭头函数有什么区别
1、箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值,这就意
味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的
this,
2、箭头函数没有自己的 arguments 对象,但是可以访问外围函数的 arguments
对象
3、不能通过 new 关键字调用,同样也没有 new.target 值和原型
详细说说你对闭包的理解
闭包属于一种特殊的作用域,称为 静态作用域。它的定义可以理解为: 父函数
被销毁 的情况下,返回出的子函数的[[scope]]中仍然保留着父级的单变量对象
和作用域链,因此可以继续访问到父级的变量对象,这样的函数称为闭包。
闭包会产生一个很经典的问题:
- 多个子函数的[[scope]]都是同时指向父级,是完全共享的。因此当父级的变
量对象被修改时,所有子函数都受到影响。
解决:
- 变量可以通过 函数参数的形式 传入,避免使用默认的[[scope]]向上查找
- 使用 setTimeout 包裹,通过第三个参数传入
- 使用 块级作用域,让变量成为自己上下文的属性,避免共享
浏览器输入url到页面加载全过程
浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP,向服务器发起请求;
服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
浏览器对加载到的资源(HTML、JS、CSS 等)进行语法解析,建立相应的内部数据结构(如
HTML 的 DOM Tree);
载入解析到的资源文件,渲染页面,完成。
什么是回流和重绘
当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重
新构建。这就称为回流(reflow)。
每个页面至少需要一次回流,就是在页面第一次加载的时候。
在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树。
完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
什么是原型链,谈谈你的理解
原型链是由原型对象组成,每个对象都有 __proto__ 属性,指向了创建该对象
的构造函数的原型,__proto__ 将对象连接起来组成了原型链。是一个用来实现
继承和共享属性的有限的对象链。
属性查找机制: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着
原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查
找,直至最顶级的原型对象 Object.prototype,如还是没找到,则输出
undefined;
什么是事件冒泡
事件冒泡,就是元素自身的事件被触发后,如果父元素有相同的事件,如 onclick
事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事
件也会一级一级根据嵌套关系向外触发,直到 document/window,冒泡过程结束。
说说Vue的生命周期
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、
挂载 Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是 Vue 的生命周期。
通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。
每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、
运行中、销毁。
实例、组件通过 new Vue() 创建出来之后会初始化事件和生命周期,然后就会
执行 beforeCreate 钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,
无法访问到数据和真实的 dom,一般不做操作
挂载数据,绑定事件等等,然后执行 created 函数,这个时候已经可以使用到数
据,也可以更改数据,在这里更改数据不会触发 updated 函数,在这里可以在渲
染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做
初始数据的获取
接下来开始找实例或者组件对应的模板,编译模板为虚拟 dom 放入到 render 函数中准备渲染,然后执行 beforeMount 钩子函数,在这个函数中虚拟 dom 已经创
建完成,马上就要渲染,在这里也可以更改数据,不会触发 updated,在这里可
以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这
里做初始数据的获取
接下来开始 render,渲染出真实 dom,然后执行 mounted 钩子函数,此时,组件
已经出现在页面中,数据、真实 dom 都已经处理好了,事件都已经挂载好了,可
以在这里操作真实 dom 等事情...
当组件或实例的数据更改之后,会立即执行 beforeUpdate,然后 vue 的虚拟 dom
机制会重新构建虚拟 dom 与上一次的虚拟 dom 树利用 diff 算法进行对比之后重
新渲染,一般不做什么事儿
当更新完成后,执行 updated,数据已经更改完成,dom 也重新 render 完成,可
以操作更新后的虚拟 dom
当经过某种途径调用$destroy 方法后,立即执行 beforeDestroy,一般在这里做
一些善后工作,例如清除计时器、清除非指令绑定的事件等等
组件的数据绑定、监听...去掉后只剩下 dom 空壳,这个时候,执行 destroyed,
在这里做善后工作也可以
data为什么是函数
在 new Vue() 中,data
是可以作为一个对象进行操作的,然而在 component 中,data 只
能以函数的形式存在,不能直接将对象赋值给它。
当 data 选项是一个函数的时候,每个实例可以维护一份被返回对象的独立的拷贝,这样各
个实例中的 data 不会相互影响,是独立的。
Vue组件通信有哪些方法
第一种:父传子:主要通过props来实现的
具体实现:父组件通过import引入子组件,并注册,在子组件标签上添加要传递的属性,子组
件通过props接收,接收有两种形式一是通过数组形式[‘要接收的属性’ ],二是通过对象形式{ }来接收,对象形式可以设置要传递的数据类型和默认值,而数组只是简单的接收
第二种:子传父:主要通过$emit来实现
具体实现:子组件通过通过绑定事件触发函数,在其中设置this.$emit(‘要派发的自定义事
件’,要传递的值),$emit中有两个参数一是要派发的自定义事件,第二个参数是要传递的值
然后父组件中,在这个子组件身上@派发的自定义事件,绑定事件触发的methods中的方法接受的
默认值,就是传递过来的参数
第三种:兄弟之间传值有两种方法:
方法一:通过event bus实现
具体实现:创建一个空的vue并暴露出去,这个作为公共的bus,即当作两个组件的桥梁,在两个
兄弟组件中分别引入刚才创建的bus,在组件A中通过bus.$emit(’自定义事件名’,要发送的值)
发送数据,在组件B中通过bus.$on(‘自定义事件名‘,function(v) { //v即为要接收的值 })接
收数据
方法二:通过vuex实现
具体实现:vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括
state,actions,mutations,getters 和 modules 5 个 要 素 , 主 要 流 程 : 组 件 通 过 dispatch 到
actions,actions是异步操作,再actions中通过commit到mutations,mutations再通过逻辑操作改
变state,从而同步到组件,更新其数据状态
Watch和computed的区别
区别一:
watch 可以允许你没有返回值,对数据做一些处理,
但是 computed 必须要有返回值,他才能根据返回值,知道你函数依赖的是谁,当哪个数据
改变的时候,触发该方法。
区别二:
computed 可以函数依赖很多值,但是 watch 只能依赖一个值。
说说你对hash和history的理解,history模式刷新出现空白怎么解决
hash 模式
在浏览器中符号“#”,#以及#后面的字符称之为 hash,用 window.location.hash 读取;
特点:hash 虽然在 URL 中,但不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端安
全无用,hash 不会重加载页面。
history 模式
history 采用 HTML5 的新特性;如果你使用 history 的话,改变路由的时候,后台会给你响应;
且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,
以及 popState 监听浏览器历史记录变化,但是 pushState(),replaceState()不会触发该函数。
v-if和v-show的区别
相同点: 两者都是在判断 DOM 节点是否要显示。
不同点:
a.实现方式: v-if 是根据后面数据的真假值判断直接从 Dom 树上删除或重建元素节点。
v-show 只是在修改元素的 css 样式,也就是 display 的属性值,元素始终在 Dom 树上。
b.编译过程:v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事
件监听和子组件; v-show 只是简单的基于 css 切换;
c.编译条件:v-if 是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真
时才开始局部编译; v-show 是在任何条件下(首次条件是否为真)都被编译,然后被缓存,
而且 DOM 元素始终被保留;
d.性能消耗:v-if 有更高的切换消耗,不适合做频繁的切换; v-show 有更高的初始渲染消
耗,适合做频繁的额切换。
说一下路由导航守卫的用法
- 全局守卫
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
- 路由独享的守卫 你可以在路由配置上直接定义 beforeEnter 守卫
- 组件内的守卫 你可以在路由组件内直接定义以下路由导航守卫
Vue双向数据绑定的原理
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持
各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
具体步骤:
第一步:需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter
和 getter
这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化
第二步:compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,
并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通
知,更新视图
第三步:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个 update()方法
3、待属性变动 dep.notice()通知时,能调用自身的 update()方法,并触发 Compile 中绑定的
回调,则功成身退。
第四步:MVVM 作为数据绑定的入口,整合 Observer、
Compile 和 Watcher 三者,通过 Observer
来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起
Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数
据 model 变更的双向绑定效果。
说一说你对vuex的理解
vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括
state,actions,mutations,getters 和 modules 5 个 要 素 , 主 要 流 程 : 组 件 通 过 dispatch 到
actions,actions是异步操作,再actions中通过commit到mutations,mutations再通过逻辑操作改
变state,从而同步到组件,更新其数据状态,而getters相当于组件的计算属性对,组件中获取到的
数据做提前处理的.再说到辅助函数的作用.
谈谈你对axios的了解
axios 是一个基于 Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生 XHR
的封装,只不过它是 Promise 的实现版本,符合最新的 ES 规范,它本身具有以下特征:
1.从浏览器中创建 XMLHttpRequest
2.支持 Promise API
3.客户端支持防止 CSRF
4.提供了一些并发请求的接口(重要,方便了很多的操作)
5.从 node.js 创建 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换 JSON 数据
说说你对spa单页面应用的理解
SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
基于上面一点,SPA 相对对服务器压力小;
前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
缺点:
初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。
代码实现千分化整数数字(例如:123(123);1234(1,234);123456789(123,456,789))
<div id=”app”>
<input type=”number” v-module=”num”/>
<p>{{num|NumFormat}}</p>
</div>
var.filter('NumFormat',function{
var inPart=Number(Value)-Nnumber(Value)%1
var inPartFormat=inPart.string.replace(/(\d)(?=(?:\d{3})+$)\g,'$1,')
return inPartFormat
})
var app=new Vue({
el:"#app",
Data:{
Num:""
}
})