-
生命周期
-
初始化:
- beforeCreate:初始化前,不能访问实例上的数据
- created: 初始化后,可以访问实例上的数据
-
挂载:
- beforeMount:挂载前,不能访问到真实dom
- mounted:挂载后,可以访问真实dom
-
更新
- beforeUpdate:数据改变,但是dom还没更新
- updated: 数据改变,且dom已更新
-
销毁
- beforeDestroy:销毁前,还能访问子组件
- destroyed:销毁后,不能访问子组件
activated(当组件激活时调用) deactivated(当组件失活时调用)
vue2.x生命周期 beforeCreate:创建前,实例化还没有完成,所以不能访问data与methods, 可以调接口,只是不适合(不能访问data与methods,如果接口用到data与methods就不适合使用) beforeCreate(){ setTimeout(()=>{},10000) axios({url:,params:}).then(res=>{ this:就是当前实例对象 }) } created:创建后,实例化已完成,可以访问data属性与methods方法,不能访问vue渲染后的dom 常用于进入页面接口请求 nextTick:微任务 this.$nextTick(()=>{ 访问dom })
beforeMount:渲染前,读取了(el)需要渲染template内的内容 mounted:渲染后,完成了dom渲染,第一个可以访问vue渲染后dom的生命周期, 常用于进入页面dom操作 beforeUpdate:更新前,页面中使用的相关数据已修改,但是渲染还没完成 updated:更新后,页面中使用的相关数据已修改,且渲染已完成(不保证所有渲染已完成) beforeDestroy:销毁前,还没有销毁,data与methods都可以访问,能做一些善后工作(setInterval,scroll事件需要移除) destroyed:销毁后(中断渲染),可以访问data属性methods方法,不能访问vue渲染后的dom,能做一些善后工作(setInterval,scroll事件需要移除)
vue3.x生命周期 setup:创建实例前(入口函数) onBeforeMount:渲染前,读取了(el)需要渲染template内的内容 onMounted:渲染后,完成了dom渲染,第一个可以访问vue渲染后dom的生命周期, 常用于进入页面dom操作 onBeforeUpdate:更新前,页面中使用的相关数据已修改,但是渲染还没完成 onUpdated:更新后,页面中使用的相关数据已修改,且渲染已完成(不保证所有渲染已完成) onBeforeUnmount:销毁前等效以前的beforeDestroy onUnmounted:销毁后等效以前的destroyed 去掉了beforeCreate,created,新增了setup(在beforeCreate前),命名上重点都加了on,销毁 前(beforeDestroy==>onBeforeUnmount),销毁后:(destroyed===>onUnmounted) 生命周期使用: 1:导入: import {onMounted} from 'vue' 2:使用 setup(){ onMounted(()=>{ ...相应代码 }) onMounted(()=>{ ...相应代码 }) onMounted(()=>{ ...相应代码 }) } 特点:多次使用
-
重中之重、Vue的双向数据绑定原理是什么? 答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 具体步骤: 第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter 这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化 第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图 第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是: 1、在自身实例化时往属性订阅器(dep)里面添加自己 2、自身必须有一个update()方法 3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。 第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。 -
Vue双向绑定原理? 在 Vue 2.x 中,利?的是 Object.defineProperty 去劫持对象的访问器(Getter、Setter),当对象属性值发?变化时可获取变化,然后根据变化来作后续响应; 在 Vue 3.0 中,则是通过 Proxy 代理对象进?类似的操作。 -
一、什么是MVVM? MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。 在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。 ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。 -
vuex面试相关 (1)vuex是什么?怎么使用?哪种功能场景使用它? vue框架中状态管理。在main.js引入store,注入。新建一个目录store,…… export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车 (2)vuex有哪几种属性? 有五种,分别是 State、 Getter、Mutation 、Action、 Module vuex的State特性 A、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data B、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新 C、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中 vuex的Getter特性 A、getters 可以对State进行计算操作,它就是Store的计算属性 B、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用 C、 如果一个状态只在一个组件内使用,是可以不用getters vuex的Mutation特性 Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。 (3)不用Vuex会带来什么问题? 可维护性会下降,想修改数据要维护三个地方; 可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的; 增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。 -
v-model的原理是什么?
- v-model的原理是 : input事件与value属性的绑定
- 当input事件触发,就会修改data中的值,data中的值发生改变就会渲染视图上
- 如果不是input元素,可以使用model:{}来修改
- Prop:修改绑定的值,例如input修改为checked
- event:修改事件名,例如value修改为change
-
29.Es6的新特性有哪些? 与es5区别 区别于函数,更加专业化(类似于 JAVA 中的类) 写法更加简便,更加容易实现类的继承
- 箭头函数
- 模版字符串
- 解构赋值
- 展开运算符 ...
- let const 变量声明
- Promise
- class 类
- for of
- async、await
- 修饰器
- Symbol
- Proxy
-
http协议
- http协议
- 一套用来传输超文本的协议
- 请求、响应
- 请求报文三大类:
- 请求行:请求方式、请求路径、遵守的协议版本
- 请求头:键值对形式,包含了当前发请求的环境信息和身份信息
- 请求体: 传递给服务器的数据,一般post请求会通过请求体发送数据,get请求通过url拼接
- 响应报文三大类
- 响应行:响应状态码、状态描述文字、遵守协议版本
- 响应头:键值对形式,包含了当前服务器的信息和然后浏览器要做的事
- 响应体:服务器返回给浏览器的数据
-
.你在使用vue进行开发时有什么收获?数据响应化处理
- 为所有的组件属性定义明确的顺序
- 使用混入mixins
- 谨慎使用$set
- 因为在大多数情况下,数据都应该在data中定义,并进行数据响应化处理
- 使用插槽构建公共组件
- 使用keep-alive避免组件多次切换渲染浪费性能 内部包裹的标签不会被销毁和重新创建0
-
防抖和节流有什么用,一般的使用场景,原理是什么 1.作用 使用函数节流与函数防抖的目的,就是为了节约计算机资源,提升用户体验。 2.场景 节流一般是用在必须执行这个动作,但是不能够执行太频繁的情况下,例如滚动条滚动时函数的处理,可以通过节流适当减少响应次数; 防抖一般是用来,用户输入有操作时,暂时不执行动作,等待没有新操作时,进行相应响应,例如用户名输入校验的情况,可以等待用户输入完成后再发送请求去校验。 3.原理 总的来说,函数节流与函数防抖的原理非常简单,巧妙地使用 setTimeout 来存放待执行的函数,这样可以很方便的利用 clearTimeout 在合适的时机来清除待执行的函数。 函数节流: 指定时间间隔内只会执行一次任务; 函数防抖: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。 区别:防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行 -
你是如何做屏幕适配的?
- 1·通过Media Queries 媒体查询,通过查询设备的宽度来执行不同的css代码
- 2·使用弹性布局
- 3·根据屏幕宽度设置rem ,需要适配的元素都使用rem为单位
-
1、Vue 的 nextTick 的原理是什么? (高薪常问) \1. 为什么需要 nextTick ,Vue 是异步修改 DOM 的并且不鼓励开发者直接接触 DOM,但有时候业务需要必须对数据更改--刷新后的 DOM 做相应的处理,这时候就可以使用 Vue.nextTick(callback)这个 api 了。 \2. 理解原理前的准备 首先需要知道事件循环中宏任务和微任务这两个概念,常见的宏任务有 script, setTimeout, setInterval, setImmediate, I/O, UI rendering 常见的微任务有 process.nextTick(Nodejs),Promise.then(), MutationObserver; \3. 理解 nextTick 的原理正是 vue 通过异步队列控制 DOM 更新和 nextTick 回调函数先后执行的方式。如果大家看过这部分的源码,会发现其中做了很多 isNative()的判断,因为这里还存在兼容性优雅降级的问题。可见 Vue 开发团队的深思熟虑,对性能的良苦用心。 -
$nextTick的实现原理是什么
- nextTick主要是通过js事件循环(Event Loop)的执行机制原理,使用Promise微任务来实现的
- vue会判断当前浏览器是否支持Promise,如果不支持则使用mutationobserver,如果还不支持则调用setImmediate,如果还不支持最后调用setTimeout
-
5.你做过哪些性能优化?
- 减少HTTP请求
- 图片/路由使用懒加载
- 外部资源使用CDN引入
- 功能相似的组件与逻辑抽离并复用
- 长列表数据使用懒加载
- 函数防抖 函数节流
- 减少js代码中的全局变量,html标签语义化
-
原型链是什么
- 每个函数都有一个 prototype 的属性,指向原型对象
- 原型对象中有一个
constructor 属性,指向构造函数本身 - 每个实例都有一个
__proto__ 属性,这个属性指向原型对象
有一个特殊的点,所有的 JavaScript 对象都是继承自 **Obejct** 的对象。而 **Obejct** 对象的 **__proto__** 最终指向了 null。
- 每个函数都有一个 prototype 的属性
- 指向原型对象
- 原型对象中存储所有实例对象共享的属性和方法
- 不需要共享的属性和方法放在构造函数中
那有了原型对象之后,我们通过 new 关键字来创建实例对象。这个时候创建出来的实例,会自动挂载构造函数原型对象上的属性值。
**注意:**在原型对象 prototype 里,有一个 constructor 属性,这个属性会又指回到构造函数本身去。
-
内存泄露 但它却存在一个致命的问题:循环引用。 如果两个对象相互引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄露。
function cycle() {
let o1 = {}
let o2 = {}
o1.a = o2
o2.a = o1
return "Cycle reference!"
}
cycle()
利用闭包函数解决内存问题
// 8. 闭包函数: 是一个子函数,可以让外界直接使用局部作用域的变量
// 不会造成内存浪费, 比直接用return要更好一些
-
什么是敏捷开发 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。 在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。 传统的开发模式和敏捷开发模式的对比 瀑布模型: 优点:
- 为项目提供了按阶段划分的检查点。
- 当前一阶段完成后,您只需要去关注后续阶段.
- 它提供了一个模板,这个模板使得分析、设计、编码、测试和支持的方法可以在该模板下有一个共同的指导。
缺点:
- 各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量。
- 由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发风险。
- 通过过多的强制完成日期和里程碑来跟踪各个项目阶段。
- 瀑布模型的突出缺点是不适应用户需求的变化。
敏捷模型: 优点: 敏捷开发的高适应性,以人为本的特性。 更加的灵活并且更加充分的利用了每个开发者的优势,调动了每个人的工作热情。 缺点: 由于其项目周期很长,所以很难保证开发的人员不更换,而没有文档就会造成在交接的过程中出现很大的困难。 -
原文链接:软件开发模式之敏捷开发(scrum)_android_Mr_夏-CSDN博客_敏捷开发 -
前端图片压缩上传 本文实现的功能流程如下:
- 用户通过input框选择图片
- 使用FileReader进行图片预览
- 将图片绘制到canvas画布上
- 使用canvas画布的能力进行图片压缩
- 将压缩后的Base64(DataURL)格式的数据转换成Blob对象进行上传
-
.slot和slot-scope的原理是什么 66.slot和slot-scope的原理是什么?
- 在父组件的渲染函数中,会将子组件的插槽内容解析成节点,然后传递给子组件的渲染函数
- slot会在父组件编译渲染阶段生成了Vnodes,所以slot数据的作用域是父组件,子组件渲染的时候直接拿这些渲染好的Vnodes
- 子组件的渲染函数会把Vnodes传递给子组件实例的$slot
- slot占位符会被解析成一个函数 _t, _t执行从子组件的$slot上拿到Vnodes节点并把结果返回,最后替换slot占位符
- 而对于slot-scope 作用域插槽,父组件在编译和渲染阶段并不会直接生成Vnodes,而是在父组件Vnode的data中保留一个scopedSlots对象,存储着不同名称的插槽以及插槽对应的渲染函数,只有在编译和渲染子组件的时候才会执行对应的渲染函数生成Vnodes,由于渲染函数是在子组件中执行的,所以作用域是子组件
-
less和sass的区别 原理 1.1 Less定义:是一种动态的样式语言,使CSS变成一种动态的语言特性,如变量、继承、运算、函数。Less既可以在客户端上面运行(支持IE6以上版本、Webkit、Firefox),也可以在服务端运行(Node.js) 1.2 SaSS定义:是一种动态样式语言,SaSS里面的语法属于缩排语法,对于之前的css相比,多出了很多功能,更容易阅读 1.3 预处理器。Less和SaSS都属于预处理器,它会定义一种新的语言,其总体思想是为CSS增加一些编程的特性,将 CSS 作为目标生成文件, 之后开发者就只要使用这种语言进行CSS的编码工作。 Less和Sass的主要不同就是他们的实现方式。 Less是基于JavaScript,是在客户端处理的。 Sass是基于Ruby的,是在服务器端处理的。 关于变量在Less和Sass中的唯一区别就是Less用@,Sass用$。 Sass与Scss是什么关系? Sass的缩排语法,对于写惯css前端的web开发者来说很不直观,也不能将css代码加入到Sass里面,因此sass语法进行了改良,Sass 3就变成了Scss(sassy css)。与原来的语法兼容,只是用{}取代了原来的缩进。 二、less和sass的相同之处 Less和Sass在语法上有些共性,比如下面这些: 1、混入(Mixins)——class中的class; 2、参数混入——可以传递参数的class,就像函数一样; 3、嵌套规则——Class中嵌套class,从而减少重复的代码; 4、运算——CSS中用上数学; 5、颜色功能——可以编辑颜色; 6、名字空间(namespace)——分组样式,从而可以被调用; 7、作用域——局部修改样式; 8、JavaScript 赋值——在CSS中使用JavaScript表达式赋值。 -
js中事件绑定的几种方式
-
HTML事件处理程序:直接在html的标签中添加事件属性, 例如: <div οnclick="fun()"></div> 这样做很是不好,有下列两大缺点 (1)存在一个时差问题,因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件(比如js代码还没有下载下来),由此会引发错误。 (2)HTML与js代码紧密耦合。如果要更换事件处理程序,就要改动两个地方:HTML代码和JS代码,这非常不利于后期代码的维护。 -
DOM1级事件处理程序:将一个函数赋值给一个事件处理程序属性,表示元素的方法,这时的事件处理程序是在元素的作用域中运行 var oBox = document.getElementById("container"); oBox.onclick = function() {} 优点是:简单和所有浏览器都支持。 缺点是:只能给该元素绑定一个事件。于是出现DOM2级事件处理程序。 -
DOM2级事件处理程序:addEventListener()添加事件,removeEventListener()删除事件。可添加多个,执行顺序与添加顺序相同。两个方法都接受三个参数 第一个参数:事件名称 第一个参数:作为事件处理程序的函数 第一个参数:捕获值false(不捕获)/true(捕获),不写表示默认值false 例如: var oBox = document.getElementById("container"); oBox.addEventListener("click",fn(),false);
oBox.removeEventListener("click",fn(),false);
function fn(){//执行代码} 关于第三个参数一般填写默认值false或不填,因为:大多数情况下,都是将事件处理程序添加到时间流的冒泡阶段,这样可以最大限度地兼容各种浏览器,如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。关于捕获和冒泡同时存在的情况下我总结了以下几点: (1)冒泡且捕获:捕获导致不能进入更低层事件,点击该层的更低层只能触发该捕获层,一般为了不阻断其他事件的触发设置捕获为false。 (2)冒泡但不捕获:执行冒泡顺序,从触发层从内到外执行事件,与事件监听绑定的顺序无关。 (3)若多级包含元素且多个元素都添加事件监听则为了更稳定的执行时间需要:①每个元素的事件监听的捕获都设置为false或不填。②并且在执行函数内阻止冒泡。e.stopPropagation()||e.cancelBubble=true; -
IE事件处理程序:attachEvent()添加事件,detachEvent()删除事件,由于(IE8-)不支持捕获,所以两种方法只支持两个参数: 第一个参数:事件处理程序函数名称eg:onclick onmouseover 第二个参数:作为事件处理程序的函数 例如: var oBox = document.getElementById("container"); oBox.attach("click",fn());
oBox.detach("click",fn());
function fn(){//执行函数} 注意:使用这种方法的事件处理程序的作用域是全局,函数内this指向window而不是事件目标对象,如果要指定事件目标对象可以也使用event.srcElement。能给添加多个,但是执行顺序与添加顺序相反。
说一下你在 Vue 中踩过的坑(必会)
1、第一个是给对象添加属性的时候,直接通过给 data 里面的对象添加属性然后赋值,新添
加的属性不是响应式的
1.1)解决办法:通过 Vue.set(对象,属性,值)这种方式就可以达到,对象新添加的属
性是响应式的
2、在 created 操作 dom 的时候,是报错的,获取不到 dom,这个时候实例 vue 实例没有挂载
2.2)解决办法:通过:Vue.nextTick(回调函数进行获取)
说一下webpack的打包原理
Webpack是把项目当做一个整体,通过给定一个主文件,webpack将从这个主文件开始找到项目中所有依赖的文件,使用loaders类处理,最后打包成一个或者多个浏览器可识别的js文件
CDN 的全称是 Content Delivery Network,即内容分发网络。
CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
?
|