1、说一下Vue的优点
体积小,更高的运行效率,双向数据绑定,生态丰富、学习成本低
2、v-show和v-if的共同点和不同点?
共同点:都能控制元素的显示和隐藏;
不同点:
实现本质方法不同,v-show本质就是通过控制css中的display设置为none,控制隐藏,只会编译一次;
v-if是动态的向DOM树内添加或者删除DOM元素,若初始值为false,就不会编译了。而且v-if不停的销毁和创建比较消耗性能。
总结:如果要频繁切换某节点,使用v-show(切换开销比较小,初始开销较大)。如果不需要频繁切换某节点使用v-if(初始渲染开销较小,切换开销比较大)。
3、vue.js双向数据绑定原理?
Vue.js 2.0 采用数据劫持(Proxy 模式)结合发布者-订阅者模式(PubSub 模式)的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。
Vue.js 3.0, 放弃了Object.defineProperty ,使用更快的ES6原生 Proxy (访问对象拦截器, 也称代理器)
实现步骤:
[if !supportLists]1)[endif]需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
2)compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
3)Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是: ①在自身实例化时往属性订阅器(dep)里面添加自己 ②自身必须有一个update()方法 ③待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
4)MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 --> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
4、你对Vue项目进行了哪些优化
不在模板里面写过多表达式
循环调用子组件时添加key
频繁切换的使用v-show,不频繁切换的使用v-if
尽量少用float,可以用flex
按需加载,可以用require或者import()按需加载需要的组件
5、vue.js的响应式
当VUE实例数据发生改变时,页面也会发生响应。
当创建Vue实例时,vue 会遍历data 选项的属性,利用 Object.defineProperty 为属性添加 getter 和 setter 对数据的读取进行劫持(getter 用来依赖收集,setter 用来派发更新),并且在内部追踪依赖,在属性被访问和修改时通知变化。
依赖的模式:
vue.js采用数据劫持结合发布-订阅模式,通过 Object.defineproperty 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发响应的监听回调。
6、data为什么是函数?
如果组件里data 直接写了一个对象的话,那么在模板中多次声明这个组件,组件中的 data 会指向同一个引用。
此时对data 进行修改,会导致其他组件里的 data 也被修改。使用函数每次都重新声明一个对象,这样每个组件的data都有自己的引用,就不会出现相互污染的情况了。
7、介绍一下keep-alive
keep-alive是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染。
1)一般结合路由和动态组件一起使用,用于缓存组件;
2)提供include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;
3)对应两个钩子函数activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。8、介绍虚拟DOM
(1)虚拟dom是为了解决浏览器性能问题而被设计出来的,当操作数据时,将改变的dom元素缓存起来,都计算完后再通过比较映射到真实的dom树上。
(2)让我们不用直接操作DOM元素,只操作数据便可以重新渲染页面
9、diff算法
diff的过程就是调用名为patch的函数,比较新旧节点,一边比较一边给真实的DOM打补丁。
diff算法的本质是找出两个对象之间的差异,目的是尽可能复用节点。此处说到的对象其实就对应 vue中的 virtual dom,即使用 js对象来表示页面中的 dom 结构。
diff算法比较新旧虚拟dom
如果节点类型相同,则比较数据,修改数据
如果节点不同,直接干掉节点及所有子节点,插入新的节点
如果给每个节点都设置了唯一的key,就可以准确的找到需要改变的内容,否则就会出现修改一个地方导致其他地方都改变的情况。比如A-B-C-D, 我要插入新节点A-B-M-C-D,实际上改变的了C和D。但是设置了key,就可以准确的找到B C并插入。
10、如何编译template 模板?
compile编译会有三个过程
(1)parse 根据正则进行字符串解析,得到指令、class、style等数据,形成语法树(AST)
(2)对 parse 生成的 AST 进行静态内容的优化,标记静态节点(和数据没有关系不需要每次都刷新的内容),标记静态根节点。
(3)generate 生成 render
生成render 的 generate 函数的输入也是 AST,它递归了 AST 树,为不同的 AST 节点创建了不同的内部调用方法,等待后面的调用。
11、计算属性compoter和watch的区别
computed用于处理复杂的逻辑运算,主要和methods储存方法来进行区分;methods储存方法,computed储存需要处理的数据值;methods每次都会调用,computed有缓存机制,只有改变时才执行,性能更佳;
watch顾名思义,用于监听数据变化,其中可以监听的数据来源有三部分:props、data、computed内的数据;watch提供两个参数(newValue,oldValue),第一个参数是新值,第二个参数保存旧值;
区别:
计算属性computed :
支持缓存,只有依赖数据发生改变,才会重新进行计算
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过的数据通过计算得到的
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
不支持缓存,数据变,直接会触发相应的操作;
watch支持异步;
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
当一个属性发生变化时,需要执行对应的操作;一对多;
12、组件传值
1、父传子:父组件中通过v-bind绑定一个属性,子组件中通过props接收父组件中的绑定的属性
2、子传父:子组件通过广播的方式$emit将值传递给父组件,父组件中通过一个函数去接收子组件中传递过来的值
3、兄弟间传值:可以通过中间媒介父组件进行传递值得中转
4、使用vuex状态管理,可以实现数据的随意存储和获取
5、provide、inject 父组件通过provide注入一个依赖,其所有的子孙组件可以通过inject来接收
13、生命周期函数
vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。
钩子函数 描述
beforeCreate 在实例初始化之后,数据观测(data observer)和 event/watch事件配置之前被调用
created 在实例创建完成后立即被调用,在这一步实例已经完成了:数据观测、属性和方法的运算和 event/watch事件的回调,但是$el属性目前不可见,还无法操作dom。
beforeMount 在挂载开始之前被调用
mounted 在挂载成功后被调用,el被新创建的vm.$el替换,已经可以操作dom
beforeUpdate 数据更新之前调用
update 数据更新完成时调用,组件dom已经更新
activated 组件被激活时调用
deactivated 组件被移除时调用
beforeDestory 组件销毁前调用
destoryed 组件销毁后调用
14、vue中的key的作用是什么?
当Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用让每个item有一个唯一的识别身份,可以下标值index或者id, 主要是为了vue精准的追踪到每一个元素,高效的更新虚拟DOM。
15、什么是MVVM?
MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
16、mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
区别:vue数据驱动,通过数据来显示视图层而不是节点操作。场景:数据操作比较多的场景,更加便捷
17、为什么避免v-if 和 v-for 用在一起
当Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。
18、Vue的路由实现:hash模式 和 history模式
hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 ,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回404 错误。
history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 /items/id。 后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”
19、$route和$router的区别
$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。
20、vue常用的修饰符?
1.事件修饰符
.prevent: 阻止默认事件(在指定的事件后进行默认事件的阻止);
.stop: 阻止单击事件冒泡(在指定事件后阻止事件冒泡,阻止指定在最内层事件的标签里);
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用
.once:控制元素指定的事件只执行一次
2. 表单元素修饰符
.number:能够强制的指定表单元素的内容数据类型是number
.trim:能够去除输入内容左右两边的空格
.lazy:只有标签的change事件执行后才会执行数据的双向绑定
[if !supportLists]21、[endif]Vue.js SPA单页面应用的理解及其优缺点?
SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
1)用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
2)基于上面一点,SPA 相对对服务器压力小;
3)前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
缺点:
1)初次加载耗时多:为实现单页Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
2)前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
3)SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。22、Vuex原理
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
(1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
(2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。
主要包括以下几个模块:
1)State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
2)Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
3)Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
4)Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
5)Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
commit 和dispatch的区别在于commit是提交mutatious的同步操作,dispatch是分发actions的异步操作
1)dispatch:含有异步操作,例如向后台提交数据,写法this.$store.dispatch(‘action方法名’,值)
2)commit:同步操作,写法:this.$store.commit(‘mutations方法名’,值)23、使用过Vue SSR 吗?说说 SSR?
SSR大致的意思就是vue在客户端将标签渲染成整个html片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。
24、Vue 框架怎么实现对象和数组的监听?
Vue 框架是通过遍历数组 和递归遍历对象,从而达到利用Object.defineProperty() 也能对对象和数组(部分方法的操作)进行监听。
25、Proxy 与 Object.defineProperty 优劣对比
Proxy的优势如下:
Proxy可以直接监听对象而非属性;
Proxy可以直接监听数组的变化;
Proxy有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
Proxy作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
Object.defineProperty的优势如下:
兼容性好,支持IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。
26、let、var、const之间的区别
1)var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
2)let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
3)const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
(1)代码层面的优化
v-if 和 v-show 区分使用场景computed 和 watch 区分使用场景v-for 遍历必须为 item 添加 key,且避免同时使用 v-if长列表性能优化事件的销毁图片资源懒加载路由懒加载第三方插件的按需引入优化无限列表性能服务端渲染 SSR or 预渲染(2)Webpack 层面的优化
Webpack 对图片进行压缩减少 ES6 转为 ES5 的冗余代码提取公共代码模板预编译提取组件的 CSS优化 SourceMap构建结果输出分析Vue 项目的编译优化(3)基础的 Web 技术的优化
开启 gzip 压缩浏览器缓存CDN 的使用使用 Chrome Performance 查找性能瓶颈4人点赞
日记本
作者:疯的很理智链接:作者:it优课链接: