一、Vue2
1. 关于生命周期
1.1 生命周期有哪些?发送请求在created还是mounted?
生命周期 | 描述 |
---|---|
beforeCreate |
组件实例被创建之前(没有dom,没有$data) |
created |
组件实例已经完全创建(没有dom,有$data) |
beforeMount |
组件挂载之前(没有dom,有$data) |
mounted |
组件被挂载到实例上之后(有dom,有$data) |
beforeUpdate |
组件数据发生变化,更新之前 |
updated |
组件数据更新之后 |
beforeDestroy |
组件实例销毁之前 |
destroyed |
组件实例销毁之后 |
mounted可以操作dom又可以操作data,还可以操作子组件;而在created的时候不能操作dom也不能操作子组件。
发送请求是异步任务,会在同步任务执行完毕之后执行,即获取到数据也是会在mounted执行完之后。
这个问题具体要看项目和业务情况,因为组件的加载顺序是,会先执行父组件的前3个生命周期,再执行子组件的前4个生命周期。如果业务是父组件引入子组件,并且优先加载子组件的数据,那么在父组件中当前请求要放在mounted
中,让子组件的请求先去执行,让子组件的数据先加载出来。
1.2 为什么发送请求不在beforeCreate里?beforeCreate和created有什么区别?
如果请求是在methods里封装好的,在beforeCreate里是拿不到methods的方法的。
beforeCreate阶段没有$data ,拿不到methods方法,created阶段有$data,拿得到methods方法。
1.3 在created中如何获取dom?
- 用异步代码获取,例如setTimeout
- 使用vue的
this.$nextTick
1.4 一旦进入到组件会执行哪些生命周期?
beforeCreate
、created
、beforeMount
、mounted
1.5 第二次或者第N次进去组件会执行哪些生命周期?
如果当前组件加入了keep-alive,只会执行activated
;
如果没有加入keep-alive依然执行前四个生命周期beforeCreate
、created
、beforeMount
、mounted
1.6 父子组件生命周期执行顺序?
父组件 beforeCreate
created
beforeMount
子组件 beforeCreate
created
beforeMount
mounted
父组件 mounted
1.7 加入keep-alive会执行哪些生命周期?
如果使用了keep-alive组件,当前组件会额外增加两个生命周期。
activated
:被 keep-alive 缓存的组件激活时调用
deactivated
:被 keep-alive 缓存的组件失活时调用。
如果当前组件加入了keep-alive,第一次进入这个组件会执行5个生命周期:beforeCreate
created
beforeMount
mounted
activated
1.8 你在什么情况下用过哪些生命周期?说一说生命周期使用场景?
created
:单一组件进行请求
mounted
:有父子组件关系的时候,进行请求;同步操作dom
activated
:处理缓存
beforeDestroy
:关闭页面的时候进行数据记录
2. 关于组件
2.1 组件通讯方式
父传子:
- v-bind绑定props。不能传孙,且有多个子组件时需要一个一个操作;子不能直接修改父组件的数据
- 子组件直接使用父组件数据
this.$parent
。子能直接修改父组件的数据 - 依赖注入provide、inject。不用逐级传递,可以实现直接传递给孙
子传父:
- 子组件自定义事件
this.$emit
。 - 父组件直接使用子组件数据:
this.$children[index].xxx
或this.$refs[name].xxx
兄弟互传:
- EventBus(
$on
接收方,$emit
发送方)
2.2 父组件如何直接修改子组件的值
this.$children[index].xxx
或 this.$refs[name].xxx
2.3 子组件如何直接修改父组件的值
this.$parent.xxx
2.4 如何找到父组件
this.$parent
2.5 如何找到根组件
this.$root
2.6 keep-alive
用来缓存当前组件
2.7 slot插槽
- 匿名插槽
- 具名插槽
- 作用域插槽:对组件传递 props 那样,向一个插槽的出口上传递 attributes
2.8 provide、inject
依赖注入,用来实现给后辈组件传递数据
2.9 如何封装组件
抽取复用部分内容,用slot插槽去实现父组件可以自定义部分特殊的内容;通过v-bind绑定props去实现获取父组件数据;通过自定义事件去实现给父组件传递数据。
3. 关于Vuex
3.1 vuex有哪些属性
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享。
State
用来存储公共数据源。全局共享属性。Mutation
用于同步变更state中的数据。Action
用于异步变更state中的数据,但是在Action中还是要用过触发Mutation的方式间接变更数据。Getter
用于对Store中的数据进行加工处理形成新的数据(类似于计算属性),Store中数据发生变化,Getter中的数据也会变化。针对state数据进行二次计算。moudle
属性是将store分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
3.2 vuex使用state值
this.$store.state.xxx
computed: { ...mapState(['全局数据名称1','全局数据名称2',...]) }
区别:使用this.$store的方式可以直接修改(不推荐),使用辅助函数的方式不能直接修改
3.3 vuex的getters值修改
getters不可以修改
3.4 vuex的mutations和actions的区别
相同点:都是来存放全局方法的;不能有return值
区别:mutation是同步的,actions是异步的;mutation是用来修改state的,action是用来提交mutation的
3.5 vuex持久化存储
vuex本身不是持久化存储,它只是一个全局数据管理仓库。
实现方式:
- 自己写localStorage
- 使用vuex-persistedstate插件
4. 关于路由
4.1 路由的模式和区别
路由模式:history、hash
区别:
- 表象不同:hash路径有一个#,history/
- history找不到当前页面会发送请求,而hash不会
- 项目打包前端自测的时候,hash可以看到内容,hsitory默认情况是看不到内容的
4.2 子路由和动态路由
详请->
Vue Router基础知识整理
4.3 路由传值
详请->
Vue Router基础知识整理
4.4 路由故障
当前页跳当前页,路径不变,参数变
import Vue from 'vue'
import VueRouter from 'vue-router'
// 解决路由重复跳转错误
const routerPush = VueRouter.prototype.push;
VueRouter.prototype.push = function (location) {
return routerPush.call(this, location).catch(err => { })
};
Vue.use(VueRouter)
4.5 $router 和 $route的区别
$router
路由管理对象(路由跳转)$route
路由单体对象,指某一条路由(获取当前路径相关)
4.6 导航守卫
全局守卫:全局前置守卫
router.beforeEach
:路由进入前;全局后置钩子router.afterEach
:路由进入后路由独享守卫:
beforeEnter
只在进入路由时触发组件内守卫:
beforeRouteEnter
在渲染该组件的对应路由被验证前调用、beforeRouteUpdate
在当前路由改变,但是该组件被复用时调用、beforeRouteLeave
在导航离开渲染该组件的对应路由时调用
5. 关于API
5.1 $set
场景:直接通过数组下标去修改数组造成相应丢失
this.$set(target,key,value)
5.2 $nextTick
等待下一次 DOM 更新刷新的工具方法。异步的。
获取更新后的dom;等待dom更新完再执行后续操作。
官方说明:当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。nextTick()
可以在状态改变后立即使用,以等待 DOM 更新完成。
5.3 $refs
用来获取dom
5.4 $el
获取当前组件的节点
5.5 $data
获取当前组件的data数据
5.6 $children
获取当前组件的所有子组件(一个数组)
5.7 $parent
找到当前组件的父组件,无则返回自身
5.8 $root
找到当前组件的根组件,无则返回自身
5.9 data定义数据
return里外的区别
外:需要用this;不被劫持(没有get/set),不支持双向绑定
内:被劫持,双向绑定
5.10 computed计算属性
计算结果要修改的话要通过set写法
计算属性computed:(可依赖多个属性):
- 缓存:计算属性基于其依赖进行缓存。
- 性能优化:当依赖没有改变时,多次访问计算属性不会触发重新计算
- 同步:计算属性是同步的,并在渲染过程中进行计算。
- 简洁性:对于简单的数据转换和组合,计算属性提供了更简洁的语法。
5.11 watch
监听属性watch:(只监听一个属性,可监听到数据变化前的值):
- 异步:监听属性允许你在数据变化后执行异步操作。
- 执行机制:监听属性在数据改变后触发,而不是在渲染过程中。
- 可访问DOM:在监听属性函数中,你可以访问组件的DOM。
- 对复杂逻辑的支持:如果你需要进行复杂的逻辑判断或操作,监听属性是更好的选择。
初始化的时候先执行一次:immediate:true
对象数据深层监听:deep:true
5.12 methods和computed的区别
computed返回结果有缓存, methods没有。当返回结果在dom中多次用到的时候,用computed性能更佳。
6. 过关于指令
6.1 如何自定义指令
全局:main.js
局部:组件内
Vue2自定义指令说明文档
Vue3自定义指令说明文档
vue2vue3指令钩子有所区别
6.2 vue单向绑定
双向绑定:v-model
单向绑定:v-bind,props接收
6.3 v-if 和 v-for 优先级
vue2中v-for的优先级高于v-if
vue3中v-if的优先级高于v-for
不建议在同一节点一起用
7. 关于原理
7.1 $nextTick原理
功能:等待下一次 DOM 更新刷新的工具方法。获取更新后的dom。异步。
$nextTick(callback) {
return Promise.resolve().then(() => {
callback();
})
}
官方说明:当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。nextTick()
可以在状态改变后立即使用,以等待 DOM 更新完成。nextTick()
可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。
7.2 双向绑定原理
通过Object.defineProperty劫持数据发生的改变,如果数据发生了改变(在set进行赋值的),触发update方法进行更新节点内容({{str}}),从而实现数据双向绑定的原理。