目录
面试之vue篇
vue父子组件生命周期执行顺序
- 渲染阶段
- 父beforeCreate - 父created - 父beforeMount
- 子beforeCreate - 子created - 子beforeMount - 子mounted
- 父mounted
- 更新阶段
- 父beforeUpdate
- 子beforeUpdata - 子updated
- 父updated
- 父组件更新阶段
- 父beforeUpdated - 父updated
- 销毁阶段
- 父 beforeDestroy
- 子 beforeDestroy – destroyed
- 父 destroyed
v-for指令的 key作用
- key作用:就是给遍历的dom节点添加一个唯一的标志
- key值必须为唯一和稳定的值
- vue的渲染起由:vue再渲染的时候,为了高效的性能,会保留原本的标签(dom节点),再原有的基础上进行渲染
- 添加key值之后,对渲染的列表增删改查之后,针对唯一的key值进行修改,实现精准修改dom节点,实现高效的虚拟dom
- 虚拟dom (Virtual DOM)
- 虚拟DOM就是一个结构类似于真实DOM的js对象
- 虚拟DOM提高性能的原因:
- 1:减少DOM节点的操作 console.time()打印时间,console.endtime()
- 2:在一个特点的时间内,过滤掉无效的dom操作,根据初始的dom的状态和结束的dom状态,两者判断有差异,那么就操作dom(这是依靠diff算法来处理的)
v-for之中的key值 id和index那个快
- 若是key使用为index值,若是数据基本上不变的情况下,diff算法根据key值为index查找更快
- 若是key使用id值,若是数据量多,而且数据是有变化的,diff算法根据key值为id查找更快
vue局部样式的原理
- 给局部组件添加一个 scoped
- 再编译的时候,会给组件的html标签上添加一个自定义属性值(data-v-[‘hash值’],这个值为哈希值)
- 这个属性 便是 属性选择器实现
- 注意点:::v-deep 可以修改其他组件的样式! >>>
v-if 和 v-show的区别
-
v-if:就是根据条件判断,是否创建dom元素,若是为true则创建dom节点,若是为false则不创建dom节点或者销毁dom节点(这是惰性的)
-
v-show:dom节点已经渲染完毕了,只是控制css的显示隐藏(display:block none)
vue生命周期
- vue生命周期就是从vue 实例对象创建 - 使用 - 销毁的阶段,这些阶段都伴随着钩子函数的触发
- 在初始化数据前,会触发 beforeCreate()钩子函数
- 在注入数据后,会触发created()钩子函数 这是最新拿到data数据的
- 之后对模板的编译,把html解析为dom树,还有css也是解析为样式dom树,两者结合,再加上js渲染引擎渲染,形成一刻虚拟dom树,保存在浏览器内存之中,此时页面是没有挂载上的! 这个阶段后会触发 beforeMount()钩子函数
- 然后根据el挂载视图,若是有template会替换掉el所挂载的,若是有render()也是会替换掉前面的 经过挂载后,会触发mounted()钩子函数,在这里可以操作dom节点,发起ajax请求
- 若是数据data有更新,那么数据更新前会触beforeUpdate()钩子函数
- 数据更新后,会触发updated()钩子函数
- 之后,在实例销毁前,会触发beforeDestroy()钩子函数,这时候el还是可以使用的
- 实例销毁后,destroyed() el已经被销毁了,数据的双向绑定已经解绑了! 这里一般用去定时器的取消,ajax的取消!
- vue一次生命周期会触发几个钩子函数
- beforeCreate()
- created()
- beforeMount()
- mounted()
vuex的作用
- vuex状态管理工具
- vuex的作用:
- 对组件数据状态的管理,可跨组件去实现
- vuex缺点:刷新页面,会清空vuex的数据
- 解决:
- 把数据存储再本地之中,刷新后,再进行调用
- 封装一个方法,刷新页面后,vuex数据为空,再使用数据的页面,进行接口调用
- 解决:
vue中computed与watch、methods的区别
- computed:计算属性
- 具有缓存效果,若是数据有发生改变,拿最新的,否者拿缓存的
- 第一次的时候就执行了
- watch:监听属性
- 监听数据的改变,函数内返回 一个 新值 与 旧值,针对性的做想应逻辑处理
- 只有数据发生改变才会触发
- deep:监听对象
- immediate:立即触发
- methods:方法
- 组件的加载,methods的方法都会执行一遍,不具备缓存效果
mixin作用
- 就是抽离公共代码,组件注册等,还有一些公共的变量,公共的分页函数等
v-for遍历的数据,通过下标修改数据
- v-for遍历的数据,通过下标修改数据,是可以修改数据但页面不会重新渲染
<!--
描述:
作者:xzl
时间:05月06日171358
-->
<template>
<div>
Home
<div v-for="(item, idx) in arr" :key="idx">{{ item }}</div>
<div>{{ obj }}</div>
<button @click="btn">按钮</button>
</div>
</template>
<script>
export default {
name: 'Home',
components: {},
data() {
return {
arr: [
{
age: '1'
},
{
age: '2'
}
],
obj: {
age: 10
}
}
},
methods: {
btn() {
this.arr[0].age = '001'
this.obj.age = '100'
}
}
}
</script>
<style lang="scss" scoped></style>
nextTick 实现原理
- nextTick
- 作用:是为了清空执行消息队列之中的宏任务与微任务。
- 多次调用nextTick会将nextTick存入队列之中,通过这个异步方法清空当前队列。
- nextTick是异步方法!
vue路由
-
全局的路由守卫
- router.beforeEach 全局前置路由守卫 -> 可以用于权限管理
- router.beforeResolve 全局解析守卫
- router.afterEach 全局后置钩子
-
路由独享的守卫
- beforeEnter
-
组件的路由守卫
- beforeRouteEnter 进入路由前 ( 进行异步请求 )
- beforeRouteLeave 离开路由前
- beforeRouteUpdate 路由更新
router、route的区别
- $router 这是路由对象
- 大体而言,就是用之路由之间的跳转,a路由跳转到 b路由 等
- this. r o u t e r . p u s h ( ) 、 t h i s . router.push({})、this. router.push()、this.router.replace({})
- route 这是指向当前活跃的路由对象
- 可以从当前路由之中拿到当前活跃路由的相关信息( path、name、数据等 )
query和params传递参数区别
- query
- 以参数的形式传递,在url之中的参数路径 ? 后面拼接对应的query参数
- 刷新后,当前url依旧存在,所传递的值不会消失,类似get请求
- parmas
- 以动态路由的形式传递,需要在路由之中配置
eg: { path: '/home/:id }
- 刷新后,params传递的值会消息,但id比较特殊会保留下来,类似post请求
- 以动态路由的形式传递,需要在路由之中配置
this. r o u t e r . p u s h ( ) 、 t h i s . router.push({})、this. router.push()、this.router.replace({})的区别
- this.$router.push({})
- 具有前退后进的效果
- this.$router.replace({})
- 不存在history记录的路由
hash和history区别
- hash 就是指 url 后面的 # 号以及后面的字符,history没有带#,外观上比hash 模式好看些
- 原理
- hash原理
- hash 改变会触发 hashchange 事件,不会触发http请求,因此改变hash值不会重新加载页面
- history原理
- history中新增的两个API pushState() 和 replaceState() 和一个事件onpopstate监听URL变化
- history模式URL就要和后端进行一致,所以要改为history也需要后端的配合,否则会报错
- hash原理
keep-alive 多级路由缓存
- keep-alive 组件对第三级及以上级的路由页面缓存失效
- 解决方案
- 方案1、直接将路由扁平化配置,都放在一级或二级路由中
- 方案2、再一层缓存组件用来过渡,并将其name配置到include中
- 解决方案
- 方案2
// src/layout/component/AppMain.vue
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view :key="key" />
</keep-alive>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
}
}
</script>
keep-alive 下的生命周期函数
- activated,deactivated这两个生命周期函数一定是要在使用了keep-alive组件后才会有的,否则则不存在 。
- 当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,
- 退出时触发deactivated。
- 当再次进入(前进或者后退)时,只触发activated。
- 注意点:
- activated里面,可以对于缓存的组件页面 进行 初始化页面数据 等
- deactivated里面,可以对于缓存的组件页面 进行 删除定时器什么的