1.vue组件data 为什么必须是函数?而vue根实例没有此限制?
vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们公用一个data对象,那么状态变更将会影响所有组件实例,这是不合理的,采用函数的形式定义,在initData时会将其作为工厂函数返回全新data对象,有效规避多实例之间状态污染问题,而vue根实例创建过程则不存在该限制,也是因为根实例只能有一个,不需要担心这种情况。
简单说:
// 导入多次组件,指向是一样的,这种写法对象是复杂类型,所有导入组件的 数据会混乱
data:{
leftPosition:0,
}
// 这种写法每次return新对象,互不影响
data(){
return {
leftPosition:0,
}
}
2.v-if和v-for哪个优先级更高?如果俩个同时出现,应该怎么优化得到更好的性能?
- 显然v-for优先于v-if被解析
- 如果同时出现,每次渲染都会先执行循环再判断条件,无论如何循环都不可避免,浪费了性能
- 要避免出现这种情况,则在外层嵌套template,在这一层进行v-if判断,然后在内部进行v-for循环
3.key的作用?
- key的作用主要是为了高效的更新虚拟dom,其原理是vue在patch过程中通过key可以精准判断俩个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少dom操作量,提高性能。
- 另外,若不设置key还可能在列表更新时引发一些隐蔽的bug
- vue中在使用相同标签名元素的过度切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过度效果。
4.diff理解
- diff算法是虚拟dom技术的必然产物,通过新旧虚拟dom作对比(即diff),将变化的地方更新在真实dom上,另外,也需要diff高效执行对比过程,从而降低时间复杂度为O(n). 2.vue2.x中为了降低watcher粒度,每个组件只有一个watcher与之对应,只有引入diff才能精确找到发生变化的地方。 3.vue中diff执行的时刻是组件实例执行其更新函数时,它会比对上一次渲染结果oldVnode和新的渲染结果newVnode,此过程称patch。 4.diff过程整体遵循深度优先,同层比较策略,俩个节点之间比较会根据它们是否拥有子节点或者文本节点做不同操作,比较俩组子节点是算法的重点,首先假设头尾节点可能相同做4此比对尝试,如果没有找到相同节点才按照通用方试遍历查找,查找结束再按情况处理剩下的节点,借助key通常可以非常精确的找到相同的节点,因此整个patch过程非常高效
5.跨域问题
1.什么是跨域? 域名、协议、ip地址、端口号 任何一个不一样就是跨域
2.解决跨域?
- jsonp ---使用script的src发送 只能get请求.
- cors后台设置允许跨域 需要后台设置允许跨域 所有后台语言都可以设置.
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods:"POST,GET,OPIONS,DELECT"
-
服务器代理
1>重点现在vue框架是可以自己设置服务器代理的proxy
vue 在vue.config.js可以配置重写webpack
6.Keep-alive 的使用
1.怎么缓存?Keep-alive 2.缓存了 我突然需要缓存的组件 重新发生请求换数据? 缓存的组件还提供了activated生命周期,可以在这里面重新发送请求
<keep-alive >
<router-view></router-view>
</keep-alive>
新增了俩种生命周期: 1》activated 组件激活 缓存之后 其他的不会走 但是这个每次进去都触发 2》deactivated组件走了
7.刷新后vuex中的数据消失了怎么解决?
vuex数据位于内存,页面刷新会导致数据归零,也就是所谓的消失,可以用localStorage来存储,在state数据初始化/更新的时候,进行读取和设置本地缓存操作
8.vue原理
vue通过原生js的object.defineProperty 监听到了 我们写的data数据,这个data里面的数据,有修改就会触发object.defineProperty里面的set 在set里面我们可以获取到最新的修改的值去页面上 正则匹配到对应的地方 替换修改。
9.前端鉴权一般思路?
1.有些axios请求需要token 我们是可以配置请求拦截器 2.有些页面需要登录才能看, 我们也可以用路由导航守卫router.beforeEach 判断token 3.不同的人登录返回不同的后台侧边栏,
router.beforeEach((to,from,next)=>{
// 判断user信息是否已经获取
if(token){
// 根据用户的角色类型来生成对应的新路由
const newRouter=[{path:'/xx'}...];
router.addRoutes(newRouter);
// 为正确渲染导航,将对应的新路由添加到对vuex中渲染对应的侧边栏
}
})
10.vue和react的数据流
vue react 数据流是单向的, 父-子 vue还有一个概念是v-model
11.vue的特征?
1) 轻量级的框架
Vue.js 能够自动追踪依赖的模板表达式和计算属性,提供 MVVM 数据绑定和一个可组合的组件系统,具
有简单、灵活的 API,使读者更加容易理解,能够更快上手。
2) 双向数据绑定
声明式渲染是数据双向绑定的主要体现,同样也是 Vue.js 的核心,它允许采用简洁的模板语法将数据声
明式渲染整合进 DOM。
3) 指令
Vue.js 与页面进行交互,主要就是通过内置指令来完成的,指令的作用是当其表达式的值改变时相应地
将某些行为应用到 DOM 上。
4) 组件化
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。
在 Vue 中,父子组件通过 props 传递通信,从父向子单向传递。子组件与父组件通信,通过触发事件
通知父组件改变数据。这样就形成了一个基本的父子通信模式。
在开发中组件和 HTML、JavaScript 等有非常紧密的关系时,可以根据实际的需要自定义组件,使开发
变得更加便利,可大量减少代码编写量。
组件还支持热重载(hotreload)。当我们做了修改时,不会刷新页面,只是对组件本身进行立刻重载,
不会影响整个应用当前的状态。CSS 也支持热重载。
5) 客户端路由
Vue-router 是 Vue.js 官方的路由插件,与 Vue.js 深度集成,用于构建单页面应用。Vue 单页面
应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来,传统的页面是通过超链接实
现页面的切换和跳转的。
6) 状态管理
状态管理实际就是一个单向的数据流,State 驱动 View 的渲染,而用户对 View 进行操作产生
Action,使 State 产生变化,从而使 View 重新渲染,形成一个单独的组件。
12.vue中父子组件的传值的方式有几种?它们有什么数据上的限制?
props event bus $emit vuex storage provide/inject(优点是不用层层传递了)
12.Virtual DOM 是什么?
Virtual DOM 是什么? Virtual DOM 其实就是一棵以 JavaScript 对象( VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。
简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性。不同的框架对这三个属性的命名会有点差别。
对于虚拟DOM,咱们来看一个简单的实例,就是下图所示的这个,详细的阐述了模板 → 渲染函数 → 虚拟DOM树 → 真实DOM的一个过程
blog.fundebug.com/2019/06/26/…
13.$nextTick?
nextTick,则可以在回调中获取更新后的 DOM
14.响应式原理?
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者。
var obj = {};
Object.defineProperty(obj, 'name', {
get: function() {
console.log('获取了')
return val;
},
set: function (newVal) {
console.log('设置了')
}
})
obj.name = 'yzg'; / /在给obj设置name属性的时候,触发了set这个方法
var val = obj.name; //在得到obj的name属性,会触发get方法