# 我的面试题 **Repository Path**: TH_HAN/my-interview ## Basic Information - **Project Name**: 我的面试题 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-03-21 - **Last Updated**: 2022-03-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ■ week1-day1 基本语法 ## 💘 课题 week1-day1 Vue基础(基本语法:简介、模板语法、列表渲染、条件渲染、事件处理) ## 🆕 先学vue3基本语法 vue3 Vue.createApp({data(){},methods:{}}).mount(#app") ## 🌟 说出vue常用的指令 {{}} 插值语法啊,v-html v-text v-bind v-model v-on v-if v-for v-once v-pressive v-cloak ## 🌟 MVVM、MVC面试题 - 谈谈你对MVC的理解 mvc是后端的一种常用的开发思想,通过M模型,V视图,C控制器将程序开发分离化,C控制器负责调度M模型与V视图之间的联动。 - 谈谈你对MVVM理解 MVVM是前端的一种常见开发思想,主要有M模型 V视图 VM构成,M模型负责管理数据,V视图负责展示数据,而VM作为两者的桥梁,通过监控模型数据变化,通知视图进行更新。 - 谈谈MVVM和MVC区别 两者应用的场景不同,前者趋向于前端开发,后者趋向于后端开发,并且MVVM实现了双向通信,无需手动处理因模型数据改变导致的视图变化,或者视图变化引起的模型数据更新,MVC则为单项通信,C控制器来进行调度M与V ## 🌟 说一下v-show、v-if的区别 v-show和v-if都可以控制页面元素的隐藏显示,而v-show控制的是css样式,而v-if控制的是dom。前者仅仅具有重绘意图,而后者则有回流举动。 ## 🆕 判断循环v-if、v-for优先级 在v2中,同一个标签对象身上书写二者,v-if的优先级是小于v-for的,在V3中则相反,v-if的优先级会大于v-for,这样会减少不必要的性能开销。 # ■ week1-day2 特殊语法 ## 💘 课题 week1-day2 Vue基础(特殊语法:表单输入绑定、购物车案例) 无,都在【week1-day6 Vue原理】课件中 # ■ week1-day3 花式思想 ## 💘 课件 week1-day3 Vue基础(花式思想:Class与Style绑定、计算属性、侦听器、过滤器、自定义指令、ref属性、混入) ## 🌛 Class与Style绑定工作有用过吗 用过的,做后台项目时的导航菜单栏啊,还有tab选项卡,页面主题色切换的时候用过。将样式操作代码写入到模型当中,一可以减少视图的代码量,二可以动态控制样式的改变。 ## 🌟 计算属性和侦听器区别、使用场景 计算属性和侦听器最大的区别我认为是前者拥有响应式依赖缓存,而后者却没有,当然了在使用上面也有一定差别,计算属性需要在视图中调用,而侦听器则不需要调用。 计算属性的在需要进行复杂逻辑运算的时候使用,比如项目中的权限树形数据啊,还有分类树形数据等等。 侦听器最大的应用场景就是下拉框的联动问题还有路由变化时面包屑的更新啊,各种input框的模糊搜索,筛选啊,二维码的请求显示啊等等。 ## 🌟 watch监控失效场景&解决方案 当我们侦听的数据类型为对象类型时,那么watch是无法监控到对象内部数据的变化的,我们可以将watch的内置函数deep写入到计算属性内以此达到深度侦听的目的。 ## 🌟 watch两大属性应用场景 deep 一般监控路由变化 根据meta路由元信息更新面包屑 还有分配角色权限 重置树形控件 还有封装的form table组件编辑时需要更新行数据 immediate meta路由元信息首次重置面包屑 获取首次form table组件行数据 ## 🌟 谈谈你对过滤器的理解有没有用过 过滤器简单来说就是把数据给进行过滤的,很类似计算属性,但是在语法上有一定的优势,更加简洁,并且可以同一封装,全局使用。 项目中使用过滤器的场景大部分都是处理一些后端返回状态,比如支付,购买,物流状态,选择状态,因为在计算机的中只有0和1 所以需要我们进行过滤成用户可以一眼认出的数据。 ## 🌟 谈谈你对混入的理解有没有用过 混入其实就是将vue实例中的一些公共的逻辑代码进行封装起来,可以较少代码量,提高可维护性。 我们以前做后台项目的时候用过一些,比如一些删除确认框,成功提示框的封装,还有jump重定向,路由重定向等等。 # ■ week1-day4 组件编程 ## 💘 课件 week1-day4 Vue基础(组件编程:组件化开发思想、组件封装、props、$emit、组件通信、插槽slot、仿写UI组件库、动态组件等) ## 🌟 为啥data要写函数里面返回对象 因为一个组件被复用多次,也就会创建多个实例,如果data是对象数据类型的话,因为对象属于基本引用类型,会导致实例之间的数据相互污染,当我们写成函数的时候,每次我们复用组件的时候,重新调用data函数,他会给我们返回一个全新的数据副本对象。 ## 🌛谈谈你对单向数据流的理解 单向数据流我认为就是子组件里面的数据必须是由父组件或者根组件传递过来的,并且子组件内不可直接修改接收的数据,应该有传递者修改后重新传递给子组件进行使用 ## 🌟 如何实现组件通信? 我们常用的就是prop \$emit \$eventbus 插槽 provide inject v-model $parent $children $refs这些 ## 🌟 事件.native作用 可以解决组件上书写原生事件失效的问题。 ## 🌟 在组件上写原生事件失效解决方案 一般来说如果我们在事件处理过程中没有数据的处理我们是可以写.native修饰符的,不过在项目中还是重写原生事件比较多。 ## 🌟 在组件上使用v-model原理 在组件上使用v-model其实对v-bind和@input进行简写封装了而已。 具体代码为 v-model== v-bind:value=data中的键 @input=data=>data中的键=data ## 🌛 修饰符.sync原理 <组件名 v-bind:属性名.sync="data中的键"> <组件名 v-bind:属性名="data中的键" @update:必须一样的属性名="data => data中的键 = data"> # ■ week1-day5 剩余知识:生命周期、keep-alive等等 ## 💘 课件 week1-day5 Vue基础(剩余知识:虚拟DOM、浏览器运行机制、回流重绘、生命周期、keep-alive、transition过渡 ## 🌟 说出浏览器运行机制 浏览器主进程 负责创建和销毁tab进程,网页文件下载啊,控制网页前进后退一些功能的实现的。 渲染进程,主要是进行页面渲染的,其中渲染进程中几个主要的线程有GUI渲染线程,js引擎线程,事件线程,定时器线程。 GPU进程,负责3d图形绘制的 第三方插件进程,解决一些跨域,还有插件的。 ## 🌟 说出浏览器输入网址干了啥 浏览器输入网址后,浏览器将会带着你的网址去DNS服务器上寻找网址相对应的IP地址,找不到就告诉你网页无法访问,找到了,再根据IP地址加上端口再次访问服务器,然后服务器给你返回数据,通过renderer渲染进程进行解析,其中GUI线程负责解析html css 绘制dom树和css树最后结合成渲染树,然后页面显示。 ## 🌛 说出JS为什么是单线程 js的功能用途主要是实现网页和用户的交互,对DOM的操作,这决定了他只能是单线程,否则会产生很麻烦的同步问题。 ## 🌛 说出JS是单线程 为什么不存在执行效率问题 JS虽然是单线程的,但是他在执行代码的时候会在内存中形成一个执行栈,遇到耗费时间的代码会先交给其他的线程进行处理,等到处理好了再从执行栈中取出执行,从而保证执行效率。 ## 🌟 谈谈你对回流重绘的理解 回流就是元素自身样式发生改变回导致页面布局流的改变 比如元素的宽高啊 边框啊 定位等等 重绘是重绘元素本身的样式改变不会导致页面布局流的改变 比如重绘元素的背景颜色 阴影 字体颜色等等 ## 🌟 哪些属性导致回流、哪些属性导致重绘 回流就是元素的属性改变导致页面的布局流发生了改变,比如当我们修改了元素的宽高啊边框啊都会导致回流。 重绘是重绘元素本身样式发生改变不会导致页面布局流发生改变,比如元素的背景颜色,字体颜色,透明度这些属性都会导致重绘而不会导致回流。 ## 🌟 如何避免或减少回流重绘 避免频繁操作样式 最好一次性书写style属性,避免多次渲染 避免频繁操作DOM 可以创建一个documenFragment 在它上面操作样式属性 然后放到页面上 即虚拟DOM 避免频繁读取会造成回流重绘的属性 如果需要 可以使用变量存储起来 ## 🌟 谈谈你对虚拟DOM的理解 通过js描述真实的DOM 减少回流重绘 ## 🌟 说出VUE有哪些生命周期并说出应用场景 created 发送请求 mounted 发送请求 操作DOM updated 监控数据变化更新DOM,比如聊天框滚至底部啊,订单可视化图表重置等 destroyed 清除非VUE的资源 避免内存泄漏 比如定时器 ## 🌟 created里面可以操作DOM吗 一般来说不可以,反正用如果用ref是不可以的 用原生js可以操作,不过如果非要用ref操作 可以用this.nextTick包起来操作 ## 🌛 watch与created() 哪个先执行? created 先执行 不过watch写了immediate就是watch先执行了 ## 🌟 谈谈你对keep-alive的理解,并说出应用场景 可以将组件数据缓存到内存中,避免频繁卸载挂载产生的额外性能开销。 比如tab选项卡 移动端长列表 还有后台项目环境下的菜单 ## 🌟 谈谈你对$nextTick的理解,并说出应用场景 简单来说就是获取最新DOM 比如我们有一个可隐藏的对话框,里面有二维码数据 或者一些表单选项的获取焦点 获取输入值什么的,当我们控制这个对话框的隐藏状态变化的时候,我们会因为DOM还未渲染完毕二导致我们获取不到DOM,那么这个时候我们就需要用nextTick将这段代码包起来,就可以实现。 ## 🌟 说出$nextTick原理 vue在更新dom时为异步操作,当vue监测到模型数据改变以后后,不会立马去更新dom 而是开启一个异步队列,将操作放进这个队列内,然后等待同一时间循环中的所有事件都处理完才会从队列取出执行,其实就是eventloop的原理,而使用了necttick包住我们需要执行的代码以后,可以在页面更新后再去执行代码从而获取最新DOM # ■ week2-day1 路由相关 ## 💘 课件 week2-day1 Vue进阶(项目准备:路由、重定向、路由模式、路由原理、路由参数、路由传参、嵌套路由、命名视图、导航守卫、路由addRoute) ## 🌛 路由-对象里面的键 {path,component,alias,direction,name,meta} ## 🌟 路由-你说下vue路由模式有几种? 一般来说有两种,一种是hash 一种是history,还一个abstract用于移动端。 ## 🌟 路由-你说下vue路由原理? vue路由的原理就是基于spa单页面应用思想,利用BOM api实现的。 hash 是location.hash进行改变路由 然后window.onhashChange 来监控路由变化 history 是history.pushstate进行改变路由 window.onpopstate 来监控路由变化 ## 🌟 路由-history有什么问题,如何解决? 刷新网页无法加载的问题 我们可以通过服务器配置来结局(和hash的区别 路径带#) ## 🌟 路由-什么是单页面应用SPA优缺点,如何选择 单页面应用就是只有一张web页面的应用,加载一个html应用用来显示数据 优点:用户体验度比较高 不用刷新网页 交互由ajax完成 比较适合前后端开发分离 后端提供接口 前端请求接口 js进行渲染 缺点:首屏加载慢 因为会加载所有的组件和路由内容以及大量的html元素 (解决首屏加载过慢,可以路由懒加载、图片压缩、引用外部cdn、图片懒加载、ui框架按需加载、开启gzip压缩、使用ssr) 不利于seo优化,因为seo优化其实是对html中内容进行检索的,而单页面应用使用js渲染 色哦无法抓取到js中的内容的。 ## 🌟 路由-参数周边种类、方式 query params query配合path params配合name 定义路由加冒号 或者还有一种params配合name 定义路由不加冒号 ## 🌟 路由-谈谈你对编程式导航的理解 编程式导航术语而已,其实就是使用js进行跳转网页。 语法 this.$router.push( { path:'/路径', query: {参数名:值} } ) this.$router.push( { name:'名称', params: {参数名:值} } ) 获取:this.$route.query/params.参数名 ## 🌟 路由-说出嵌套路由&命名视图的场景 嵌套路由一般来说在后台项目的两栏布局中使用的比较多左侧菜单右侧主体区域,因为主体区域内的组件需要动态变化,而主体区域是不需要一直变化的,所以我们可以使用嵌套路由,将需要变化的组件对应路由写进主体区域路由内,实现路由嵌套 具体实现:我们在定义路由时写上children 然后在children里面在写我们需要定义的子路由信息就可以了,一级路由会在app.vue直接显示,而二级路由会在一级路由的内部显示。 命名视图可以封装一些公用的头部底部组件,比如移动端的navbar tabbar什么的,然后通过定义路由时添加name属性,可以将指定组件直接添加到对应路由的组件中,不需要来回导入导出,比较方便。 具体实现:我们首先将公共组件封装好,然后再我们路由页面导入我们需要的公共组件,然后定义路由时,将component改成components 变成一个对象形式,然后在里面添加我们导入的相应的组件就可以了。 ## 🌟 路由-全局导航守卫登陆鉴权 判断用户是否登录 我们可以在全局导航守卫里面设置一个白名单 如果访问路径在这个名单里面我们就直接next 如果不在 我们进行权限判断 即token的存在与否 存在的话登陆成功 不存在的话 next()跳转至登录页。 ## 🌟 路由-导航守卫种类&作用 全局导航守卫 还有 组件导航守卫 全局导航守卫里面常用的有 beforeEach beforeAfter beforeResolve 组件导航守卫里面有 beforeRouterEnter beforeRouterUpdated beforeRouterLeave 还有一个不常用的那个afterEach 具体作用有点忘了 ## 🌛 路由-导航守卫执行顺序 beforeRouterLeave beforeEach beforeRouterUpdate beforeEnter beforeRouterEnter beforeResolve afterEach ## 🌟 路由-动态路由如何实现 首先我做的项目都是后端路由,因为不同的角色访问的菜单列表是不一样的,我们可以 先在api中定义接口导出, 然后在vuex中的角色文件中的actions中定义函数去调接口,去获取路由数据, 而我们调用的时候需要在全局导航守卫beforeEach中去判断token 即用户是否登录, 如果登陆了 且菜单没有数据,我们就需要去调用vuex中的actions中函数, 他会触发mutations中的我们定义的addrouter函数 去动态添加路由以及视图的菜单显示。 , ## 🌟 路由-元信息有啥用 meta 中可以存放面包屑数据 也可以加标识控制是否缓存组件 ## 🌛 路由-过渡特效场景 transition # ■ week2-day2 脚手架相关 ## 💘 课件 week2-day2 Vue进阶(项目准备:脚手架、ToDoList案例、组件封装、全局组件、Vue.config.js配置) ## 🌟 说出框架中做了哪些配置vue.config.js 解决跨域的配置啊,还有一些别名啊 但是跨域问题上线以后还是需要解决的 nginx反向代理解决 ## 🌟 说出跨域的解决方案 一般来说,我们在开发环境下用的最多的是前端代理,当然了,谷歌命令和谷歌插件啊同样可以解决。 而到了生产环境,都是由后端,测试他们使用Nginx反向代理进行解决的。 ## 🌟 说出Vue.use原理 vue.use 主要用来在框架开发中注册全局插件 比如注册全局的组件 倒入全局的js文件 # ■ week2-day3 UI组件库 ## 💘 课件 week2-day3 Vue进阶am(项目准备:UI组件库ElemenUI、IView、AntdV、Vant、Mint等、自研UI组件库) ## 🌛 说出UI组件库/UI框架原理 # ■ week2-day4/5 Vue千锋🤝美团项目布局 ## 🌟 项目开发中有没有封装过组件 封装过组件啊 ## 🌟 项目中封装了哪些组件 做后台项目的时候封装了一些全局组件 比如表格 表单 dailog 还有一些页面组件 用户编辑啊 权限菜单啊 树形控件等等 ## 🌟 组件如何封装的 全局组件在src目录下的components下面创建,实现功能 然后组件通信技术实现组件的数据传递 然后在main.js中注册就可以直接全局使用了 而对于页面组件来说,我们可以在views下面的文件夹内,创建组件文件,同样是在文件内实现功能,然后props接收数据,然后页面中需要导入使用就可以了 ## 🌟 样式相关 我们可以使用scoped 来防止样式污染 使用sass语法可以让我们进行选择器嵌套 另外的话 对于一些开启样式私有化的元素我们可以使用::v-deep 或者/deep/ 解决 如果是css 环境下 我们也可以使用 >>>解决 ## 🌟 用户角色权限三者是如何关联的 首先我们在权限页面可以进行添加删除,实现后端路由 接着可以添加删除角色 然后给角色分配权限 最后我们创建用户的时候给用户分配角色 这样我们后期就可以判断用户的不同角色来实现动态路由显示不同页面。 week1-day6 Vue原理 💘 课题 week1-day6 Vue原理(语法原理:v-model语法原理、响应式原理、Vue源码分析、自定义Vue库) 🌟 说一下v-model原理 v-model其实就是基于:value 和@input封装的语法糖 🌟 VUE2响应式原理(中级) vue2 在初始化数据的时候,会使用Object.defineProperty 对data中的所有属性进行数据劫持,如果属性发生变化就会通知更新操作 🌟 VUE2响应式原理(高级 vue2 在初始化数据的时候,底层会使用Object.defineProperty对data中的所有属性进行数据劫持,然后通过发布订阅通知视图更新 🌟 VUE2响应式数据无法劫持原因、和解决方案 🌟 $forceUpdate 原理 这个以前大概看过源码,好像就是底层notify强制视图所有数据全部更新了一次好像。 🌟 $set 原理 $set 其实就是vue的一个原型方法,原理的话是底层通过defineReactive进行数据劫持,然后notify进行视图更新。 🌛 $delete 原理 🌟 Vue.set/delete 原理 🆕 响应式原理 2109班面试追问 ``` 问1:created、和mounted区别 答1:created不可以dom操作 问2:真的不可以吗 答2:可以通过 this.$nextTick() 问3:父子组件嵌套、生命周期执行顺序 created、mounted 答2:大方向 父created、子created、子mounted、父mounted