vue生命周期
什么是vue生命周期?
vue实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom->渲染、更新->渲染、卸载等一些列的过程。我们称这是vue的生命周期。
vue生命周期的作用?
vue的生命周期中有多个事件钩子,让我们在控制整个vue示例的过程时更容易形成好的逻辑。
第一次页面加载会触发那几个钩子?
beforeCreate、created、beforeMount、mounted
DOM渲染在哪个周期中就已经完成
mounted
Vue 的父组件和子组件生命周期钩子执行顺序是什么
-
加载渲染过程 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
-
子组件更新过程 父beforeUpdate->子beforeUpdate->子updated->父updated
-
父组件更新过程 父beforeUpdate->父updated
-
销毁过程 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
vuex相关面试
vuex有哪几种属性?
5中,分别是state、getter、mutation、action、module
state单一状态树。在state中需要定义我们所需要管理的数组,对象,字符等,只有在这里定义了,在vue的组件中才能获取你定义的这个对象的状态。(基本数据 )getter类似vue的计算属性,当我们需要从store的state中派生出一些状态,那么我们就需要使用getter,getter会接受state作为第一个参数,而且getter的返回值会根据他的依赖被缓存起来,只有getter中的依赖值(state中的某个需要派生状态的值)发生改变的时候才会被重新计算。(从基本数据派生的数据 )mutation更改store中state状态的唯一方法就是提交mutation,每个mutation都有一个字符串类型的事件类型和一个回调函数,我们需要改变state的值就要在回调函数中改变。我们要执行这个回调函数,那么我们需要执行一个相应的调用方法:store.commit。(提交更改数据的方法,同步! )actionaction可以提交mutation,在action中可以执行store.commit,而且action中可以有任何的异步操作。在页面中如果我们要调用这个action,则需要执行store.dispatch.( 像一个装饰器,包裹mutations,使之可以异步。 )module其实只是解决了当state中很复杂臃肿的时候,module可以将store分割成模块,每个模块中拥有自己的state、mutation、action和getter。(模块化Vuex)
vuex的State特性是?
- Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
- state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
- 它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
vuex的Getter特性是?
- getters 可以对State进行计算操作,它就是Store的计算属性
- 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
- 如果一个状态只在一个组件内使用,是可以不用getters
vuex的Mutation特性是?
- Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作
Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
- 如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
- 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。
不用Vuex会带来什么问题?
- 可维护性会下降,你要想修改数据,你得维护三个地方
- 可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的
- 增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。 但兄弟组件有大量通信的,建议一定要用,不管大项目和小项目,因为这样会省很多事
vuex的store有几个属性值?
state,mutations,active,getters
Vue computed 和 watch 区别
methods- 在页面中使用大量或是复杂的表达式去处理数据,对页面的维护会有很大的影响。这个时候就需要用到computed 计算属性来处理复杂的逻辑运算。
- computed 计算属性只有在相关的数据发生变化时才会改变要计算的属性,当相关数据没有变化是,它会读取缓存。
- Watch:当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,自定义 watcher 的方式就会很有帮助。
写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么?
key是给每一个vnode的唯一id,可以依靠key,更准确, 更快的拿到oldVnode中对应的vnode节点。
如果数据位置替换了,
- 没key,dom位置不变,节点innerText内容更新了
- 有key,dom位置变了,内容没有更新
数据进行增删
- 没key, 节点位置不变,内容也更新了
- 有key, 节点删除了 A, B 节点,新增了 F, G 节点
['1', '2', '3'].map(parseInt) what & why ?
对于每个迭代map, parseInt()传递两个参数: 字符串和基数。 所以实际执行的的代码是:
['1', '2', '3'].map((item, index) => {
return parseInt(item, index)
})
即返回的值分别为:
介绍下 Set、Map、WeakSet 和 WeakMap 的区别?
Set
- 成员的值都是唯一的,没有重复的值
- 两个属性 constructor,size
- 可以遍历,
- 四个方法:add, delete,has,clear
weakSet
- 不重复的值的集合
- 成员只能是对象,而不能是其他类型的值。
- 没有size属性,不能遍历,
- 三个方法add,delete,has
Map
- JavaScript 的对象(Object),本质上是键值对的集合
- 但是传统上只能用字符串当作键。
- 可以遍历,方法很多,可以干跟各种数据格式转换
weakMap
- 只接受对象作为键名
- 健名所指向的对象,不计入垃圾回收机制
- 不能遍历,方法同get,set,has,delete
ES5/ES6 的继承除了写法以外还有什么区别?
介绍下深度优先遍历和广度优先遍历,如何实现?
请分别用深度优先思想和广度优先思想实现一个拷贝函数?
setTimeout、Promise、Async/Await 的区别
事件循环中分为宏任务队列和微任务队列。
setTimeout
console.log('script start') //1. 打印 script start
setTimeout(function(){
console.log('settimeout') // 4. 打印 settimeout
}) // 2. 调用 setTimeout 函数,并定义其完成后执行的回调函数
console.log('script end') //3. 打印 script start
// 输出顺序: script start -> script end -> settimeout
Promise
console.log('script start') // 1111111
let promise1 = new Promise(function (resolve) {
console.log('promise1') // 222222
resolve()
console.log('promise1 end') // 333333
}).then(function () {
console.log('promise2')
})
setTimeout(function(){
console.log('settimeout')
})
console.log('script end')
// 输出顺序: script start -> promise1 -> promise1 end -> script end-> promise2 -> settimeout
async/await
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出顺序:script start -> async1 start -> async2 -> script end -> async1 end
将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组
已知如下数组: var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]; 编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
let newArr = [...new Set(arr.flat(Infinity)].sort((a,b)=>a-b)
Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?
promise构造函数是同步执行的,then方法是异步执行的
介绍下 npm 模块安装机制,为什么输入 npm install 就可以自动安装对应的模块?
????
有以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() 、 instanceof 以及 Array.isArray()
关于 const 和 let 声明的变量不在 window 上
在ES5中,全局变量直接挂载到全局对象的属性上,所以能在window上看到var声明的变量 在ES6中,全局对象的属性和全局变量脱钩,但是为了保持兼容性,旧的不变,所以var、function声明的全局变量依然可以在window对象上看到,而let、const声明的全局变量在window对象上看不到
vue 的双向数据绑定,Model 如何改变 View,View 又是如何改变 Model 的
在 Vue 中,子组件为何不可以修改父组件传递的 Prop,如果修改了,Vue 是如何监控到属性的修改并给出警告的。
为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。
vue如何知道修改了父组件传来的props?
然而 props传入的是对象的话 是可以直接在子组件里更改的, 因为是同一个引用 组件对于data的监听是深度监听 而对于props的监听是浅度监听
使用 sort() 对数组 [3, 15, 8, 29, 102, 22] 进行排序,输出结果
let arr = [3, 15, 8, 29, 102, 22]
arr.sort((a, b)=>{
return a-b
})
双向绑定和 vuex 是否冲突
在严格模式下直接使用确实会有问题。 解决方案:
<input v-model="message" />
computed: {
message: {
set (value) {
this.$store.dispatch('updateMessage', value);
},
get () {
return this.$store.state.obj.message
}
}
}
mutations: {
UPDATE_MESSAGE (state, v) {
state.obj.message = v;
}
}
actions: {
update_message ({ commit }, v) {
commit('UPDATE_MESSAGE', v);
}
}
Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
- Object.defineProperty无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;
- Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy可以劫持整个对象,并返回一个新的对象。
- Proxy不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
怎么让一个 div 水平垂直居中
<div class="parent">
<div class="child"></div>
</div>
div.parent{
display:flex;
}
div.child{
margin:auto;
}
给定两个数组,写一个方法来计算它们的交集。
var nums1 = [1, 2, 2, 1], nums2 = [2, 2, 3, 4];
var newArr2 = nums1.filter((item) => {
return nums2.includes(item);
});
console.log(newArr2);
如何把一个字符串的大小写取反(大写变小写小写变大写),例如 ’AbC' 变成 'aBc' 。
function processString (s) {
var arr = s.split('');
var new_arr = arr.map((item) => {
return item === item.toUpperCase() ? item.toLowerCase() : item.toUpperCase();
});
return new_arr.join('');
}
console.log(processString('AbC'));
input 搜索如何防抖,如何处理中文输入
var let const
let
- let 只在let命令所在的代码块内有效。
- 不存在变量提升。
- 暂时性死区(只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。)
- 不允许在相同作用域内,重复声明同一个变量。
var
- var命令声明的,在全局范围内都有效
- 会发生变量提升
- 可以重复定义
- 没有块级作用域
const
- 声明一个只读的常量。一旦声明,常量的值就不能改变。
- 一旦声明变量,就必须立即初始化,
- 只在声明所在的块级作用域内有效。
- 不存在变量提升。
- 不可重复声明