vue前端面试题(全!精!)带答案

如何全局统一处理后端的返回报错或者网络问题
修改axios的响应拦截器interceptors 【axios.interceptors.response.use】
1、axios的特点有哪些?
一、Axios 是一个基于 promise 的 HTTP 库,支持promise所有的API
二、它可以拦截请求和响应
三、它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
四、安全性更高,客户端支持防御 XSRF
2、axios有哪些常用方法?
一、axios.get(url[, config])   //get请求用于列表和信息查询
二、axios.delete(url[, config])  //删除
三、axios.post(url[, data[, config]])  //post请求用于信息的添加
四、axios.put(url[, data[, config]])  //更新操作
Head  HEAD请求只返回响应头信息,不返回实际的响应主体
3、说下你了解的axios相关配置属性?
Url:用于请求的服务器URL
Method:创建请求时使用的方法,默认是get
baseURL:将自动加在url前面,除非url是一个绝对URL。它可以通过设置一个baseURL便于为axios实例的方法传递相对URL
transformRequest:允许在向服务器发送前,修改请求数据,只能用在'PUT','POST'和'PATCH'这几个请求方法
headers:自定义请求头     eg: {'X-Requested-With':'XMLHttpRequest'},
params:URL参数,必须是一个无格式对象(plainobject)或URLSearchParams对象;所谓的无格式的对象就是属性值皆为字符串的对象
Auth:表示应该使用HTTP基础验证,并提供凭据
Proxy:代理服务器的主机名称和端口
axios原理
createInstance底层根据默认设置 新建一个Axios对象,所有的请求内部调用的都是Axios.prototype.request,将prototype.request的内部this绑定到新建的Axios对象上,从而形成一个axios实例。新建Axios对象时,会有两个拦截器,request拦截器,response拦截器。
request拦截器是在请求发送前进行一些操作,比如统一添加token
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,例如加入token
    .......
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });
response拦截器是在接收到响应后进行一些操作,比如登录失效跳转到登录页。
axios.interceptors.response.use(function (response) {
    // 在接收响应做些什么,例如跳转到登录页
    ......
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });
隐藏页面某个元素的方法 / v-if v-show的区别
v-if     v-show
v-show不管条件真假,第一次渲染的时候都会编译出来,添加到DOM中。之后切换的时候,通过display: none;样式来控制显隐。只改变css的样式,几乎不会影响什么性能
v-if 通过动态地向 DOM 树内添加或删除 DOM 元素来实现内容的显隐。在首次渲染的时候,如果条件不成立,那么页面上没有这些元素。当条件成立的时候,开始局部编译,动态的向DOM元素里面添加元素。当条件从真变为假的时候,开始局部编译,删除这些元素。
`v-if` 有较高的切换消耗,适合用于条件不经常变化的场景,
`v-show` 有较高的初始渲染消耗* 适合于需要频繁切换显隐的场景
计算属性compute,watch 区别
`computed`适合于计算依赖多个数据属性的复杂属性值,基于响应式依赖进行缓存,只在相关响应式依赖发生改变时才会重新求值,不支持异步。适用于多个数据改变影响一个数据值的情况
计算属性默认只有 getter,所以只能取值,不能赋值,如果想要修改计算属性 那就自己实现setter方法。
`watch`适合于监听数据属性,并在数据变化时执行操作,支持异步,不支持缓存。`watch`选项中的函数有两个参数,第一个是最新的值,第二个参数是输入之前的值,顺序是新值,旧值。适用于一个数据改变影响多个数据的情况
iframe内外部交互的方式
1.从vue到iframe的信息传递:
使用window.postMessage,:在Vue组件中使用window.postMessage‘发送消息,iframe中通过监听‘message'事件接收消息。
Vue组件内嵌iframe:
将iframe作为vue组件的一部分,通过props或其他方式将数据传递给iframe。
通过eventbus,使用$emit触发事件,iframe中通过$on监听事件。
2.从iframe到Vue的信息传递:
使用window.postMessage,在iframe中使用window.parent.postMessage发送消息。在vue中通过监听message接收。
window.addEventListener:在vue应用中通过 window.addEventListener’监听全局事件。在iframe中通过 window.top.dispatchEvent•触发全局事件,从而与Vue通信。
注意事项:
安全性:在进行跨域通信时,需要确保安全性。使用^postMessage^时,可以通过设置目标域的白名单来限制消息发送的目标。
iframe加载完成:确保iframe已经加载完成再进行通信,可以使用 1oad〝事件或者iframe .onload^回调。
跨域限制:如果Vue应用和ifrarme不在同一个域下,需要确保在iframe的响应头中包含"Access-Control-Allow-Origin'.
Vue 子组件和父组件生命周期钩子函数执行顺序
组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。
组件的销毁操作是先父后子,销毁完成的顺序是先子后父。
加载渲染过程:
1.父组件 beforeCreate
2.父组件 created
3.父组件 beforeMount
4.子组件 beforeCreate
5.子组件 created
6.子组件 beforeMount
7.子组件mounted
8. 父组件 mounted
更新过程:
1.父组件 beforeUpdate
2.子组件 beforeUpdate
3.子组件 updated
4.父组件 updated
销毁过程:
1.父组件 beforeDestroy
2.子组件 beforeDestroy
3.子组件 destroyed
4.父组件 destoryed
created:已创建 //已创建,在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
Mounted:渲染完成 //已挂载,在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些操作。
Updated 数据更新 //在实例更新完成后被调用,此时实例的数据已经重新渲染到DOM上。可以在这个阶段对DOM进行操作,但要避免无限循环的更新。
beforeDestroyed :即将销毁 //即将执行销毁过程,一般在此阶段停止定时器、取消eventbus等操作
Vue2中父子组件传值方式,兄弟组件传值方式
父传子:子组件通过props的方式来接收父组件传递过来的数据;注意props是单向的,你无法改变父组件的值,可以在data()里重新定义一个变量),把props赋值给它。
使用ref,给子组件定义一个ID,父组件通过这个ID可以直接访问子组件里面的方法和属性;
加上.sync 表示双向绑定,实际上是监听 属性的同时 监听update的事件 回传数据修改属性的值
子传父:子组件调用$emit向父组件传递事件并携带参数,父组件使用事件接收;
兄弟传递:可以使用 eventBus,eventbus.$emit()  eventbus.$on;eventbus.$off移除
以上所有组件间的传值都可以使用 vue的状态管理来实现(vuex),但是此方法不建议使用
v-model原理
v-model 是 Vue 的语法糖,用于简化表单元素和数据之间的双向绑定。实际上是将 :value 和 @input 绑定的细节封装起来,使得双向绑定变得更加简洁和易读。
v-model有局限性,绑定的属性名只能叫value
总结一下,v-model 的原理包括两个方面:
1.属性绑定: 将表单元素的值与 Vue 实例中的数据绑定,确保显示的值与数据同步。
2.事件监听: 监听表单元素的输入事件变化时,通过该事件将新值赋给 Vue 实例中的数据。
vue跨域解决方式
开发中
1、前端在vue.config中配置代理,proxy中的target地址
2、后端配置cors; Access-Control-Allow-Origin*
部署后  使用ngnix进行转发
vuex中存储的数据,刷新页面后导致数据丢失,如何解决
原因
刷新页面时,vue实例重新加载,导致store被重置
store是存储组件状态的,但不是本地数据存储,如果不希望被重置可以用本地存储
sessionStorage/localStorage
监听页面是否刷新,如果页面刷新了,将state对象存入到localStorage中。
页面打开之后,判断localStorage中是否存在state对象,如果存在,则说明页面是被刷新过的,将localStorage中存的数据取出来给vuex中的state赋值。如果不存在,说明是第一次打开,则取vuex中定义的state初始值。
第三方插件
vuex-persistedstate
vuex-persistedstate:在页面重新加载之间保持并重新补充Vuex状态
四、补充
cookie: 不适合存储较大的数据 (一段不超过4KB的小型文本数据)
localStorage: 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除(永久存储)
sessionStorage: 临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据(推荐)
cookie可设置失效时间,默认为关闭浏览器后失效
localStorage除非手动清除,否则永久有效
sessionStorage仅在当前网页会话下有效,关闭页面或浏览器后就会被清除
cookie区分域,不区分端口,同ip下的不同端口cookie是共享的,sessionStorage和localStorage不可共享
VUE浅拷贝和深拷贝实现方式
1.Object.assign()-----将一个或多个对象复制到目标对象
  单级结构时深拷贝,多级结构浅拷贝,Object.assign()对象是用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,将返回目标对象。
2.concat()-----连接两个或多个数组
单级结构时深拷贝,多级结构浅拷贝
3.slice()-----从已有的数组中返回选定的元素
单级结构时深拷贝,多级结构浅拷贝
4.JSON.parse(JSON.stringify()) (一定是深拷贝,常用)
  用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝
5.cloneDeep() (第三方js工具库lodash,封装了常用的工具方法,跟面试官说你在开发中常用这个库)
单级多级均为深拷贝,使用lodash工具中cloneDeep方法实现深拷贝,需要通过npm引入lodash库
Vue中 keep-alive
keep-alive  Vue 的内置组件,用它包裹动态组件时,会缓存不活动的组件,而不是销毁。
它是一个抽象组件,不会被渲染成 DOM 元素
作用是  在组件切换过程中,防止重复渲染DOM
原理: 在 created 函数调用时将需要缓存的 VNode 节点保存在 this.cache 中/在 页面渲染 时,如果 VNode 的 name 符合缓存条件(可以用 include 以及 exclude 控制),则会从 this.cache 中取出之前缓存的 VNode 实例进行渲染。
(VNode:虚拟DOM,其实就是一个JS对象)
< keep-alive > 会将数据保留在内存中,进入页面时调用 activated,代替原本的created钩子
被包含在 < keep-alive > 中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated
activated:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。
deactivated:在组件被停用时调用。
注意: 在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。
页面第一次进入,钩子的触发顺序 created -> mounted -> activated,退出时触发 deactivated。
当再次进入(前进或者后退)时,只触发 activated。
npm6和npm8对于peer deps处理方式的差异
peerDependencies的目的是提示安装满足插件peerDependencies所指定依赖的包,然后在插件import或者require所依赖的包的时候,永远都是引用统一安装的npm包,最终解决插件与所依赖包不一致的问题。
跨域时浏览器发送的预检请求的请求方法和请求中常见的属性
当发起跨域请求的时候,会在正式请求之前先发起options请求,也就是cors预检请求,如果服务器接受,浏览器才会发起正式请求
Access-control-request-method 实际请求将使用的方法
Access-control-request-headers 实际请求携带的头信息
Access-control-allow-method 服务器允许的请求方法
Access-control-allow-origin 允许跨域请求的域名
Access-control—allow-headers 允许实际请求携带的header
Access-control-max-age 预检请求结果的缓存时间
介绍一个了解的微前端框架并说明其优缺点 
微前端用通俗易懂的话来说就是:一个主应用(基座)中可以搭建多个子应用(微应用),这些子应用可以是不同版本,不同前端框架,而且跟主应用的语言无关,主应用仅仅是一个基座。
microapp qiankun
qiankun 蚂蚁金服的微前端框架,体积稍大,加载性能方面可能稍有影响,
microapp 京东出品,基于web component原生组件渲染,从组件化的思维实现微前端
接入成本最低,无关技术栈,样式隔离,js沙箱,静态资源补全
展示pdf(pdf只预览不下载) 
转成图片展示、用KKFile这个服务展示
表格列特别多怎么办  
虚拟列、减少渲染的字符数量  三方插件vxe-table
node多版本切换  尤其是node-sass的版本对应
n管理,比nvm好用
nodesass版本不符怎么办,先删除sass-loader再删除node-sass,之后安装对应版本就好了
依赖版本升级了怎么办 
去掉 版本通配符 ^和~ 固定下来版本
x.y.z  x主版本 y副版本 z补丁版本
^更新副版本,比如^1.0.1,就是更新到1.x的最新版本
~更新补丁,比如~1.0.1,就是更新到1.0的最新版本
两个组件的依赖冲突了怎么办      
看这个组件是否有 和现有组件 依赖的冲突, 如果有用install --force解决
返回页面变成空白了  
keep-alive问题
浏览器兼容性问题
兼容工具:postcss等
使用babel,但是babel不转换新的api,比如Promise,所以引入core-js来解决(core-js包含了babel-polyfill)。
babel是一个js编译器
nodejs版本升级注意事项
确保node跟项目的依赖兼容,若不兼容,可以尝试更新依赖版本,逐步升级。
第一个项目(之前说的或者简历中)的技术栈是什么,自己认为比较好的技术栈
uniapp
项目上有没有难点的问题,如何解决的
由于之前的业务相对常规,没有遇到过大的困难,但是也比较期待再今后工作中遇到一些难题,因为这样才会有成长。
IT项目开发管理说明,通过哪些工具
禅道、jira

vue的生命周期有哪些及每个生命周期做了什么?

beforeCreate是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。
created在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。
beforeMount发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。
mounted在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。
beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染
updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。
beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。
destroyed发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。

在Vue3中,去掉了beforeCreate、created两个生命周期函数,用setup来替代(也就是说在setup中写的代码,相当于之前在这两个函数中写的代码);
在Vue3中,将beforeDestroy、destroyed两个生命周期函数更名为onBeforeUnmount、onUnmounted;
在Vue3中,其它生命周期函数并没有改变,只是在每个生命周期函数前面加上了一个on。

v-if和v-for谁的优先级更高

​​​​​​​​​​​​​​

在Vue2中,v-for的优先级要高于v-if,但是在Vue3中,v-for的优先级要低于v-if。

v-for的key是做什么的

标识当前VNode节点,在进行更新操作时会将更新前后两个key相同的元素视作同一元素,进行对比,然后进行相应的更新操作。
如果没有key,就只能按顺序进行对比

为什么不建议使用index作为v-for的key

数据变化时,index对应的新老对象可能发生变化。

data为什么必须是一个函数

data是一个组件的私有属性,但是一个组件可以被其它多个组件使用,之所以必须是一个函数,是因为函数作用域是私有作用域,保证变量不会被污染。
如果我们返回一个普通对象,在多个组件使用该组件时,如果都对data中的某个属性进行了修改,所有使用该组件的组件都会被影响。
而使用函数则每次都会创建一个新的对象,保证当前的data不会被其它组件所影响。

扫描二维码关注公众号,回复: 17460809 查看本文章

v-model的原理是什么,vue2和vue3中有什么区别?

v-model就是v-bind:xxx和@xxx的语法糖,默认为v-bind:value和@input。
在Vue2中,如果我们想改变v-model绑定的值和事件,可以给组件添加model配置项。
在Vue3中,移除了.sync修饰符,使用v-model来替代。此时在自定义组件中v-model代表的含义为v-model:moduleValue,也就相当于:module-value="xxx" && @update:module-value="newValue => xxx = newValue"。并且在Vue3中,v-model可以传参,默认参数就是moduleValue,我们也可以改为v-model:a,这时就代表我们给子组件的一个名为a的props属性传参,并且接收了一个@update:a的回调。

Vue中computed和watch的作用是什么,有什么区别?

computed称为计算属性,它必须拥有返回值,它的值可以是固定的,也可以是依赖其它响应式数据计算出来的,它进行一些同步运算处理,当它依赖其它值时,只有当其它值改变时,它才会触发更新。
watch称为监听,它需要监听一个响应式数据,当它监听的数据改变时,它会处理回调任务,可以在回调中做一些异步操作。
区别:
computed是有缓存的,读取computed属性时,如果依赖的值没有变化,就会读取缓存的内容,而watch没有缓存,只要数据改动,就会触发回调;
computed必须要有返回值,watch不需要有返回值;
computed在初始化时就会执行一次,而watch初始化时默认不会执行,如果我们想让它执行,可以设置它的immediate属性为true;
computed相当于创建了一个新的响应式属性,而watch相当于监听原有的响应式属性,然后执行回调;
computed中处理的是同步操作,而watch可以处理异步任务。

vue-router有哪些路由模式,有什么区别

hash、history、Abstract、Memory
1:URL 格式:
Hash 模式:URL 中带有 # 符号和哈希值,例如 XXXX
History 模式:URL 没有 # 符号,直接使用正常的 URL 地址,例如 XXXX
Abstract 模式:不进行 URL 处理,路由信息保存在内存中,适用于非浏览器环境。
2:浏览器行为:
Hash 模式:URL 的哈希值发生变化时,浏览器会触发 hashchange 事件,Vue Router 监听该事件来进行路由导航,不会向服务器发送请求。
History 模式:URL 发生变化时,浏览器会向服务器发送请求,服务器需要配置相应的路由规则来正确响应路由。
Abstract 模式:不涉及浏览器行为,路由信息保存在内存中,适用于非浏览器环境。
3:刷新页面:
Hash 模式:刷新页面时,URL 中的哈希值不会被发送到服务器,仍然停留在前端,因此前端能够通过哈希值来恢复应用的状态。
History 模式:刷新页面时,URL 将被发送到服务器,服务器需要配置相应的路由规则来正确响应路由,否则会导致 404 错误。
Abstract 模式:不涉及浏览器行为,无论如何刷新页面都不会发送请求到服务器。
4:服务器配置:
Hash 模式:不需要特殊的服务器配置,因为哈希值不会发送到服务器。
History 模式:需要服务器配置来支持路由的正常工作,主要是为了在刷新页面或直接访问 URL 时能正确响应路由。
Abstract 模式:不涉及服务器配置,适用于非浏览器环境。
选择使用哪种路由模式取决于项目的需求和环境。
Hash 模式简单易用,不需要服务器配置,但 URL 带有哈希值;
History 模式去除了哈希值,更符合传统 URL 的形式,但需要服务器配置支持;
Abstract 模式适用于非浏览器环境,不涉及浏览器行为。

路由的传参方式,介绍一下区别

query参数会在URL显式存在,params一般不会出现在URL上(动态路由除外);
query传参可以和path属性一起使用,params不能和path属性一起使用,只能和name属性一起使用;
params传参在刷新页面时会参数丢失(动态路由不会),而query传参不会有这种情况。

$router和$route的区别

可以把$router视为全局的路由对象,操作路由一些方法时,使用$router;
把$route视为当前活跃的路由对象,当访问当前路由信息的时候,使用$route;

Vue2和Vue3的响应式有什么区别

Vue2中,响应式系统是通过依次遍历data返回的对象,将里面每一个属性通过Object.defineProperty进行定义,然后在属性描述符中添加get/set,实现getter/setter方法,在访问属性时,在getter函数中收集依赖(记录哪些方法或变量在使用这个属性),在修改属性时,在setter函数中派发依赖(将收集到的依赖依次更新),从而达到响应式。
Vue3中,响应式系统是通过ES6中的Proxy实现对一个对象的代理,然后设置handler.get/handler.set,在对代理对象进行操作时,可以触发get/set,和Object.defineProperty类似,get中实现收集依赖,在set中实现派发依赖,从而达到响应式的效果。

列表组件,他的data发生了变化但UI没变,可能是什么原因?

data的List是同一个内存对象长度没变,或者只是其中item的字段变了

列表组件,只改变其中一个item中的某个字段,怎么操作?

使用$set()

列表组件,如果数据量特别大,列特别多,怎么处理?

虚拟滚动

介绍一下$set()的实现原理?

$set解决的就是对象/数组添加新属性不是响应式的问题,因此它的核心就是调用此方法,vue内部帮助我们把添加的属性变成响应式。
首先这个方法接收三个参数:
target:需要添加属性的对象;
key:需要添加/修改的对象key值;
val:需要修改的value值;
1. 判断传入的对象是否为数组,并且key是否为一个正确的索引,如果是,就会修改数组长度为key和原数组长度的最大值,然后调用数组的splice方法进行更新数组,我们知道splice方法也是不能被defineProperty监听的,为什么这里要调用此方法呢?这是因为Vue内部帮我们重写了数组原型的该方法。
2. 如果传入的是一个对象,那么就判断传入的key值是否在对象中,并且不是在对象的原型上,如果已经在对象中的话,不管当前对象是否为响应式对象,直接通过target[key] = val修改属性值就行了(如果原对象是响应式,那么它已有的属性肯定是响应式的,如果不是,那它已有的属性也不需要是响应式)。
3. 如果传入的对象是vue实例,那么就会抛出警告;
4. 最后通过target.__ob__判断传入的对象是否为响应式的,如果不是响应式,那么给非响应式对象添加属性时,也不需要是响应式,直接使用target[key]=val就行了,如果对象是一个响应式的,那么给它添加新属性,也必须要变成响应式,于是就会调用defineReactive方法将该属性添加getter/setter(本质就是使用Object.defineProperty)将其变成响应式。

$nextTick的作用是什么,原理是什么?

$nextTick是 Vue.js提供的一个异步更新DOM的方法。因为Vue的更新是异步的,如果你想在改变某个属性之后立即去操作DOM,可能结果并不是你想要的,而nextTick允许你在当前 DOM 更新循环结束之后执行一个回调函数,这样可以确保在回调函数中操作的DOM是最新的。
Vue2中传入nextTick的回调函数,会放入callbacks数组中,然后会遍历callbacks数组,依次执行其中的函数。具体在什么时机执行呢?如果支持Promise,就使用Promise.then,否则就使用MutationObserver,这两种是微任务,如果都不支持,会判断是否支持setImmediate(Node中),如果不支持则会使用setTimeout的方式来进行异步执行。
Vue3中,由于无法访问this,因此在使用时变成了导入nextTick函数进行调用,并且该函数返回一个Promise对象,我们可以使用await或者.then来获取异步操作的结果。可见,Vue3中的nextTick只是利用了promise来实现的。

Vue3中ref和reactive的区别是什么?

Vue3的响应式原理是基于Proxy的,而Proxy只能代理对象,如果我们要实现一个基本数据类型的响应式怎么办呢?只能通过将它变成对象的方式;
reactive只能传入一个对象,而ref可以传入任何类型;
ref声明的变量,我们在访问时,除了模板之外,必须使用xxx.value,而reactive不用;
reactive声明的变量可能会造成响应式丢失,这也是为什么官方更推荐使用ref的原因;

常见的布局方式有哪些?

常见的布局方式‌包括‌
静态布局、‌流式布局、‌弹性布局(‌Flex布局)、‌display布局、‌浮动布局、‌定位布局、‌栅格布局和‌grid布局

flex布局用过吗,简单描述一下flex布局

Flex布局(Flexible Box Layout),也称为弹性盒布局,是一种CSS布局模式,旨在提供一种更有效的方式来布局、对齐和分配容器中项目之间的空间,即使它们的大小未知或动态变化‌‌。Flex布局通过调整元素的宽度和高度,使网页在不同分辨率设备上自适应展示,特别适用于响应式设计‌。适用于多种场景,包括:
垂直居中一个块内容‌:使容器的所有子项占用等量的可用宽度/高度‌。
‌多列布局‌:使所有列采用相同的高度,即使它们包含的内容量不同‌。
通过这些属性和应用场景,Flex布局能够提供灵活的布局解决方案,适应各种设计需求。
常用的属性:
flex-direction:
flex-wrap:
‌justify-content‌:
align-items‌:
align-content‌

媒体查询用过吗,简单描述一下媒体查询

媒体查询(Media Queries)可以根据不同的设备特性如屏幕尺寸、分辨率等来应用不同的样式规则。
@media media-type and (media-feature) {
/* 样式规则 */
}
media-type 表示媒体类型,常见的媒体类型包括 all(所有设备)、screen(屏幕设备)、print(打印机)等。 如果不指定媒体类型,则默认为 all。
media-feature 表示媒体特性,用于根据设备的属性来选择样式规则。 常见的媒体特性包括 width(宽度)、height(高度)、orientation(方向) resolution(分辨率)等。

谈一下CSS的选择器以及CSS的优先级

id选择器,#开头,后面跟上元素的id;
类选择器,.开头,后面跟上元素的类名;
标签选择器,标签名;
相邻选择器,第一个选择器+第二个选择器(h1+h2);
子代选择器,父元素选择器>子元素选择器(.father>.son);
后代选择器,父元素选择器+空格+后代选择器(.father p);
后续相邻相抵选择器,第一个选择器~第一个元素之后的选择器(.first~p(在first之后,并且和first同级的所有p标签));
属性选择器,标签名+标签的属性(比如div[class=^a],就代表所有类名以a开头的div元素);
伪类选择器,比如:last-child、:is()、:not()、:first-child、:nth-child(n)、:nth-of-type(n)等等;
伪元素选择器,::after、::before等;
通配符选择器,*
优先级:
!important的优先级最高,无视权重;
其次是内联样式,权重1000;
其次是id选择器,权重100;
再然后是类选择器、伪类选择器、属性选择器,权重10;
再然后是标签选择器、伪元素选择器,权重1;
再然后是通配符选择器,权重0;

如何实现一个高度为0.5px的线

可以通过实现一个1px的线,然后通过CSS的2D转换(scaleY)进行缩放,就变成了0.5px。
<style>
.line {
width: 100%;
height: 1px;
background: #333;
transform: scaleY(0.5);
}
</style>

如何实现一个双栏布局

flex布局最简单

Vue2和Vue3的构建工具分别是什么,有什么区别?

vue2:webpack,vue3:vite
开发环境下vite不需要打包,因为它基于ES Module,能够按需加载,而webpack则需要对所有文件进行打包,分析依赖,流程较为繁琐,大型项目构建较慢;
生产环境下vite是由rollup完成的打包,而webpack不是;

怎么在打包的时候去掉代码中的console相关代码?

vue2 用webpack插件 terser-webpack-plugin。
vue3 在config文件中的esbuild配置中配置drop: ["console", "debugger"],

setTimeout不准时

原因:js是单线程的,执行其他任务时可能导致setTimeout的延迟时间被延长,竞争执行(比如用户点击等)。

解决:setInterval 或 requestAnimationFrame

float盒子高度塌陷

伪元素选择器::after  设置display:block,伪元素是一个行内元素

.box::after{

        clear:both;

        display:block;

}

猜你喜欢

转载自blog.csdn.net/u010609022/article/details/140797697