Vue部分:
1.watch和computed什么情况或者什么场景下用?
共同点是:都是希望在依赖数据发生改变的时候,被依赖的数据根据预先定义好的函数,发生“自动”的变化。
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
应用:
当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
computed 计算后返回新一个数据受多个数据影响(比如:计算总价格、过滤某些数据、购物车商品结算的时候)
computed是用来处理你使用watch和methods的时候无法处理(比如有缓存的时候监听不了数据变化),或者是处理起来并不太恰当的情况的,利用computed处理methods存在的重复计算情况。
watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;
watch 监听某个数据的变化(监听完调用什么函数) 一个数据影响多个数据
(比如:浏览器自适应、监控路由对象、监控自身属性变化、搜索数据)
(可参考文章的例子:https://www.cnblogs.com/lxmyhappy/p/11597134.html)
2.实现双向绑定的原理?(vue源码分析)
当data 有变化的时候它通过Object.defineProperty()方法中的set方法进行监控,并调用在此之前已经定义好data 和view的关系了的回调函数,来通知view进行数据的改变,而view 发生改变则是通过底层的input 事件来进行data的响应更改。
给data中的所有属性提供set方法, set方法监视get中属性的变化,一旦它变了页面就更新了
vue是通过数据劫持的方式来做数据绑定的,
其中最核心的方法便是通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的。
数据绑定:更data中的数据,更新界面
数据劫持:
初始化显示:页面(表达式/指令)能从data中读取数据显示(编译/解析)
更新显示:更新data中的属性数据==>页面更新
MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
整理了一下,要实现mvvm的双向绑定,就必须要实现以下几点:
①实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
②实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
③实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
④mvvm入口函数,整合以上三者
(参考文章:https://github.com/DMQ/mvvm)
https://segmentfault.com/a/1190000006599500
3.对于MVVM的理解?
MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
4.Vue如何实现动态路由?路由的原理?
路由原理:vue-router通过hash与history 两种方式实现前端路由,更新视图但不重新请求页面是前端路由原理的核心之一。
总结路由的生命周期:
- 会触发离开的钩子 beforeRouteLeave
- 如果进入到新的页面 beforeEach
- beforeEnter 进到路由的配置中
- beforeRouteEnter 组件进入时的钩子
- 解析完成 beforeResolve
- afterEach 当前进入完毕
- 当属性变化时 并没有重新加载组件 会触发beforeRouteUpdate方法
- 组件渲染完成后 会调用当前beforeRouteEnter回调方法
(动态路由参考文章
https://segmentfault.com/a/1190000015419713?utm_source=tag-newest)
5.组件之间如何通信?
父—>子props方法接收父组件传来的值;
子—>父 $emit触发父组件中子组件自定义的事件;
(*自定一个事件名tanslate和一个参数this.msg *)
兄弟组件:bus 创建vue实例作为桥梁,使用该实例的on以及emit实现数据传递信息;/vuex
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。
5.$nextTick( )的作用?
当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,
你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后再获取,才能成功。(异步更新队列)
6.vuex是什么?怎么使用?哪种功能场景使用它?
只用来读取的状态集中放在store中;
改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
在main.js引入store,注入。新建了一个目录store,….. export 。
场景有:单页应用中,组件之间的状态、登录状态、加入购物车
state
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。一般用来来存储应用中需要共享的状态;
mutations只能是同步地更改状态;commit
action异步地更改状态,action并不直接改变state,而是通过mutation来改变的。dispath
getters类似vue的计算属性,主要用来过滤一些数据。
modules项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
7.vue生命周期?beforeMount和mounted的用法?
Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前)在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。[挂载到DOM树之前]
mounted(载入后)在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。[挂载到DOM树之后]
第一次页面加载会触发:beforeCreate, created, beforeMount, mounted
--------------------------------------------------------------------------------------------
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
8.单页面和多页面的应用?
多页面应用
单页面应用
包含多个独立完成的HTML页面(缺点:请求次数多)
整个项目只有一个完整的HTML页面,其他的页面只不过是HTML片段(优:请求少,JS渲染)
页面跳转本质:
删除整个DOM树,重新加载另一个整个DOM树
页面跳转本质:
把当前DOM树中局部片段替换为另一个HTML片段
如果两个页面都需要一个相同的资源,每个页面都要重复请求
如果多个“片段页面”都要用到相同的资源,只需要下载一次即可
缺点:切换慢
缺点:首屏时间慢,SEO差
9.Vue修饰符有哪些?
①v-model的修饰符:
.lazy- 取代 input 监听 change 事件 光标离开input框才会更新数据
.number - 输入字符串转为有效的数字
.trim - 输入首尾空格过滤
②v-on(@)的修饰符:
.stop - 调用 event.stopPropagation()。阻止事件冒泡
.prevent - 调用 event.preventDefault()。阻止默认行为
比如:表单的提交、a标签的跳转就是默认事件
.capture - 事件的完整机制是捕获-目标-冒泡,事件触发是目标往外冒泡。
.self - 只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个div里面有个按钮,div和按钮都有事件,我们点击按钮,div绑定的方法也会触发,如果div的click加上self,只有点击到div的时候才会触发,变相的算是阻止冒泡。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。(.keyup、.enter等)
.native - 监听组件根元素的原生事件。
.once - 只能用一次,无论点击几次,执行一次之后都不会再执行。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
③v-bind(:)的修饰符:
.prop- 默认绑定到 DOM 节点的 attribute 上,
使用 .prop 修饰符后,会绑定到 property
注意事项:
使用 property 获取最新的值;
attribute 设置的自定义属性会在渲染后的 HTML 标签里显示,property 不会。
修饰符用途:
通过自定义属性存储变量,避免暴露数据
防止污染 HTML 结构
.sync (2.3.0+) 语法糖,子组件当中修改父组件的某个数据时可以用到。
:isShow.sync="isShow"其实是 @update:isShow="bol=>isShow=bol"语法糖。是其一种简写形式。(参考文章https://www.jianshu.com/p/d42c508ea9de)
10.v-cloak的应用?
防止闪现,和 CSS 规则如 [v-cloak] { display: none } 一起用时
//css中[v-cloak]{ display: none;} 样式的属性选择器 去找有这样的一个属性名的选中器
//html中<div v-cloak>{{message }}</div>
//不会显示`{{message}}`没渲染的瞬间,直到编译结束渲染出结果才会显示。
显示{{message}} 模板在解析之前有模板属性,解析之后没有了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。