html-CSS

练习题 - 图1

js基础

ES6

vue

1、说说你对 SPA 单页面的理解,它的优缺点分别是什么?

关键点 SPA SEO 优缺点 回答逻辑

  1. 什么是SPA
  2. 优点
    1. 用户体验好-不用跳转重载页面
    2. 服务器压力小-减少了重复的数据传输
    3. 前后端职责分离、架构清晰
  3. 缺点
    1. 初次加载需要将js、CSS统一加载
    2. 页面切换需要自己建立堆栈管理
    3. 内容是动态替换的,SEO难度较大(不便于搜索引擎检索)

扩展

  1. 出处-
  2. vue-router

2、v-show 与 v-if 有什么区别?

关键点 是否修改dom display 回答逻辑

  1. v-if:条件为真时,渲染条件块,通过操作虚拟dom来间接的操作真实dom
  2. v-show:元素总会被渲染,但因display属性,而展示或不展示
  3. 各自适用的场景:
    1. 需要频繁切换条件的场景,使用v-show
    2. v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;

扩展

  1. 出处看第一个的扩展

3、Class 与 Style 如何动态绑定?

关键点 回答逻辑

  1. 都可以通过对象语法和数组语法进行动态绑定

扩展

  1. 30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度) - 掘金

4、怎样理解 Vue 的单向数据流?111

关键点 prop 父子组件通信 回答逻辑

  1. 什么是单向数据流
  2. 此情况下,子组件如何修改父组件的数据

扩展

  1. 出处



5、computed 和 watch 的区别和运用的场景?

关键点 computed watch 运用场景 回答逻辑

  1. 计算属性能做的watch都能做到
  2. 但watch能执行异步操作

扩展

  1. 出处-

  2. 简明

  1. 有代码

6、直接给一个数组项赋值,Vue 能检测到变化吗?

关键点 不能 引用类型 由于 JavaScript 的限制,Vue 不能检测到以下数组的变动:

  • 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:vm.items.length = newLength

回答逻辑

  1. 解决方法:使用set或者splice
  1. // Vue.set
  2. Vue.set(vm.items, indexOfItem, newValue)
  3. // vm.$set,Vue.set的一个别名
  4. vm.$set(vm.items, indexOfItem, newValue)
  5. // Array.prototype.splice
  6. vm.items.splice(indexOfItem, 1, newValue)
  1. // Array.prototype.splice
  2. vm.items.splice(newLength)

扩展



7、谈谈你对 Vue 生命周期的理解?111

关键点 生命周期4-8 回答逻辑

  1. 定义:Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
  2. 比较重要的mount 和 destroy这两个阶段

扩展


  1. 表格
生命周期 描述
beforeCreate 组件实例被创建之初,组件的属性生效之前
created 组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用
beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用
mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
beforeUpdate 组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
update 组件数据更新之后
activited keep-alive 专属,组件被激活时调用
deactivated keep-alive 专属,组件被销毁时调用
beforeDestory 组件销毁前调用
destoryed 组件销毁后调用
  1. 流程图

练习题 - 图2


8、Vue 的父组件和子组件生命周期钩子函数执行顺序?

关键点 子先父后 回答逻辑

  1. image.png

扩展



9、在哪个生命周期内调用异步请求?

关键点 created beforeMount mounted 回答逻辑

  1. image.png

扩展


10、在什么阶段才能访问操作DOM?

关键点 看生命周期流程图! 回答逻辑

  1. 在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。

扩展


11、父组件可以监听到子组件的生命周期吗?

关键点 父子组件通信 生命周期钩子 回答逻辑

  1. 2个方式
  1. // Parent.vue
  2. <Child @mounted="doSomething"/>
  3. // Child.vue
  4. mounted() {
  5. this.$emit("mounted");
  6. }
  1. // Parent.vue
  2. <Child @hook:mounted="doSomething" ></Child>
  3. doSomething() {
  4. console.log('父组件监听到 mounted 钩子函数 ...');
  5. },
  6. // Child.vue
  7. mounted(){
  8. console.log('子组件触发 mounted 钩子函数 ...');
  9. },
  10. // 以上输出顺序为:
  11. // 子组件触发 mounted 钩子函数 ...
  12. // 父组件监听到 mounted 钩子函数 ...

当然 @hook 方法不仅仅是可以监听 mounted,其它的生命周期事件,例如:created,updated 等都可以监听。

扩展

有源码解释。


12、谈谈你对 keep-alive 的了解?

关键点 保留状态 exclude比include优先级高 回答逻辑 image.pngimage.png


扩展


13、组件中 data 为什么是一个函数?

为什么组件中的 data 必须是一个函数,然后 return 一个对象,而 new Vue 实例里,data 可以直接是一个对象?

关键点 `` 回答逻辑

  1. 因为组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值会相互影响,如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。
  1. // data
  2. data() {
  3. return {
  4. message: "子组件",
  5. childName:this.name
  6. }
  7. }
  8. // new Vue
  9. new Vue({
  10. el: '#app',
  11. router,
  12. template: '<App/>',
  13. components: {App}
  14. })

扩展


14、v-model 的原理?

关键点 双向绑定 表单元素 image.png 回答逻辑


  1. <input v-model='something'>
  2. 相当于
  3. <input v-bind:value="something" v-on:input="something = $event.target.value">
  • 如果在自定义组件中,v-model 默认会利用名为 value 的 prop 和名为 input 的事件 ```javascript 父组件:

子组件:

{{value}}

props:{ value: String }, methods: { test1(){ this.$emit(‘input’, ‘小红’) }, },

  1. > **扩展**
  2. ---
  3. <a name="PBLd7"></a>
  4. ### 15、Vue 组件间通信有哪几种方式?
  5. > **关键点 **``
  6. > **回答逻辑**
  7. > Vue 组件间通信是面试常考的知识点之一,这题有点类似于开放题,你回答出越多方法当然越加分,表明你对 Vue 掌握的越熟练。Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,下面我们分别介绍每种通信方式且会说明此种方法可适用于哪类组件间通信。
  8. > 1. **props / $emit 适用 父子组件通信**
  9. >
  10. 这种方法是 Vue 组件的基础,相信大部分同学耳闻能详,所以此处就不举例展开介绍。
  11. > 2. **ref $parent / $children 适用 父子组件通信**![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662206705271-f27e23d8-cd18-4ec0-aa05-39e6b97c8964.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=91&id=u9b2d0075&margin=%5Bobject%20Object%5D&name=image.png&originHeight=137&originWidth=1163&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27681&status=done&style=shadow&taskId=uc5dbb1d6-0874-4fe0-ad04-fb3cb11c67c&title=&width=775.3333333333334)
  12. > 3. **EventBus $emit / $on 适用于 父子、隔代、兄弟组件通信**
  13. >
  14. 这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。
  15. > 4. **$attrs/$listeners 适用于 隔代组件通信**![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662206731756-13455a9f-6c6a-49d9-9b5d-fd6ae144b5c0.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=161&id=u9e939253&margin=%5Bobject%20Object%5D&name=image.png&originHeight=242&originWidth=1127&originalType=binary&ratio=1&rotation=0&showTitle=false&size=78272&status=done&style=shadow&taskId=u829bb434-3d99-46aa-99df-4f6a0418316&title=&width=751.3333333333334)
  16. > 5. **provide / inject 适用于 隔代组件通信**
  17. >
  18. 祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。 provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
  19. > 6. **Vuex 适用于 父子、隔代、兄弟组件通信**![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662206785436-0187067b-bbf8-4168-89a7-ae704a644406.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=193&id=u4b577e2a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=290&originWidth=1147&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93566&status=done&style=shadow&taskId=u8e0f8d64-84b6-4a1f-b2d2-8848125578c&title=&width=764.6666666666666)
  20. >
  21. **扩展**
  22. ---
  23. <a name="F8lC1"></a>
  24. ### 16、你使用过 Vuex 吗?
  25. > **关键点 **`介绍什么是vuex` `状态管理` `如何使用` `何时使用` `没code`
  26. > **回答逻辑**
  27. > ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662209025710-99f9d83c-1186-4adb-adba-faf3d36e9f1f.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=212&id=u6ac0c37c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=318&originWidth=1149&originalType=binary&ratio=1&rotation=0&showTitle=false&size=97595&status=done&style=shadow&taskId=u793c7b21-5809-4a49-a15b-40b756532a2&title=&width=766)
  28. > ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662209009011-e7740402-140f-492b-b5c7-72b819d12d47.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=225&id=u36a4d6fc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=337&originWidth=1144&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93988&status=done&style=shadow&taskId=ubd0a3e3c-d99c-4485-9684-eb23323f71d&title=&width=762.6666666666666)
  29. > **扩展**
  30. > ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662209363586-4a8a3dd8-6252-43de-be1d-3baf236250b3.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=252&id=u66142433&margin=%5Bobject%20Object%5D&name=image.png&originHeight=378&originWidth=257&originalType=binary&ratio=1&rotation=0&showTitle=false&size=20329&status=done&style=shadow&taskId=uc64921e4-f791-42ba-bca6-b2258f2dec9&title=&width=171.33333333333334)
  31. ---
  32. <a name="ii5qT"></a>
  33. ### 17、使用过 Vue SSR 吗?说说 SSR?
  34. > **关键点 **`服务端渲染` `优缺点`
  35. > **回答逻辑**
  36. > ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662257795369-44cb6058-84b4-46a0-b223-8a7d65525869.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=170&id=u5ab20a95&margin=%5Bobject%20Object%5D&name=image.png&originHeight=255&originWidth=1170&originalType=binary&ratio=1&rotation=0&showTitle=false&size=99465&status=done&style=shadow&taskId=ua7f7cf1c-f4c6-4980-a5ba-11b749562c0&title=&width=780)![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662257815136-cbb0e39a-2e17-4ce5-9d2f-fc7e093864a2.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=437&id=u7fbe9d5a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=656&originWidth=1148&originalType=binary&ratio=1&rotation=0&showTitle=false&size=256592&status=done&style=shadow&taskId=uc3ce1f01-b4bc-4e73-82c2-1e97093afa7&title=&width=765.3333333333334)
  37. > 1. <br />
  38. >
  39. **扩展**
  40. > demo项目
  41. ---
  42. <a name="tn20u"></a>
  43. ### 18、vue-router 路由模式有几种?
  44. > **关键点 **`**hash**`** **`**history**` `abstract`
  45. > **回答逻辑**
  46. > 1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/1304571/1662258018760-4794f997-2ae1-43b1-913e-e7fa1707ba54.png#clientId=u80bc0ad9-6350-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=166&id=uec91326c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=249&originWidth=1144&originalType=binary&ratio=1&rotation=0&showTitle=false&size=62702&status=done&style=shadow&taskId=u0c801762-6887-4148-8abd-72b76d74189&title=&width=762.6666666666666)
  47. ```javascript
  48. switch (mode) {
  49. case 'history':
  50. this.history = new HTML5History(this, options.base)
  51. break
  52. case 'hash':
  53. this.history = new HashHistory(this, options.base, this.fallback)
  54. break
  55. case 'abstract':
  56. this.history = new AbstractHistory(this, options.base)
  57. break
  58. default:
  59. if (process.env.NODE_ENV !== 'production') {
  60. assert(false, `invalid mode: ${mode}`)
  61. }
  62. }

扩展


19、能说下 vue-router 中常用的 hash 和 history 路由模式实现原理吗?

关键点 HTML5 回答逻辑

  1. hash模式的实现原理
    1. 早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。比如下面这个网站,它的 location.hash 的值为 '#search':https://www.word.com#search
    2. image.png
  2. history模式的实现原理(栈管理)
    1. HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState()history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,如下所示:
  1. window.history.pushState(null, null, path);
  2. window.history.replaceState(null, null, path);
  1. image.png

扩展


20、什么是 MVVM?

关键点 `` 回答逻辑

  1. View 层-View 是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建 。
  1. <div id="app">
  2. <p>{{message}}</p>
  3. <button v-on:click="showMessage()">Click me</button>
  4. </div>
  1. Model 层-Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端提供的 api 接口。
  1. {
  2. "url": "/your/server/data/api",
  3. "res": {
  4. "success": true,
  5. "name": "IoveC",
  6. "domain": "www.cnblogs.com"
  7. }
  8. }
  1. ViewModel 层

image.png

  1. var app = new Vue({
  2. el: '#app',
  3. data: { // 用于描述视图状态
  4. message: 'Hello Vue!',
  5. },
  6. methods: { // 用于描述视图行为
  7. showMessage(){
  8. let vm = this;
  9. alert(vm.message);
  10. }
  11. },
  12. created(){
  13. let vm = this;
  14. // Ajax 获取 Model 层的数据
  15. ajax({
  16. url: '/your/server/data/api',
  17. success(res){
  18. vm.message = res;
  19. }
  20. });
  21. }
  22. })

扩展


21、Vue 是如何实现数据双向绑定的?111

关键点 `` 回答逻辑

  1. Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据
  2. View 变化更新 Data ,可以通过事件监听的方式来实现,所以 Vue 的数据双向绑定的工作主要是如何根据 Data 变化更新 View。

image.png 扩展


22、Vue 框架怎么实现对象和数组的监听?111

关键点 `` 回答逻辑

  1. 通过 Object.defineProperty() 对数据进行劫持,但是 Object.defineProperty() 只能对属性进行数据劫持,不能对整个对象进行劫持,同理无法对数组进行劫持
  2. Vue 能检测到对象和数组(部分方法的操作)的变化,那它是怎么实现的呢?
  1. /**
  2. * Observe a list of Array items.
  3. */
  4. observeArray (items: Array<any>) {
  5. for (let i = 0, l = items.length; i < l; i++) {
  6. observe(items[i]) // observe 功能为监测数据的变化
  7. }
  8. }
  9. /**
  10. * 对属性进行递归遍历
  11. */
  12. let childOb = !shallow && observe(val) // observe 功能为监测数据的变化

通过以上 Vue 源码部分查看,我们就能知道 Vue 框架是通过遍历数组 和递归遍历对象,从而达到利用 Object.defineProperty() 也能对对象和数组(部分方法的操作)进行监听。

扩展


23、Proxy 与 Object.defineProperty 优劣对比

关键点 `` 回答逻辑

  1. proxy的优势
  • Proxy 可以直接监听对象而非属性;
  • Proxy 可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  • Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
  1. Object.defineProperty 的优势如下:
  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

扩展


24、Vue 怎么用 vm.$set() 解决对象新增属性不能响应的问题 ?

关键点 `` 回答逻辑 image.png

  1. export function set (target: Array<any> | Object, key: any, val: any): any {
  2. // target 为数组
  3. if (Array.isArray(target) && isValidArrayIndex(key)) {
  4. // 修改数组的长度, 避免索引>数组长度导致splcie()执行有误
  5. target.length = Math.max(target.length, key)
  6. // 利用数组的splice变异方法触发响应式
  7. target.splice(key, 1, val)
  8. return val
  9. }
  10. // key 已经存在,直接修改属性值
  11. if (key in target && !(key in Object.prototype)) {
  12. target[key] = val
  13. return val
  14. }
  15. const ob = (target: any).__ob__
  16. // target 本身就不是响应式数据, 直接赋值
  17. if (!ob) {
  18. target[key] = val
  19. return val
  20. }
  21. // 对属性进行响应式处理
  22. defineReactive(ob.value, key, val)
  23. ob.dep.notify()
  24. return val
  25. }

image.png

扩展


25、虚拟 DOM 的优缺点?以及 26、虚拟 DOM 实现原理?

关键点 `` 回答逻辑

  1. 优点:
  • 保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;
  • 无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;
  • 跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。
  1. 缺点:
  • 无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。
  1. 虚拟 DOM 的实现原理主要包括以下 3 部分:
  • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
  • diff 算法 — 比较两棵虚拟 DOM 树的差异;
  • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

扩展


27、Vue 中的 key 有什么作用?

关键点 `` 回答逻辑


扩展


8、Vue 的父组件和子组件生命周期钩子函数执行顺序?

关键点 `` 回答逻辑


扩展


8、Vue 的父组件和子组件生命周期钩子函数执行顺序?

关键点 `` 回答逻辑


扩展


8、Vue 的父组件和子组件生命周期钩子函数执行顺序?

关键点 `` 回答逻辑


扩展


8、Vue 的父组件和子组件生命周期钩子函数执行顺序?

关键点 `` 回答逻辑


扩展


8、Vue 的父组件和子组件生命周期钩子函数执行顺序?

关键点 `` 回答逻辑


扩展

浏览器和计算机网络

手写题和算法题

性能优化