1、为什么要使用vue,vue有什么好处?
渐进式,轻量级,多用途高性能,可维护性。本身具有响应式和组件化特点。以数据驱动为核心。
2、vue和react的区别是什么?
核心思想不同,响应原理不同。vue依赖收集,自动优化,数据变化时自动渲染是双向数据流。react需要设置属性手动优化,是单向数据流。
3、什么是mvvm模式?什么是mvc模式?两者有什么区别?
Model-View-ViewModel 即模型-视图-视图模型。模型指数据,视图指html页面,视图模型是MVVM的核心,指vue实例。ViewModel扮演监听者,数据发生改变时,通知视图做自动更新,视图发生改变时,通知数据做改动。这就实现了数据的双向绑定。
优点:低耦合,可复用,独立开发
MVC分为:Model(模型),View(视图),Controller(控制器)。
Controller是Model和View的协调者,View和Model不直接联系。基本都是单向联系。C即Controller指的是页面业务逻辑。MVC是单向通信。
MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验
4、vue的双向绑定原理是什么?
vue2中核心是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
vue3中改用了proxy,直接动态添加新属性可以实现数据响应。
5、Vue2.0和vue3.0有什么区别?
响应式原理不同,通过ref和reactive 给数据包上一层Proxy,通过 Proxy 监听属性的变化,从而实现对数据的监控。
vue3可以按需编译,体积更小。
vue3增加了组合式API,可维护性增强了。
6、Vue的生命周期有哪一些?说一下它们每个阶段做什么操作?
以vue3回答:
vue的生命周期是指,从创建vue对象到销毁vue对象的过程。整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册js方法,控制整个大局。
生命周期函数:就是在某一时刻会自动执行的函数。
beforeCreate:在实例生成之前会自动执行的函数
create:在实例生成之后会自动执行的函数
beforeMount:在组件内容被渲染到页面之前自动执行的函数
mounted:在组件内容被渲染到页面之后自动执行的函数
beforeUpdate:当数据data发生变化时会立即自动执行的函数
updated:当数据data发生变化时,页面重新渲染完成后,会自动执行的函数
beforeUnmount:当Vue 应用失效时,自动执行的函数
unmounted:当Vue 应用失效时,且dom完全销毁之后,自动执行的函数
7、vue的核心概念是什么?
vue 的核心概念就是数据驱动;所谓数据驱动指,视图是由数据驱动生成的,我们对视图的修改不会直接操作DOM,而是通过修改数据进行视图的更新。相较于传统的操作DOM进行开发,大大简化了代码量,只关心数据的修改让代码的逻辑变得非常清晰,DOM变成了数据的映射,所有的逻辑都是对数据的操作。
另外一个是组价化。没什么好说的大家都懂。
8、组件中data数据为什么必须以函数返回的形式,而不是简单的对象形式呢?
vue官方文档解释:组件是可复用的vue实例,组件不管复用多少次,组件中的data数据都应该是相互隔离的,互不影响,基于这一理念data就不能是一个单纯的对象,而是函数返回值的形式,所以每一组件实例可以维护一份被返回对象的独立拷贝。vue根实例中是可以使用对象形式的。
9、vue很适合创建单页面应用,什么是单页面应用?优缺点是什么?
单页面应用(SPA)是指只有一个主页面的应用,浏览器一开始要加载所有必需的 html、js、css。所有的页面内容都包含在这个主页面中。但在编写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。单页面应用的优点有以下几个。(1)用户体验良好。不需要重新刷新页面,减少TTFB的请求耗时,数据也是通过Ajax异步获取,页面显示流畅。(2)前后端分离。前端负责界面显示,后端负责数据存储和计算,各司其职,不会把前后端的逻辑混杂在一起。(3)减轻服务端压力,服务器只需要提供API接口,不用管理页面逻辑和页面的拼接,吞吐能力会提高几倍。(4)共用一套后端程序代码,适配多端同一套后端程序代码,不用修改就可以适用于 Web、手机、平板。单页面应用的缺点有以下几个。(1)不利于SEO的优化。因为页面数据都是前端异步加载的方式,不利于搜索引擎的抓取。(2)首屏加载过慢。单页面首次加载,需要将所有页面所依赖的CSS和JS合并后统一加载,所以CSS和JS文件会较大,影响页面首次打开的时间。
10、Vue的监听属性(watch)和计算属性(computed)有什么区别?
computed 是计算属性,也可以理解为一个方法。计算属性的结果会被缓存起来,只有依赖的属性发生变化时才会重新计算,必须返回一个数据,主要用来数据的操作。其中计算的结果如果不发生改变就不会触发,且必须返回一个值并在DOM中绑定的才能取得值。他可以自动获取数据的改变。
watch 属性是手动定义的所需监听的值,主要用于监听某个数据的变化,从而去执行某些具体的回调业务逻辑,不仅仅局限于返回数据。不同的数据可以在其中多次定义监听值,这时会消耗一定性能,他并不能像computed那样自动改变。
computed 和 watch 都能实现的功能,建议使用computed 因为更加简洁
11、计算属性(computed)中setter属性的用法?
计算属性默认只有getter,不过在需要时也可以使用setter。
当手动修改计算属性的值,像修改一个普通数据那样时,就是触发setter,执行一个自定义的操作。例如下面的代码:
computed:{ fullName:{ //setter set(){ let names = newValue.split(' '); this.firstName = names[0]; } } }
当运行vm.fullName = '张三' 时,setter会被调用。
12、vue中计算属性compute和方法methods可以实现相同的功能,为什么要使用计算属性而不是是去定义一个方法没呢?
计算属性是基于它们的依赖进行缓存的,即 只有当计算属性依赖的内容发生变更时,才会重新计算。相关依赖没有改变,多次访问计算属性会立即返回之前计算好的结果,而不必再次执行函数。 反之,如果使用方法实现,多次调用该方法时,方法都会重新执行一次,这无形中增加了系统的开销。 还有一种情况就是,在调用methods中一个方法时,所有的方法都会被调用。而计算属性则优化了这一情况。 计算属性调用不能使用括号,调用方法则需要加入括号。computed 和 methods 都能实现的一个功能,建议使用 computed,因为有缓存,可以减少系统调用
13、Vue常用的指令有哪些?
v-model,v-text,v-html,v-if,v-show,v-bind,v-on,v-once,v-for
14、v-If和v-show有什么区别?
v-if和v-show指令都是根据表达式的真假判断元素的显示与隐藏。v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。v-if 也是 惰性 的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。
15、Vue开发中,v-for循环为什么要使用key?
通过 key 管理状态
Vue 默认按照“就地更新”的策略来更新通过 v-for 渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。默认模式是高效的,但 只适用于列表渲染输出的结果不依赖子组件状态或者临时 DOM 状态 (例如表单输入值) 的情况 。为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key
16、Vue中provide和inject是怎么使用的?
传统的props向子代传值,如果遇到了多层子代传值,也就是给孙子辈子代传值要一层一层的传是很麻烦的。
一个组件要为组件后代提供数据,可能是孙子辈组件 ,为了避免 组件链路非常长 prop 逐级透传问题,这时使用需要使用到provide和inject。
要为组件后代提供数据,需要使用provide选项定义要传的数据,
要使用上层组件提供的数据,需在孙子辈组件使用 inject 选项来声明接收
17、v-model是什么?Vue中标签怎么绑定事件?
Vue中利用v-model进行表单数据的双向绑定。具体做了两个操作。
1,v-bind绑定了一个value属性。
2,利用v-on把当前元素绑定到一个事件上。
input元素本身有个oninput事件,每当输入框内容发生改变时,就会触发oninput,把最新的value值给到v-model绑定的属性。
18、Vue-cli 3.x创建的项目如何实现跨域请求?
Vue-cli创建的项目,可以直接利用Node.js代理服务器,通过修改vue proxyTable接口实现跨域请求。
在Vue-cli项目中的config文件夹下的index.js配置文件中。
19、在项目中,使用vue-router时url格式引发404的问题是怎么回事?
vue-router提供一个mode参数,用来控制url格式,默认用的是hash格式,如果在项目中设置使用history格式,刷新页面时可能引发404问题。
hash格式:http//:localhost:8080/#/image
history格式:http//:localhost:8080/image
原因是后端程序把url解析了,使用hash格式url有一个分隔符#,后端默认不会解析。所以服务端要增加一个覆盖所有情况的候选资源,如果url匹配不到任何静态资源,则应该返回同一个index.html。
20、Vue中 composition api中使用到 ref, reactive,它们的区别是什么?
ref, reactive 都是vue3中响应式的引用
原理,通过 proxy 对数据进行封装,当数据变化时,触发模版等内容的更新
ref 处理基础类型的数据
reactive 处理非基础类型的数据
const { ref } = Vue;
const { reactive, readonly, toRefs } = Vue;
//proxy , 'wang' 变成 proxy({value: 'wang'}) 这样的一个响应式引用
let name = ref('wang');
// proxy , { name: 'wang'} 变成 proxy({ name: 'wang'}) 这样的一个响应式引用
const nameObj = reactive({name: 'wang'});
21、VueX 的实现原理是什么?
通过定义和隔离状态管理,通过强制规则维持视图和状态间的独立性
22、在vuex中,如何开启严格模式?在严格模式下有什么效果?
开启严格模式,仅需创建store的时候传入strict:true.
在严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,都将会抛出错误。
23、Vuex的理解,有什么优缺点?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
可以响应式渲染页面,当项目体量较大和组件较多时,使用数据共享管理,代码将会变得更结构化且易维护。
刷新浏览器,vuex中的state会重新变为初始状态
解决方案-插件vuex-persistedstate如果不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。
24、Vue中数据拦截是怎么发生的?
在请求或响应被 then 或 catch 处理前拦截它们。
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
25、axios常用的请求方式有哪些?
get,post,put,request,patch
26、vue中常用的修饰符有哪些?
事件修饰符:once,stop,prevent,self
按键修饰符:enter,tap,delete,esc,up,down,right,left,space
系统修饰符:ctrl,shift
27、Vue中路由的原理
更新视图,但不发送请求。
通过hash与history 两种方式实现前端路由
每次 hash值的变化,都会触发hashchange这个事件,这样我们就可以可以通过监听hashchange这个事件来实现更新页面部分内容的操作。Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。
history 这种模式充分利用history.pushState API来完成URL跳转而无须重新加载页
28、路由跳转的方式有哪些
1、用“<router-link :to="{..}">”语句;
2、用“this.$router.push()”语句;
3、用“this.$router.replace()”语句;
4、用“this.$router.go(n)”语句。
29、Vue路由中router和route是什么区别?
this.$route:当前页面的路由信息。每个对象都是局部的,可以获取当前路由的 path,
name, params, query 等属性。
this.$router:全局的 router 实例。通过 vue 根实例中注入 router 实例,然后再注入到每个
子组件,从而让整个应用都有路由功能。其中包含了很多属性和对象(比如 history 对象),任何页面也都可以调用其 push(), replace(), go() 等方法。
30、Vuex有几个属性及作用?
1、state,用来存储变量;
2、mutations,提交更新数据的方法;
3、actions,用来解决异步流程来改变state数据;
4、getters,对state里面的变量进行过滤的;
5、modules 模块化
31、vue-router的导航守卫有哪一些?
1、全局守卫:
router.beforeEach
2、全局解析守卫:
router.beforeResolve
3、全局后置钩子:
router.afterEach
4、路由独享的守卫:
beforeEnter
5、组件内的守卫:
beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave
通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:
全局的
,单个路由独享的
, 或者组件级的
。
32、Vue中父子组件生命周期执行顺序是怎么样的?
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
1.当父组件执行完beforeMount挂载开始后,会依次执行子组件中的钩子,直到全部子组件mounted挂载到实例上,父组件才会进入mounted钩子
2.子级触发事件,会先触发父级beforeUpdate钩子,再去触发子级beforeUpdate钩子,下面又是先执行子级updated钩子,后执行父级updated钩子
33、Vue组件之间的通讯方式有哪些?
通过 props 传递
通过 $emit 触发自定义事件
使用 ref
EventBus
parent或root
attrs 与 listeners
Provide 与 Inject
Vuex
34、Vue中兄弟组件之间是如何传值的?
可以定义EventBus中间件,在需要传出的组件使用emit绑定自定义事件,在接收组件使用on绑定自定义事件接收。
35、vue中keep-alive的作用是什么?
它的功能是在多个组件间动态切换时缓存被移除的组件实例。
组件提供了 include 和 exclude 两个属性,允许组件有条件的进行缓存。
include: 字符串或正则表达式。只有匹配的组件会被缓存。
exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
36、Vue中keep-alive的生命周期执行顺序?
keep-alive的生命周期
activated
:页面第一次进入的时候,钩子触发的顺序是
created->mounted->activateddeactivated:
页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activated
37、Vue中如何封装一个组件?
定义组件的模板:使用template标签,并在其中定义组件的布局和功能。
定义组件的数据:使用data选项,定义组件的数据和状态。
定义组件的方法:使用methods选项,定义组件的行为和功能。
定义组件的计算属性:使用computed选项,定义组件的计算属性,用于动态计算和渲染数据。
定义组件的生命周期钩子:使用生命周期钩子,定义组件在不同的生命周期阶段执行的操作。
定义组件的props:使用props选项,定义组件的props,以实现父组件和子组件之间的数据传递。
封装组件:使用Vue.component注册
38、Vue中如何实现登录拦截的?
首先在定义路由的时候就需要多添加一个自定义字段
requireAuth
,用于判断该路由的访问是否需要登录。如果用户已经登录,则顺利进入路由, 否则就拦截进入登录页面。利用
vue-router
提供导航守卫beforeEach()
对路由进行判断,如果用户登陆,就把用户信息存到localstorage中,在前置的路由守卫中通过判断localstorage中是否有用户信息,实现登陆拦截功能
39、Vue中如何实现登录验证的?
利用
vue-router
提供导航守卫beforeEach()
对路由进行判断,在登录时判断localStorage中token和state中存储的用户名和密码是否存在如果存在直接跳过登录
如果不存在则使用
this.$store.dispatch触发action中axios中请求,把用户名和密码传过去,请求成功将用户名和密码保存在localStorage和state中,跳转页面即完成登录。
40、vue中的v-cloak的理解?
使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除。
一般用于解决网页闪屏的问题,在对一个的标签中使用v-cloak,然后在样式中设置[v-cloak]样式,[v-cloak]需写在 link 引入的css中,或者写一个内联css样式,写在import引入的css中不起作用。
41、vue更新数组时触发视图更新的方法?
push();pop();shift();unshift();splice();sort();reverse()
42、vue-router实现懒加载的方式?
ue异步组件技术 ==== 异步加载
vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 。但是,这种情况下一个组件生成一个js文件/* vue异步组件技术 */
{
path: '/home',
name: 'home',
component: resolve => require(['@/components/home'],resolve)
}
50、什么是盒模型?
一个元素的占比看成一个盒子。包括:
content,padding,margin,border
51、如何提高页面的加载性能?
减少第三库的引入,优化和压缩图片,预加载重要资源,启用浏览器缓存
52、实现一个元素水平垂直居中的方式?
最常用的是使用定位
position:absolute;
top:50%;
left:50%;
transform: translate(-50%, -50%);
第二常用的弹性盒子
display:flex;
align-items:center;
justify-content:center;
53、display:none与visibility:hidden的区别是什么?
display:none,它是不占位的。visibility:hidden是占位的。
54、px、em、rem的区别
px是固定的像素,一旦设置了就无法因为适应页面大小而改变。
em和rem相对于px更具有灵活性,适用于响应式布局。
em是相对于其父元素来设置字体大小的,一般都是以<body>的“font-size”为基准。rem是相对于根元素<html>。
55、H5有哪些新特性?
语义化标签:header、conent、footer、aside、nav、section、article
表单新特性:date,color,month,email,tel,url、search、number
增加了vedio和audio标签
56、CSS3有哪些新特性?
border-radius:边框圆角
box-shadow:为元素添加阴影
border-image:使用图片来绘制边框
transiton 过渡
transform 转换
animation 动画
57、如何根据窗口大小设置不同的样式?
使用媒体查询 /*窗口宽度在1000px以上,三栏显示*/ @media screen and (min-width:1000px){ #container{width:1000px;} #wrapper{width:780px; float:left;} #main{width:560px; float:right;} #sub01{width:200px; float:left;} #sub02{width:200px; float:right;} }
58、什么是事件委托?
就是利用冒泡原理,把子元素的事件绑定到父元素上,点击父元素去触发事件。
59、什么是Js原型?原型链是什么?
每一个函数都有个prototype属性 这个属性就是原型 他对应的值是原型对象。
当一个引用类型继承另一个引用类型的属性和方法时候会形成一个原型链
60、new操作符做了哪些操作?
调用构造函数
隐式创建了一个对象 并且函数this指向隐式创建的对象
执行代码 把属性和值赋值给这个对象
隐式的返回这个对象
61、什么是JSONP?其原理是什么?
动态创建script标签就是JSONP。
利用script标签的src属性不受同源策略限制。可以跨域。
62、什么是事件流?
页面事件执行的顺序
63、什么是闭包?
闭包是指有权访问另一个函数作用域变量的函数。
64、如何改变this的指向?call和apply参数有什么不同?
call,apply,bind
call和apply的区别在于传参上的不同
fun.call(fun1,'1');
fun.apply(fun1,[1]);
第一个参数为this的新指向,第二个参数传参类型不同
bind和call、apply的不同在于,bind不会立即执行,而是在下次调用的时候执行
65、let var const 有什么区别
let 声明的变量只在 let 命令所在的代码块内有效
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
var 是在全局范围内有效,拥有变量提升
66、数组去重有哪些方法?
indexOf,filter,new Set
67、http请求跨域问题,你都知道哪些解决跨域的方法,为什么会跨域?
主要源于浏览器同源策略的限制。同源要求:协议 + 域名 + 端口 一致。
同源的设计是为了防止CSRF(跨站请求伪造)
如何实现跨域请求:
nginx反向代理解决,cors跨域资源共享,jsonp
vue中直接利用Node.js代理服务器,在vue.config.js中通过修改vue proxyTable接口实现跨域请求
68、常用伪类,伪元素有哪一些?
锚点< a>有五个伪类,:link、:hover、:active、:focus、:visited
//以下情况都是E为父元素,F为子元素
E F:nth-child(n) 选择父元素的第n个子元素
E F:nth-last-child(n) 选择父元素的倒数第n个子元素
E F:first-child 父元素的第一个子元素,与E F:nth-child(1)等同
E F:last-child 父元素的最后一个子元素,与E F:nth-last-child(1)等同
E F:only-child 当前元素的父元素,有且只有它本身一个子元素(DOM节点)时,修改其样式:before:在元素之前添加内容。(这个前端必会)
:after:在元素之后添加内容。(这个前端必会)
69、移动端如何适配不同屏幕尺寸?
动态修改html的fontsize的大小,页面元素在设置尺寸时候,以rem为单位,在不同尺寸下就可以实现页面元素宽度等具有动态变化的效果
使用css中的媒体查询,根据屏幕尺寸设置html的fontsize
70、ES6的新特性有哪些?
- Object.keys() 返回对象所有属性
- Object.values() 返回对象所有属性值
- Object.entries() 返回多个数组,每个数组是 key–value
- let const
- 模板字符串
- 拓展运算符
- Array.from()是内置对象Array的方法,实例数组不能调用
- includes() 参数:数值 -------- 返回值:true/false
- map()、filter() 参数:函数-------- 返回值:数组
- forEach() 参数:函数-------- 返回值:undefined
- find() 参数:函数-------- 返回值:数值
- some()、every() 参数:函数-------- 返回值:true/false
71、什么是深拷贝和浅拷贝,如何自己实现一个深拷贝?
一个对象的属性是引用类型,那么改变该属性值里面的内容,另外的拷贝对象也会改变,因此这种拷贝是浅拷贝。
举个例子:
let obj = {
name:'张三',
age:26,
study:['Chanese','English']
}
let copeObj = obj;
obj.study.push('Freach');
console.log(copeObj.study)//['Chanese','English','Freach'];
简单说就是我给obj中study增加内容,copeObj中也会增加。
不管原数据中值是什么类型的数据,拷贝后的新数据跟原数据是相互独立,没有关联的,这是深拷贝。
可以使用递归进行深拷贝,判断如果基本数据类型直接赋值,如果是引用型类型则重新调用自身。
72、什么是防抖和节流?怎么实现?
本质上是优化高频率执行代码的一种手段
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
区别:
防抖以最后一次触发为准,如果在设定的n秒内再次触发,则以新的事件时间为准
节流以第一次触发为准,执行第一次时间后,在设定的n秒内触发都不会执行
都可以通过setTimeout实现。
73、0.1 + 0.2 等于 0.3吗?为什么?如何解决?
不等于呀,因为有浮点小数啊,具体原因是计算机二进制的计算问题,具体是什么就不深究了。
怎么解决呢?
我们可以先将其转化为整数,运算之后,然后再转化为小数。
ES6中的
Number.EPSILON,
我们可以使用两数相加再减去目标数值,结果小于Number.EPSILON
即可
74、判断一个变量是否是数组,有哪些办法?
instanceof,isArray()
75、判断一个变量是否是对象,有哪些办法?
instanceof,Object.prototype.toString
76、对象/数组常用方法有哪些?
concat,tevery,filter,find,findIndex,forEach,map,includes,indexOf,join
push,popreduce , reverse,unshift,shift,slice,some,sort,splice,toString
77、哪些遍历方式会改变原数组?
every,some,filter,map
78、Set和Map各是什么?
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
79、Flex:1 包含哪三种属性?
flex:1 是三个属性的连写:flew-grow、flex-shrink、flex-basis
等于 flex:1 1 0
80、什么是虚拟DOM,和真实DOM的区别?
虚拟DOM其实就是JavaScript对象,以js对象的形式去添加DOM元素,
利用JavaScript来编写一个虚拟DOM,在没有渲染的情况下,它就是一个字符串、一个对象。当把信息push到节点中,才会变成一个真实的DOM。
真实dom就类似于div节点
82、webpack的怎么配置?
83、get请求和post请求的区别?
get传输量小,一般限制是2-5kb,所以get传输速度更快
post没有数据大小限制,传输速度没有get快
get安全性低 因为它的数据是暴露在URL里面的,post不会暴露传输数据
84、浏览器页面呈现的过程,及重绘与回流?
- 浏览器把获取到的HTML代码解析成1个DOM树,HTML中的每个tag都是DOM树中的1个节点,根节点就是我们常用的document对象。
- 浏览器把所有样式(用户定义的CSS和用户代理)解析成样式结构体(CSSOM树),在解析的过程中会去掉浏览器不能识别的样式。
- DOM树和样式结构体(CSSOM树)组合后构建render tree。
- 注意:visibility:hidden隐藏的元素还是会包含到 render tree中的,因为visibility:hidden 会影响布局(layout),会占有空间。根据CSS2的标准,render tree中的每个节点都称为Box (Box dimensions),理解页面元素为一个具有填充、边距、边框和位置的盒子。
- 一旦render tree构建完毕后,浏览器就可以根据render tree来绘制页面了。
回流(reflow)指的是当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,即渲染树需要重新计算。
也就是说,回流是指DOM的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证DOM树上的所有其他节点的visibility属性,因此,回流是低效的。
每个页面至少需要一次回流,就是在页面第一次加载的时候。
在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。
重绘指的是当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color,visibility,outline等。
重绘不会带来重新布局,并不一定伴随回流(重排)减少回流、重绘的方法
减少回流、重绘其实就是需要减少对render tree的操作(合并多次对DOM和样式的修改),并减少对一些style信息的请求,尽量利用好浏览器的优化策略。接下来介绍解决方法。尽量不用内联样式style属性,操作元素样式的时候用添加去掉class类的方式,实现合并多次改变样式属性的操作:
给元素加动画的时候,可以把该元素的定位设置成absolute或者fixed(动画元素脱离文档流),这样不会影响其他元素,减少回流的Render Tree的规模。
在需要经常获取那些引起浏览器重排的属性值时,要缓存到变量。
尽可能在DOM树的最末端改变class。
避免设置多层内联样式。
动画效果应用到position属性为absolute或fixed的元素上。
牺牲平滑度换取速度。
免使用table布局。
避免使用CSS的JavaScript表达式。
避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性。
避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。
可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。
避免循环读取offsetLeft等属性,在循环之前把它们存起来。
85、说一下你项目中遇到的难点,如何解决?
Vue组件传值问题
父组件双向绑定获取到的数据,通过在子组件上自定义属性的方式传给子组件,子组件通过props接受,并赋值给子组件data中定义的属性,显示到页面上。
初始化可以,但父组件中数据变化后,页面上的显示的内容并没有改变。
原因:子组件data中定义的属性是string类型的变量,属于js的基本数据类型,在创建的时候就已经将数据值写入到内存栈中,之后与初始化的赋值就没有任何关系了,因此后面父组件中数据变化,子组件中属性就不会变化了。
解决办法:父组件可以向子组件传一个对象,因为对象是引用类型,赋值时将存储数据的地址进行拷贝,因此子组件中定义的属性和父组件中的对象指向同一个地址,父组件中对对象的属性值进行修改,子组件中对象的属性也会跟着变化。
解决办法2:采用watch监听,监听父组件传值的变化,对子组件中data中定义的属性重新初始化。