目录
vue:
vue 是一个构建数据驱动的渐进性框架(主张最少,无多做职责之外的事)
目标是通过API实现响应数据绑定和视图更新
MVVM:
(前端有属于自己的控制器)
视图模型双向绑定,是Model-View-ViewModel的缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到ViewModel层并自动将数据渲染到页面中, 试图变化时会通知ViewModel层更新数据。
MVVM的优点:
- 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变
- 可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
- 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xml代码
- 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写
Vue双向绑定原理
vue.js是通过数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属
性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调
- 实现一个Observer(数据监听器) : Observer的核心是通过Object.defineProprtty()来监听数据的变动,这个函数内部可以定义setter和getter,每当数据发生变化,就会触发setter。这时候Observer就要通知订阅者
- 实现一个Watcher(订阅者) :每个Watcher都绑定一个更新函数,Watcher可以收到属性的变化通知并执行相应的函数,从而更新视图
Watcher订阅者作为Observer和Compile之间通信的桥梁,主要做的事情是:
- 在自身实例化时往属性订阅器(dep)里面添加自己
- 自身必须有一个update()方法
- 待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调
- 实现一个Compile(指令解析器) : 可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器
Vue中的computed和watch的区别
Computed:计算属性
- 支持缓存,属性的结果会被缓存只有依赖数据发生改变,不会重新计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- 当一个属性由其他属性计算而来,这个属性依赖其他属性。一般使用computed(例如:购物车结算)
Watch:监听属性的变化
- 不支持缓存。键是需要观察的属性,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,监听属性的变化。数据变,直接会触发相应的操作
- 支持异步
- 当一个属性变化,会影响其他属性时,也就是其他属性依赖这个属性,一般用watch(例如:搜索数据)
组件中的data为什么是一个函数?
- 一个组件可能会被多次调用,而调用一次就会执行相应的data函数并返回新的数据对象,也就是创建多个实例。本质上,这些实例用的都是同一个构造函数。
- 如果data是对象的话,对象属于引用类型,会影响到所有的实例。
为了保证组件不同的实例之间data不冲突,防止造成数据污染,data必须是一个函数。
V-for 和v-if
- 当 v-for 和 v-if 处于同一个节点时,v-for的优先级 > v-if,意味着 v-if 将分别重复运行于每个 v-for 循环中。如果要遍历的数组很大,而真正要展示的数据很少时,这将造成很大的性能浪费(Vue2.x)
- 这种场景建议使用 computed,先对数据进行过滤
注意:3.x 版本中
v-if
总是优先于v-for
生效。由于语法上存在歧义,建议避免在同一元素上同时使用两者。比起在模板层面管理相关逻辑,更好的办法是通过创建计算属性筛选出列表,并以此创建可见元素。
v-show和v-if
推荐使用:v-if(偶尔) v-show (频繁)
共同点:
- 作用效果相同
- 都是控制元素在页面是否显示,
- 用法也相同
不同点:
- 控制手段不同
- 编译过程不同
- 编译条件不同
- 性能消耗不同【v-show初始渲染(高);v-if 切换】
- 初始渲染
- 切换
v-if:通过Dom来控制显隐
v-show:通过改变css样式display来控制显隐
Vue组件的通信方式
· props/$emit 父子组件通信
父->子props,子->父 $on、$emit 获取父子组件实例 parent、children Ref 获取实例的方式调用组件的属性或者方法 父->子孙 Provide、inject 官方不推荐使用,但是写组件库时很常用
· $emit/$on 自定义事件 兄弟组件通信
Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue() 自定义事件
· Vuex 跨级组件通信
Vuex、$attrs、$listeners Provide、inject
什么是slots,有什么作用?
在HTML中 slot
元素 ,作为 Web Components
技术套件的一部分,是Web组件内的一个占位符
该占位符可以在后期使用自己的标记语言填充
在子组件中使用是为了将父组件中的子组件模板数据正常显示。
插槽的分类有三种:默认插槽、具名插槽(插槽的名字)、作用域插槽。
可以在父组件中使用 slot-scope 从子组件获取数据
vue-router的实现原理:
通过解析url来实现不同页面之间的跳转。
vue-router中有hash和history两种模式。
hash:通过#后面的内容更改触发hashchange事件(不刷新页面)
history:通过pushState和replaceState切换url,触发popState事件(history 模式下刷新,会
web 性能优化
- 降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩, webP,lazyLoad。
- 加快请求速度:预解析 DNS,减少域名数,并行加载,CDN 分发。
- 缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage。
- 渲染:JS/CSS 优化,加载顺序,服务端渲染,pipeline。