Vue
双向绑定原理
vue2.:vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,
ue 3.0与Vue 2.0的区别仅是数据劫持的方式由Object.defineProperty更改为Proxy代理,其他代码不变。
资源请求一般在哪个生命周期
推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求能更快获取到服务端数据,减少页面loading 时间;
还有哪些生命周期可以请求资源
可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。
Vuex中的几种状态
vuex的流程
页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation。mutation会修改state中对于的值。
最后通过getter把对应值跑出去,在页面的计算属性中,通过mapGetter来动态获取state中的值
vuex有哪几种状态和属性
有五种,分别是State , Getter , Mutation , Action , Module (就是mapAction)
vuex的State特性是?
stae就是存放数据的地方,类似一个仓库 , 特性就是当mutation修改了state的数据的时候,他会动态的去修改所有的调用这个变量的所有组件里面的值( 若是store中的数据发生改变,依赖这个数据的组件也会发生更新 )
vuex的Getter特性是?
getter用来获取数据,mapgetter经常在计算属性中被使用
vuex的Mutation特性是?
Action 类似于 mutation,不同在于:
-
Action 提交的是 mutation,而不是直接变更状态。
-
Action 可以包含任意异步操作
vuex的优势
1 状态管理工具 核心是响应式的做到数据管理, 一个页面发生数据变化。动态的改变对应的页面
MVVM 模式的优缺点,与 MVC 的区别
(1).什么是MVVM
MVVM最早由微软提出来,它借鉴了桌面应用程序的MVC思想,在前端页面中,把Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离,把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回ModelView 和 Model 之间的同步工作完全是自动的,无需人为干涉(由viewModel完成)因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
(2).MVVM模式的优点:
1、低耦合:MVVM模式中,数据是独立于UI的,ViewModel只负责处理和提供数据,UI想怎么处理数据都由UI自己决定,ViewModel不涉及任何和UI相关的事,即使控件改变(input换成p),ViewModel几乎不需要更改任何代码,专注自己的数据处理就可以了2.自动同步数据:ViewModel通过双向数据绑定把View层和Model层连接了起来,View和Model这两者可以自动同步。程序员不需要手动操作DOM, 不需要关注数据状态的同步问题,MVVM 统一管理了复杂的数据状态维护3、可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。4、独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。5、可测试:ViewModel里面是数据和业务逻辑,View中关注的是UI,这样的做测试是很方便的,完全没有彼此的依赖,不管是UI的单元测试还是业务逻辑的单元测试,都是低耦合的
(3).MVVM 和 MVC 的区别:
mvc 和 mvvm 其实区别并不大。都是一种设计思想,主要区别如下:1.mvc 中 Controller演变成 mvvm 中的 viewModel2.mvvm 通过数据来驱动视图层的显示而不是节点操作。3.mvc中Model和View是可以直接打交道的,造成Model层和View层之间的耦合度高。而mvvm中Model和View不直接交互,而是通过中间桥梁ViewModel来同步4.mvvm主要解决了:mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
一般在哪个生命周期里请求接口
接口请求一般放在mounted
中,但需要注意的是服务端渲染时不支持mounted
,需要放到created
中
Vue 的组件通信
参考我另一篇文章,所有组件之间的通信
Vue 中是如何检测数组的变化
vue中我们对数组进行push,splice,shift的一些操作时候也会触发render-watcher。这是因为vue中对这些数组的方法进行了一些扩展,使其能够进行数据的响应式,
vue3:proxy可以自动做到
Vue 组件中的data为什么要写成函数形式
Vue 的组件都是可复用的,一个组件创建好后,可以在多个地方复用,而不管复用多少次,组件内的data
都应该是相互隔离,互不影响的,所以组件每复用一次,data
就应该复用一次,每一处复用组件的data
改变应该对其他复用组件的数据不影响。
为了实现这样的效果,data
就不能是单纯的对象,而是以一个函数返回值的形式,所以每个组件实例可以维护独立的数据拷贝,不会相互影响。
nextTick 是做什么用的,其原理是什么
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。应用场景:需要在试图更新之后,基于新的视图进行操作
Vue 的模板编译原理
computed 与 watch 的差异
计算属性computed :
侦听属性watch:
监听的对象也可以写成字符串的形式
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。这是和computed最大的区别,请勿滥用。嗯,就酱~
vue-router 中的导航钩子
vue-router 的导航钩子,主要用来作用是拦截导航,让他完成跳转或取消。
有三种方式可以植入路由导航过程中:
-
全局的
-
单个路由独享的
-
组件级的
1. 全局导航钩子:
全局导航钩子主要有两种钩子:前置守卫、后置钩子,
注册一个全局前置守卫:
const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
// do someting
});1234
这三个参数 to 、from 、next 分别的作用:
-
to: Route,代表要进入的目标,它是一个路由对象
-
from: Route,代表当前正要离开的路由,同样也是一个路由对象
-
next: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数
- next():进入管道中的下一个钩子,如果全部的钩子执行完了,则导航的状态就是 confirmed(确认的)
- next(false):这代表中断掉当前的导航,即 to 代表的路由对象不会进入,被中断,此时该表 URL 地址会被重置到 from 路由对应的地址
- next(‘/’) 和 next({path: ‘/’}):在中断掉当前导航的同时,跳转到一个不同的地址
- next(error):如果传入参数是一个 Error 实例,那么导航被终止的同时会将错误传递给 router.onError() 注册过的回调
注意:next 方法必须要调用,否则钩子函数无法 resolved
对于全局后置钩子:
router.afterEach((to, from) => {
// do someting
});123
不同于前置守卫,后置钩子并没有 next 函数,也不会改变导航本身
2. 路由独享的钩子
顾名思义,即单个路由独享的导航钩子,它是在路由配置上直接进行定义的:
cont router = new VueRouter({
routes: [
{
path: '/file',
component: File,
beforeEnter: (to, from ,next) => {
// do someting
}
}
]
});1234567891011
至于他的参数的使用,和全局前置守卫是一样的
3. 组建内的导航钩子
组件内的导航钩子主要有这三种:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是直接在路由组件内部直接进行定义的
我们看一下他的具体用法:
const File = {
template: `<div>This is file</div>`,
beforeRouteEnter(to, from, next) {
// do someting
// 在渲染该组件的对应路由被 confirm 前调用
},
beforeRouteUpdate(to, from, next) {
// do someting
// 在当前路由改变,但是依然渲染该组件是调用
},
beforeRouteLeave(to, from ,next) {
// do someting
// 导航离开该组件的对应路由时被调用
}
}123456789101112131415
需要注意是:
beforeRouteEnter 不能获取组件实例 this,因为当守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例 this
但是并不意味着在 beforeRouteEnter 中无法访问组件实例,我们可以通过给 next 传入一个回调来访问组件实例。在导航被确认是,会执行这个回调,这时就可以访问组件实例了,如:
beforeRouteEnter(to, from, next) {
next (vm => {
// 这里通过 vm 来访问组件实例解决了没有 this 的问题
})
}12345
注意,仅仅是 beforRouteEnter 支持给 next 传递回调,其他两个并不支持。因为归根结底,支持回调是为了解决 this 问题,而其他两个钩子的 this 可以正确访问到组件实例,所有没有必要使用回调
最后是完整的导航解析流程:
- 导航被触发
- 在失活的组件里调用离开守卫
- 调用全局的 beforeEach 守卫
- 在重用的组件里调用 beforeRouteUpdate 守卫
- 在路由配置里调用 beforEnter
- 解析异步路由组件
- 在被激活的组件里调用 beforeRouteEnter
- 调用全局的 beforeResolve 守卫
- 导航被确认
- 调用全局的 afterEach 钩子
- 触发 DOM 更新
- 在创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数
vue-router的两种模式
众所周知,vue-router有两种模式,hash模式和history模式,这里来谈谈两者的区别。
hash模式
hash模式背后的原理是onhashchange
事件,可以在window
对象上监听这个事件:
上面的代码可以通过改变hash来改变页面字体颜色,虽然没什么用,但是一定程度上说明了原理。
更关键的一点是,因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用了,同时点击后退时,页面字体颜色也会发生变化。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来,后来人们给它起了一个霸气的名字叫前端路由,成为了单页应用标配。
history路由
随着history api的到来,前端路由开始进化了,前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由
Vue中 key 值的作用
key
的作用是给予一个节点唯一的身份识别,有相同父元素的子元素必须有独特的 key
。这样它可以前后对比,算出哪些节点是要重复使用或者调整顺序。比如原先的 key
的顺序是 i1,i2,i3
,之后变成了 i2,i1,i3
这个时候只要i3保持不变,把i2 insertBefore
到i1节点前就行了(以上是举例,vue具体怎么操作的需要去研究源码)。如果是利用数组的 index
来作为 key
则两次对比没有区别,就会出现上面动图里出现的子组件没有更新的情况。
- v-for遍历时,用id,uuid之类作为key,唯一标识节点加速虚拟DOM渲染
- 响应式系统没有监听到的数据,用+new Date()生成的时间戳作为key,手动强制触发重新渲染
Vue中常见的修饰符
.lazy .number .trim
Vue中常用的指令
v-text v-html v-bind
v-model v-for和key v-if
和v-show
v-show 与 v-if 的区别
- vue-show本质就是标签display设置为none,控制隐藏
- vue-if是动态的向DOM树内添加或者删除DOM元素
keep-alive 组件的作用
1.keep-alive的作用以及好处
在做电商有关的项目中,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页,这时候我们使用keep-alive来缓存组件,防止二次渲染,这样会大大的节省性能。
2.keep-alive的基本用法
需要缓存的组件内容直接在router中添加:
3.keep-alive的生命周期
当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。
Vue的虚拟dom
模板转换成视图得过程;
详解:www.cnblogs.com/fundebug/p/…
Virtual DOM 是什么?
Virtual DOM 其实就是一棵以 JavaScript 对象( VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。
简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性。不同的框架对这三个属性的命名会有点差别。
对于虚拟DOM,咱们来看一个简单的实例,就是下图所示的这个,详细的阐述了模板 → 渲染函数 → 虚拟DOM树 → 真实DOM
的一个过程
跨域的几种实现方式
jsonp ,
nginx代理,
CORS
Websocket,
HTML5 推出了一个新的函数 postMessage()
网站的本地缓存
Cookie(或者Cookies)
localStorage
是html5的一种新的本地缓存方案,目前用的比较多,一般用来存储ajax返回的数据,加快下次页面打开时的渲染速度。
localStorage核心API:
localStorage.setItem(key, value) 设置记录
localStorage.getItem(key) 获取记录
localStorage.removeItem(key) 删除该域名下单条记录
localStorage.clear() 删除该域名下所有记录
sessionStorage
IndexedDB