笔试问题- CSS水平、垂直居中的写法
绝对定位+transform:
.parent { position: relative;}.child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);}- flex布局:.parent { display: flex; justify-content: center; align-items: center;}- 绝对定位+margin:适用于子元素宽高固定的情况。.parent { position: relative;}.child { position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; width: 100px; height: 100px;}- grid布局:.parent { display: grid; place-items: center;}- js里基本的数据类型及检验方法
基本数据类型:Number、String、Boolean、Null、Undefined、Symbol(ES6新增)、BigInt(ES2020新增)。
检验方法:
typeof:用于检测基本数据类型,但对null返回object,不能检测null和undefined的具体区别,也不能区分对象类型。
console.log(typeof 1); // "number"console.log(typeof 'abc'); // "string"console.log(typeof true); // "boolean"console.log(typeof undefined); // "undefined"console.log(typeof Symbol('foo')); // "symbol"console.log(typeof 100n); // "bigint"console.log(typeof null); // "object" - ===:可以准确判断`null`和`undefined`。console.log(null === null); // trueconsole.log(undefined === undefined); // true - instanceof:用于检测引用类型,判断对象是否为某个构造函数的实例。const arr = [];console.log(arr instanceof Array); // true- 数组去重
var arr = [ '2020', '2021', '2020', '2019', '2020', '2000', '2018', '2021'];// 使用Setconst uniqueArr1 = [...new Set(arr)];console.log(uniqueArr1);// 使用filterconst uniqueArr2 = arr.filter((item, index) => arr.indexOf(item) === index);console.log(uniqueArr2);- 跨平台应用的前端框架及熟悉框架的优势与心得
跨平台前端框架:React Native、Flutter(虽使用Dart语言但可与前端结合)、Taro、uni-app等。
以uni-app为例:
优势:一套代码可编译到多个平台,如iOS、Android、H5、小程序等,大大提高了开发效率,降低了开发成本。组件丰富,有大量现成的UI组件库可供使用,能快速搭建出美观的界面。社区活跃,遇到问题容易找到解决方案。
使用心得:在开发过程中,要注意不同平台的兼容性问题,虽然uni-app做了很多兼容处理,但仍有一些特殊情况需要手动处理。其条件编译功能非常实用,可以根据不同平台编写不同的代码逻辑。
一面问题- 动态组件及keep-alive的作用
动态组件:通过<component>元素和is属性实现动态切换不同的组件。例如:
<template> <component :is="currentComponent"></component></template><script>import ComponentA from './ComponentA.vue';import ComponentB from './ComponentB.vue';export default { data() { return { currentComponent: 'ComponentA' }; }, components: { ComponentA, ComponentB }};</script>- keep-alive的作用:用于缓存不活动的组件实例,避免重复渲染,提高性能。例如在标签页切换时,使用`keep-alive`可以保留之前标签页的状态。<keep-alive> <component :is="currentComponent"></component></keep-alive>- 对前端工程师职位的理解前端工程师负责网站或应用与用户直接交互的部分,不仅要实现美观、易用的界面,还要保证良好的性能和兼容性。需要掌握HTML、CSS、JavaScript等技术,熟悉各种前端框架和工具,与后端工程师协作完成数据交互和业务逻辑。同时,要关注用户体验,不断优化和改进产品。
- 对elementui组件进行二次封装有过对elementui组件二次封装的经验。例如,对el-table进行封装,统一设置表格的样式、分页功能等,减少重复代码,提高开发效率。在封装过程中,可以通过props接收外部传入的参数,实现灵活配置。
- js延迟加载的方式
defer:脚本会在文档解析完成后,DOMContentLoaded事件触发前执行,多个defer脚本按顺序执行。
<script defer src="script.js"></script>- async:脚本在下载完成后立即执行,不保证执行顺序,可能会在文档解析过程中执行。<script async src="script.js"></script>- 动态创建script标签:const script = document.createElement('script');script.src = 'script.js';document.body.appendChild(script);- documentload和documentready的区别
document.onload:当整个页面(包括所有资源,如图片、样式表等)完全加载完成后触发。
document.ready(通常使用$(document).ready()或DOMContentLoaded事件):当DOM结构加载完成,但不一定包含图片等外部资源时触发,执行速度比onload快。
- JavaScript继承的方法
原型链继承:通过将子类的原型指向父类的实例实现继承。
function Parent() {}Parent.prototype.sayHello = function() { console.log('Hello');};function Child() {}Child.prototype = new Parent();const child = new Child();child.sayHello();- 构造函数继承:在子类构造函数中调用父类构造函数。function Parent(name) { this.name = name;}function Child(name) { Parent.call(this, name);}const child = new Child('Tom');console.log(child.name);- 组合继承:结合原型链继承和构造函数继承。function Parent(name) { this.name = name;}Parent.prototype.sayHello = function() { console.log('Hello ' + this.name);};function Child(name) { Parent.call(this, name);}Child.prototype = new Parent();const child = new Child('Tom');child.sayHello();- 对语义化的理解语义化是指使用具有语义的HTML标签来构建网页结构,使代码更易于理解和维护,同时对搜索引擎友好。例如,使用<header>表示页眉,<nav>表示导航栏,<article>表示文章内容等。
- 对HTML5离线存储的理解HTML5离线存储允许网页在离线状态下仍然可以访问部分数据,提高了用户体验。主要包括localStorage和sessionStorage以及Application Cache(已废弃,现使用Service Worker替代)。localStorage长期保存数据,sessionStorage在会话结束时清除数据。
- HTML5新增的新特性
语义化标签:如<header>、<nav>、<article>、<section>等。
多媒体支持:<audio>和<video>标签用于播放音频和视频。
Canvas绘图:通过JavaScript在网页上绘制图形。
本地存储:localStorage和sessionStorage。
Web Workers:允许在后台线程中运行脚本,不阻塞UI线程。
- src和href的区别
src:用于替换当前元素的内容,通常用于引入外部资源,如图片、脚本等,浏览器会暂停解析当前文档,直到加载并执行完该资源。
<script src="script.js"></script><img src="image.jpg">- href:用于建立当前文档与外部资源的链接,如超链接、样式表等,浏览器不会暂停解析当前文档。<link href="style.css" rel="stylesheet"><a href="https://example.com">Link</a>
- mvvm和mvc的区别
MVC:Model(模型)负责数据处理,View(视图)负责展示,Controller(控制器)负责协调Model和View,用户操作通过Controller更新Model,Model的变化通知View更新。
MVVM:Model(模型)和View(视图)与MVC类似,ViewModel是连接Model和View的桥梁,它实现了数据的双向绑定,当Model变化时,View自动更新,当View变化时,Model也自动更新,减少了Controller的逻辑。
- 节流和防抖的区别
节流:在规定时间内只执行一次函数,无论触发多少次事件。例如,滚动事件中使用节流可以减少性能消耗。
function throttle(fn, delay) { let lastTime = 0; return function() { const now = Date.now(); if (now - lastTime > delay) { fn.apply(this, arguments); lastTime = now; } };}- 防抖:在事件触发后,等待一段时间,如果在这段时间内没有再次触发事件,则执行函数。例如,搜索框输入时使用防抖可以减少请求次数。function debounce(fn, delay) { let timer = null; return function() { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, arguments); }, delay); };}- Vue2跟vue3的区别
响应式原理:Vue2使用Object.defineProperty,Vue3使用Proxy,Proxy性能更好,可以监听数组变化和新增属性。
组合式API:Vue3引入了组合式API,使代码组织更灵活,便于复用逻辑。
性能优化:Vue3在编译阶段进行了更多优化,如静态节点提升、补丁标志等,提高了渲染性能。
- 对vue响应式的理解Vue的响应式是指当数据发生变化时,视图会自动更新。Vue2通过Object.defineProperty劫持数据的getter和setter,在数据变化时通知依赖更新视图。Vue3使用Proxy实现响应式,可以更全面地监听数据变化。
- vue的路由模式及区别
hash模式:使用URL的hash部分进行路由,兼容性好,但不美观。
const router = new VueRouter({ mode: 'hash', routes: [...]});- history模式:使用HTML5的History API实现路由,URL更美观,但需要服务器配置支持,否则刷新页面会出现404错误。const router = new VueRouter({ mode: 'history', routes: [...]});- 项目细节:根据实际项目经验,详细介绍项目背景、功能模块、技术选型、遇到的挑战及解决方案等。例如,在一个电商项目中,使用了Vue框架搭建前端页面,通过与后端API进行数据交互实现商品展示、购物车、订单等功能。在性能优化方面,使用了图片懒加载、代码分割等技术。