进阶中级前端必备知识点(三)

简介: 进阶中级前端必备知识点(三)

36、this关键字

this指向直接调用者,而非间接调用者


普通函数中的this:


在Vue所有的生命周期钩子方法(如created,mounted, updated以及destroyed)里 使用this,this指向调用它的Vue实例,即(new Vue)。


箭头函数中的this


箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window; 箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this

37、Vue生命周期

vue生命周期即为一个组件从出生到死亡的一个完整周期,主要包括以下4个阶段:创建,挂载,更新,销毁


创建前:beforeCreate, 创建后:created(有data,无$el)


挂载前:beforeMount, 挂载后:mounted(有data,有$el)


更新前:beforeUpdate, 更新后:updated


销毁前:beforeDestroy, 销毁后:destroyed


新增了使用内置组件 keep-alive 来缓存实例,而不是频繁创建和销毁(开销大)


actived 实例激活(该钩子在服务器端渲染期间不被调用。)


deactived 实例失效 (该钩子在服务器端渲染期间不被调用。

38、Vue-router路由?路由守卫?vue路由懒加载?replace和push的区别?

前端路由实现原理主要通过以下两种技术实现的

第一种:利用H5的history API实现


主要通过history.pushState 和 history.replaceState来实现,不同之处在于,pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录[发布项目时,需要配置下apache]


第二种:利用url的hash实现


我们经常在 url 中看到 #,这个 # 有两种情况,一个是我们所谓的锚点,路由里的 # 不叫锚点,我们称之为 hash,我们说的就是hash,主要利用监听哈希值的变化来触发事件 —— hashchange 事件来做页面局部更新


第三种:abstract模式


适用于所有JavaScript环境,例如服务器端使用Node.js。如果没有浏览器API,路由器将自动被强制进入此模式。


总结:hash 方案兼容性好,而H5的history主要针对高级浏览器。

路由守卫:

第一种:全局路由钩子

beforeEach(to,from,next) { }

第二种:路由独享的钩子

beforeEnter(to,from,next) {}

第三种:组件内的钩子

beforeRouteEnter(to,from,next) {}
    beforeRouteUpdate(to,from,next) {}
    beforeRouteLeave(to,from,next) {}

适用场景:动态设置页面标题,判断用户登录权限等

vue路由懒加载

vue路由懒加载主要解决打包后文件过大的问题,事件触发才加载对应组件中的js

replace和push的区别

this.$router.replace方法,不计入history记录,this.$router.push计入历史

39、双向绑定的原理

利用ES5中的Object.defineProperty结合观察者模式实现的,然后利用里面的getter和setter来实现双向数据绑定的、发布订阅模式,数据劫持


首先要对数据进行劫持监听,设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令(如v-model,v-on)对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。

40、Vue异步队列?nextTick是什么?适用场景?

异步更新队列:Vue在观察到数据变化时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发生的所以数据改变。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。然后,在下一个事件循环tick中,Vue刷新队列并执行实际(已去重的)工作。


因为Vue的异步更新队列,$nextTick是用来知道什么时候DOM更新完成的


vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick就可以获取数据更新后最新DOM的变化


适用场景:


第一种:有时需要根据数据动态的为页面某些dom元素添加事件,这就要求在dom元素渲染完毕时去设置,但是created与mounted函数执行时一般dom并没有渲染完毕,所以就会出现获取不到,添加不了事件的问题,这回就要用到nextTick处理


第二种:在使用某个第三方插件时 ,希望在vue生成的某些dom动态发生变化时重新应用该插件,也会用到该方法,这时候就需要在 $nextTick 的回调函数中执行重新应用插件的方法,例如:应用滚动插件better-scroll时


第三种:数据改变后获取焦点

41、vue核心是什么? vue和jquey的区别?vue与React

vue最大特点我感觉就是“组件化“和”数据驱动“


组件化就是可以将页面和页面中可复用的元素都看做成组件,写页面的过程,就是写组件,然后页面是由这些组件“拼接“起来的组件树


数据驱动就是让我们只关注数据层,只要数据变化,页面(即视图层)会自动更新,至于如何操作dom,完全交由vue去完成,咱们只关注数据,数据变了,页面自动同步变化了,很方便


jquery主要是玩dom操作的“神器“,强大的选择器,封装了好多好用的dom操作方法和如何获取ajax方法 例如:$.ajax()非常好用


vue:主要用于数据驱动和组件化,很少操作dom,当然vue可能通过ref来选择一个dom或组件


vue与react:


相同点:数据驱动视图、组件化、都使用 Virtual DOM


不同点:核心思想不同、组件写法差异、diff算法不同、响应式原理不同

42、vue3.x新特性?

特性:引入Tree-shaking,多出setup生命周期、响应式API、响应式侦听、Composition API(组合API)、Fragment、Teleport、Suspense等

43、Vue常用的修饰符

v-on 指令常用修饰符:


.stop - 调用 event.stopPropagation(),禁止事件冒泡。


.prevent - 调用 event.preventDefault(),阻止事件默认行为。


.capture - 添加事件侦听器时使用 capture 模式。


.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。


.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。


.native - 监听组件根元素的原生事件。


.once - 只触发一次回调。


.left - (2.2.0) 只当点击鼠标左键时触发。


.right - (2.2.0) 只当点击鼠标右键时触发。


.middle - (2.2.0) 只当点击鼠标中键时触发。


.passive - (2.3.0) 以 { passive: true } 模式添加侦听器


v-bind 指令常用修饰符:


.prop - 被用于绑定 DOM 属性 (property)。(差别在哪里?)


.camel - (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持)


.sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。


v-model 指令常用修饰符:


.lazy - 取代 input 监听 change 事件


.number - 输入字符串转为数字


.trim - 输入首尾空格过滤

44、v-for与v-show的区? v-for与v-if优先级

v-if和v-show都可以显示和隐藏一个元素,但有本质区别


v-if是惰性的,只是值为false就不会加载对应元素,为true才动态加载对应元素


v-show:是无论为true和为false都会加载对应html代码,但为false时用display:none隐藏不在页面显示,但为true时页面上用display:block显示其效果


适用场景:切换频繁的场合用v-show,切换不频繁的场合用v-if


v-for的优先级比v-if更高,这意味着 v-if将分别重复运行于每个 v-for循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,vue3.x则v-if优先级更高

45、虚拟dom是什么,有什么用

提前使用js的方式表示出dom结构树来.存储在内存里面.同样的循环.只会最终合并执行一次,大大的提高了性能.(这个地方有点儿像js中的createElementFragment文档碎片)


而在对比的过程中.通过diff算法进行比较差异.这个比较在我理解而言就是同层比较.降低了时间复杂度空间复杂度一些什么玩意儿.最终把差异同步到真实dom上去.这就是我理解的虚拟dom


在传统的jq中,操作的都是真实的DOM,.而一个真实dom的渲染过程,要经过渲染引擎构建DOM树.构建样式表.组建成render(渲染)树,的过程,要经过不断的重绘回流才能够展示给用户.


那么在直接js操作dom的过程中,比方说一个循环10次插入dom元素,其实每一次都会经历上面的过程…经历大量的重绘回流.代价特别大.性能低下.所以出现了虚拟dom

46、diff算法

diff 算法是一种通过同层的树节点进行比较的高效算法


其有两个特点:


比较只会在同层级进行, 不会跨层级比较


在diff比较的过程中,循环从两边向中间比较


diff 算法在很多场景下都有应用,在 vue 中,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较


原理:当数据发生改变时,set方法会调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图

47、vue组件通讯(即传值)有哪些

第一种:父传子:主要通过props来实现的


具体实现:父组件通过import引入子组件,并注册,在子组件标签上添加要传递的属性,子组件通过props接收,接收有两种形式一是通过数组形式[‘要接收的属性’ ],二是通过对象形式{ }来接收,对象形式可以设置要传递的数据类型和默认值,而数组只是简单的接收


第二种:子传父:主要通过$emit来实现


具体实现:子组件通过通过绑定事件触发函数,在其中设置this.$emit(‘要派发的自定义事件’,要传递的值),$emit中有两个参数一是要派发的自定义事件,第二个参数是要传递的值


然后父组件中,在这个子组件身上@派发的自定义事件,绑定事件触发的methods中的方法接受的默认值,就是传递过来的参数


第三种:兄弟之间传值有两种方法:


方法一:通过event bus实现


具体实现:创建一个空的vue并暴露出去,这个作为公共的bus,即当作两个组件的桥梁,在两个兄弟组件中分别引入刚才创建的bus,在组件A中通过bus.$emit(’自定义事件名’,要发送的值)发送数据,在组件B中通过bus.$on(‘自定义事件名‘,function(v) { //v即为要接收的值 })接收数据


方法二:通过vuex实现


具体实现:vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括state,actions,mutations,getters和modules 5个要素,主要流程:组件通过dispatch到 actions,actions是异步操作,再actions中通过commit到mutations,mutations再通过逻辑操作改变state,从而同步到组件,更新其数据状态


方法三:使用全局的变量传递


在windons或document上声明或绑定数据,取值

48、vue中methods,computed,watch的区别?

computed是多对一的关系,而watch则是一对多的关系;


methods中都是封装好的函数,无论是否有变化只要触发就会执行


computed:是vue独有的特性计算属性,可以对data中的依赖项再重新计算,得到一个新值,应用到视图中,和methods本质区别是computed是可缓存的,也就是说computed中的依赖项没有变化,则computed中的值就不会重新计算,而methods中的函数是没有缓存的。Watch是监听data和计算属性中的新旧变化。

49、vue中,怎么设置局部样式?原理?样式穿透?

css没有局部样式的概念,vue脚手架通过实现了,即在style标签上添加scoped,

scoped的实现原理:vue通过postcss给每个dom元素添加一个以data-开头的随机自定义属性、然后css根据属性选择器添加样式

第三方库的样式穿透:

  • less/sass穿透问题 >>> /deep/
  • 声明全局样式,样式加后加 !important
  • 将样式impoimport至App的上方

50、谈谈provide和inject

成对出现:provide和inject是成对出现的


作用:用于父组件向子孙组件传递数据


使用方法:provide在父组件中返回要传给下级的数据,inject在需要使用这个数据的子辈组件或者孙辈等下级组件中注入数据。


使用场景:由于vue有$parent属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。通过provide/inject可以轻松实现跨级访问父组件的数据


provider/inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量


需要注意的是这里不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据。

相关文章
|
6月前
|
前端开发 网络协议 JavaScript
|
2月前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
3月前
|
缓存 运维 前端开发
前端必备的运维知识点
【8月更文挑战第25天】前端必备的运维知识点
79 1
|
3月前
|
缓存 负载均衡 前端开发
前端必会的nginx知识点
【8月更文挑战第22天】前端必会的nginx知识点
81 0
|
4月前
|
JavaScript 前端开发 NoSQL
前端node如何学习进阶知识
【7月更文挑战第8天】 深化JavaScript基础,精通Node.js核心模块(如fs、http)与事件循环机制,学习Express框架及异步编程(回调、Promise、async/await),掌握数据库交互,参与实战项目,关注Node.js最新技术和最佳实践,以此提升进阶技能。
47 8
|
6月前
|
缓存 自然语言处理 JavaScript
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(四)
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(四)
|
6月前
|
前端开发 JavaScript 程序员
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(三)
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(三)
|
6月前
|
Web App开发 JavaScript 前端开发
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(一)
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(一)
|
6月前
|
存储 JavaScript 前端开发
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(二)
【前端开发---Vue2】史上最详细的Vue2入门教程,从基础到进阶带你彻底掌握Vue(二)
|
6月前
|
JavaScript 前端开发 Java
前端知识点03(JS)
前端知识点概览:了解JS中的this指向,包括全局、函数、new、apply/call/bind及箭头函数的规则。理解script的async和defer属性对脚本加载和执行的影响。探讨setTimeout和setInterval的用法及其在性能上的考量。ES6与ES5的区别在于新语法特性,如let/const、箭头函数、模板字符串、模块化、类和继承等。此外,ES6还引入了Symbol、解构赋值、默认参数、Map/Set和Generator等功能。别忘了点赞和支持作者哦!
48 1