前端面试宝典七(vue篇)
1、 MVC、MVVM的理解
MVC:Model、View、Controller
- View 传送指令到 Controller
- Controller 完成业务逻辑后,要求 Model 改变状态
- Model 将新的数据发送到 View,用户得到反馈
- 所有通信都是单向的
MVVM:Model、View、ViewModel
- 各部分之间的通信,都是双向的
- 采用双向绑定:View 的变动,自动反映在 ViewModel,反之亦然
2、Vue的双向绑定数据的原理
vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调
3、单向数据流和双向数据绑定
单向数据流: 顾名思义,数据流是单向的。数据流动方向可以跟踪,流动单一,追查问题的时候可以更快捷。缺点就是写起来不太方便。要使UI发生变更就必须创建各种 action 来维护对应的 state
双向数据绑定:数据之间是相通的,将数据变更的操作隐藏在框架内部。优点是在表单交互较多的场景下,会简化大量与业务无关的代码。缺点就是无法追踪局部状态的变化,增加了出错时 debug 的难度
4、组件通信
(1)父子、兄弟通信
父组件向子组件通信:子组件通过 props 属性,绑定父组件数据,实现双方通信
子组件向父组件通信:将父组件的事件在子组件中通过 $emit 触发
非父子组件、兄弟组件之间的数据传递:公共参数放在最小公约父组件,通过父组件下发给相邻兄弟组件
(2)eventbus
就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件
(3)vuex状态管理
5、v-model实现原理
v-model其实也就是语法糖,本质上是 :value和v-on的结合体,父组件隐式传入value参数,并监听input事件,子组件在值改变时隐式触发父组件的input事件
6、key的作用
key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
7、computed、watch、methods的区别和应用场景
computed计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。这个功能非常强大,它可以让你的代码更加声明式、数据驱动并且易于维护。
watch监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。就好在div写一个表达式name,data里写入num和lastname,firstname,在watch里当num的值发生变化时,就会调用num的方法,方法里面的形参对应的是num的新值和旧值,而计算属性computed,计算的是Name依赖的值,它不能计算在data中已经定义过的变量。
methods方法,函数,绑定事件调用;不会使用缓存
8、$nextTick
vue实现响应式并不是数据发生变化后dom立即变化,而是按照一定的策略来进行dom更新。
$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
9、keep-alive
<keep-alive></keep-alive>包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
10、自定义指令
在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
11、混入mixin
1)混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项
2)当组件和混入对象含有同名选项时,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
3)同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
4)值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
5)混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例
12、递归组件和组件之间的循环引用
递归组件:组件是可以在它们自己的模板中调用自身的。不过它们只能通过组件的 name 来调用
组件之间的循环引用:组件在渲染树中互为对方的后代和祖先,产生一个悖论。
解决:(1)通过 Vue.component 全局注册组件,再调用
(2)在本地注册组件的时候,你可以使用 webpack 的异步 import
components: { TreeFolderContents: () => import('./tree-folder-contents.vue') }
13、监听子组件的生命周期
1)父组件调用子组件时添加自定义事件,子组件生命周期中$emit触发父组件中添加的自定义事件
//父组件 <vm-child :value="40" @childMounted="childMountedHandle" /> // 子组件 mounted () { this.$emit('childMounted') }
2)采用hook
//父组件 <vm-child :value="40" @hook:mounted="childMountedHandle" />
子组件不用做任何处理
14、依赖注入
vue允许通过this. $parent获取父组件实例,通过this.$refs.childRef获取子组件实例。当使用 $parent 无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provide 和 inject
provide选项 允许我们指定我们想要提供给后代组件的数据/方法。
provide() { return { getMap: this.getMap } }
在任何后代组件里,我们都可以使用 inject选项 来接收指定的我们想要添加在这个实例上的 property:
inject: ['getMap']
15、vue 等单页面应用的优缺点
优点:
良好的交互体验
良好的前后端工作分离模式
减轻服务器压力
缺点:
SEO难度较高
前进、后退管理
初次加载耗时多
16、vue组件生命周期和使用
beforeCreate和created(虚拟dom创建);
beforeMount、 mounted (挂载到页面节点)
beforeUpdate、updated、 (组件数据变化触发)
beforeDestroy、destroyed (组件销毁)
(activated与deactivated只有keep-live虚拟组件中的实例会触发)
17、vue项目怎么作权限校验
- 1)接口权限控制
登陆后返回token,请求时携带到后台验证,验证通过则正常返回;否则则跳转登录
- 2)页面权限控制
(1)初始化挂在全部路由,每次跳转前做校验
(2)只挂载当前用户拥有权限的路由,如果用户通过url强制访问,则会进入404.从源头上做控制
- 3)页面按钮等权限控制
通过vue提供的自定义指令,实现按钮权限控制
18、vuex有哪几种属性
- state:vuex的基本数据,用来存储变量
- geeter:从基本数据(state)派生的数据,相当于state的计算属性
- mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
- action:和mutation的功能大致相同,不同之处在于 ==> 1)Action 提交的是 mutation,而不是直接变更状态。 2)Action 可以包含任意异步操作。
- modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
19、Vuex中actions和mutations的区别
Mutation 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。 .
20、在模块中,getter和mutation和action中怎么访问全局的state和getter?
在getter中可以通过第三个参数rootState访问到全局的state,可以通过第四个参数rootGetters访问到全局的getter。
在mutation中不可以访问全局的satat和getter,只能访问到局部的state。
在action中第一个参数context中的context.rootState访问到全局的state,context.rootGetters访问到全局的getter。
21、在v-model上怎么用Vuex中state的值
需要通过computed计算属性来转换。 <input v-model="message"> // ... computed: { message: { get () { return this.$store.state.message }, set (value) { this.$store.commit('updateMessage', value) } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!