2025年前端解决跨域的几种办法(前端解决跨域的几种办法面试题)

前端解决跨域的几种办法(前端解决跨域的几种办法面试题)从前端学习到找一份合适的工作 大大小小的面试必不可少 所以我对初级前端面试题进行了初步整理 也方便自己查阅 也希望对小伙伴们有所帮助 nbsp HTML 语义化 HTML 语义化就是让页面内容结构化 它有如下优点 如 HTML5 新标签 盒子模型 盒模型分为标准盒模型和怪异盒模型 IE 模型 标准盒模型

大家好,我是讯享网,很高兴认识大家。



从前端学习到找一份合适的工作,大大小小的面试必不可少,所以我对初级前端面试题进行了初步整理,也方便自己查阅,也希望对小伙伴们有所帮助!

【面试题】2023 中级前端面试题_数据
讯享网

 

HTML语义化

HTML语义化就是让页面内容结构化,它有如下优点

如:

HTML5新标签

盒子模型

盒模型分为标准盒模型和怪异盒模型(IE模型)

【面试题】2023 中级前端面试题_css_02

标准盒模型:元素的宽度等于style里的width+margin+border+padding宽度

【面试题】2023 中级前端面试题_css_03

 

如下代码,整个宽高还是120px

怪异盒模型:元素宽度等于style里的width宽度

【面试题】2023 中级前端面试题_数据_04

 

如下代码,整个宽高还是100px

注意:如果你在设计页面中,发现内容区被撑爆了,那么就先检查一下border-sizing是什么,最好在引用reset.css的时候,就对border-sizing进行统一设置,方便管理

rem与em的区别

rem是根据根的font-size变化,而em是根据父级的font-size变化

rem:相对于根元素html的font-size,假如html为font-size:12px,那么,在其当中的div设置为font-size:2rem,就是当中的div为24px

em:相对于父元素计算,假如某个p元素为font-size:12px,在它内部有个span标签,设置font-size:2em,那么,这时候的span字体大小为:12*2=24px

CSS选择器

css常用选择器

css选择器权重

!important -> 行内样式 -> #id -> .class -> 元素和伪元素 -> * -> 继承 -> 默认

CSS新特性

行内元素和块级元素

行内元素(display: inline)

宽度和高度是由内容决定,与其他元素共占一行的元素,我们将其叫行内元素,例如:​​等

块级元素(display: block)

默认宽度由父容器决定,默认高度由内容决定,独占一行并且可以设置宽高的元素,我们将其叫做块级元素,例如:​​

在平时,我们经常使用CSS的display: inline-block,使它们拥有更多的状态

绝对定位和相对定位的区别

position: absolute
绝对定位:是相对于元素最近的已定位的祖先元素

position: relative
相对定位:相对定位是相对于元素在文档中的初始位置

BFC

什么是BFC?

BFC格式化上下文,它是一个独立的渲染区域,让处于 BFC 内部的元素和外部的元素相互隔离,使内外元素的定位不会相互影响

如何产生BFC?

display: inline-block

position: absolute/fixed

BFC作用

BFC最大的一个作用就是:在页面上有一个独立隔离容器,容器内的元素和容器外的元素布局不会相互影响

水平垂直居中

Flex布局

水平居中

垂直居中

less,sass,styus三者的区别

变量

Sass声明变量必须是『\(』开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号:分隔开。</p><p>Less 声明变量用『@』开头,其余等同 Sass。</p><p>Stylus 中声明变量没有任何限定,结尾的分号可有可无,但变量名和变量值之间必须要有『等号』。</p><p><strong>作用域</strong></p><p>Sass:三者最差,不存在全局变量的概念</p><p>Less:最近的一次更新的变量有效,并且会作用于全部的引用!</p><p>Stylus:Sass 的处理方式和 Stylus 相同,变量值输出时根据之前最近的一次定义计算,每次引用最近的定义有效;</p><p><strong>嵌套</strong></p><p>三种 css 预编译器的「选择器嵌套」在使用上来说没有任何区别,甚至连引用父级选择器的标记 &amp; 也相同</p><p><strong>继承</strong></p><p>Sass和Stylus的继承非常像,能把一个选择器的所有样式继承到另一个选择器上。使用『@extend』开始,后面接被继承的选择器。Stylus 的继承方式来自 Sass,两者如出一辙。 Less 则又「独树一帜」地用伪类来描述继承关系;</p><p><strong>导入@Import</strong></p><p>Sass 中只能在使用 url() 表达式引入时进行变量插值</p><div data-card-editable="false" data-syntax="plain"></div><p>Less 中可以在字符串中进行插值</p><div data-card-editable="false" data-syntax="plain"></div><p>Stylus 中在这里插值不管用,但是可以利用其字符串拼接的功能实现</p><div data-card-editable="false" data-syntax="plain"></div><p><strong>总结</strong></p><p>Sass和Less语法严谨、Stylus相对自由。因为Less长得更像 css,所以它可能学习起来更容易。</p><p>Sass 和 Compass、Stylus 和 Nib 都是好基友。</p><p>Sass 和 Stylus 都具有类语言的逻辑方式处理:条件、循环等,而 Less 需要通过When等关键词模拟这些功能,这方面 Less 比不上 Sass 和 Stylus</p><p>Less 在丰富性以及特色上都不及 Sass 和 Stylus,若不是因为 Bootstrap 引入了 Less,可能它不会像现在这样被广泛应用(个人愚见)</p><h4 id="h14">link与@import区别与选择</h4><div data-card-editable="false" data-syntax="plain"></div><p>link功能较多,可以定义 RSS,定义 Rel 等作用,而@import只能用于加载 css;</p><p>当解析到link时,页面会同步加载所引的 css,而@import所引用的 css 会等到页面加载完才被加载;</p><p>@import需要 IE5 以上才能使用;</p><p>link可以使用 js 动态引入,@import不行</p><h4 id="h15">多行元素的文本省略号</h4><div data-card-editable="false" data-syntax="plain"></div><h4 id="h17">JS的几条基本规范</h4><div data-card-editable="false" data-syntax="plain"></div><h4 id="h18">JS引用方法</h4><p><strong>行内引入</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>内部引入</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>外部引入</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>注意</strong></p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h19">JS的基本数据类型</h4><p>Undefined、Null、Boolean、Number、String、新增:Symbol</p><h4 id="h20">数组操作</h4><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>在 JavaScript 中,用得较多的之一无疑是数组操作,这里过一遍数组的一些用法</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><h4 id="h21">JS有哪些内置对象</h4><div data-card-editable="false" data-syntax="plain"></div><p><br></p><h4 id="h22">get请求传参长度的误区</h4><p>误区:我们经常说get请求参数的大小存在限制,而post请求的参数大小是无限制的</p><p>实际上HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对get请求参数的限制是来源与浏览器或web服务器,浏览器或web服务器限制了url的长度。为了明确这个概念,我们必须再次强调下面几点:</p><p>1、HTTP 协议 未规定 GET 和POST的长度限制</p><p>2、GET的最大长度显示是因为 浏览器和 web服务器限制了 URI的长度</p><p>3、不同的浏览器和WEB服务器,限制的最大长度不一样</p><p>4、要支持IE,则最大长度为2083byte,若只支持Chrome,则最大长度 8182byte</p><h4 id="h23">补充get和post请求在缓存方面的区别</h4><ul><li>get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。</li><li>post不同,post做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。因此get请求适合于请求缓存。</li></ul><h4 id="h24">闭包</h4><p><strong>什么是闭包?</strong></p><p>函数A 里面包含了 函数B,而 函数B 里面使用了 函数A 的变量,那么 函数B 被称为闭包。</p><p>又或者:闭包就是能够读取其他函数内部变量的函数</p><div data-card-editable="false" data-syntax="plain"></div><p><strong>闭包的特征</strong></p><ul><li>函数内再嵌套函数</li><li>内部函数可以引用外层的参数和变量</li><li>参数和变量不会被垃圾回收制回收</li></ul><p><strong>对闭包的理解</strong></p><p>使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念</p><p>闭包 的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中</p><p>闭包的另一个用处,是封装对象的私有属性和私有方法</p><p><strong>闭包的好处</strong></p><p>能够实现封装和缓存等</p><p><strong>闭包的坏处</strong></p><p>就是消耗内存、不正当使用会造成内存溢出的问题</p><p><strong>使用闭包的注意点</strong></p><p>由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露</p><p>解决方法是:在退出函数之前,将不使用的局部变量全部删除</p><p><strong>闭包的经典问题</strong></p><div data-card-editable="false" data-syntax="plain"></div><p>这段代码输出</p><div data-card-editable="false" data-syntax="plain"></div><p>有什么办法依次输出0 1 2</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>第一种方法</p></blockquote><p>使用let</p><div data-card-editable="false" data-syntax="plain"></div><p>在这里,每个 let 和代码块结合起来形成块级作用域,当 setTimeout() 打印时,会寻找最近的块级作用域中的 i,所以依次打印出 0 1 2</p><p>如果这样不明白,我们可以执行下边这段代码</p><div data-card-editable="false" data-syntax="plain"></div><p>此时浏览器依次输出的是:</p><div data-card-editable="false" data-syntax="plain"></div><p>即代码还是先执行 for 循环,但是当 for 结束执行到了 setTimeout 的时候,它会做个标记,这样到了 console.log(i) 中,i 就能找到这个块中最近的变量定义</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>第二种方法</p></blockquote><p>使用立即执行函数解决闭包的问题</p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h25">JS作用域及作用域链</h4><p><strong>作用域</strong></p><p>在JavaScript中,作用域分为 全局作用域 和 函数作用域</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>全局作用域</p></blockquote><p>代码在程序的任何地方都能被访问,window 对象的内置属性都拥有全局作用域</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>函数作用域</p></blockquote><p>在固定的代码片段才能被访问</p><p>例子:</p><p style="text-align:center;"><img src='https://s2.51cto.com/images/blog/202212/10001147_63935e43d0e3e28651.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184' alt='【面试题】2023 中级前端面试题_前端_05' style="width: 445px; visibility: visible;"></p><p>作用域有上下级关系,上下级关系的确定就看函数是在哪个作用域下创建的。如上,fn作用域下创建了bar函数,那么“fn作用域”就是“bar作用域”的上级。</p><p>作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。</p><p>变量取值:到创建 这个变量 的函数的作用域中取值</p><p><strong>作用域链</strong></p><p>一般情况下,变量取值到 创建 这个变量 的函数的作用域中取值。</p><p>但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链</p><p style="text-align:center;"><img src='https://s2.51cto.com/images/blog/202212/10001147_63935e43e3c1439928.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184' alt='【面试题】2023 中级前端面试题_html_06' style="width: 465px; visibility: visible;"></p><p>&nbsp; </p><h4 id="h26">原型和原型链</h4><p><strong>原型和原型链的概念</strong></p><p>每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去</p><p><strong>原型和原型链的关系</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>原型和原型链的特点</strong></p><p>JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变</p><p>当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的</p><p>就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象</p><p>​</p><h4 id="h27">组件化和模块化</h4><p><strong>组件化</strong></p><p><strong>为什么要组件化开发</strong></p><p>有时候页面代码量太大,逻辑太多或者同一个功能组件在许多页面均有使用,维护起来相当复杂,这个时候,就需要组件化开发来进行功能拆分、组件封装,已达到组件通用性,增强代码可读性,维护成本也能大大降低</p><p><strong>组件化开发的优点</strong></p><p>很大程度上降低系统各个功能的耦合性,并且提高了功能内部的聚合性。这对前端工程化及降低代码的维护来说,是有很大的好处的,耦合性的降低,提高了系统的伸展性,降低了开发的复杂度,提升开发效率,降低开发成本</p><p><strong>组件化开发的原则</strong></p><ul><li>专一</li><li>可配置性</li><li>标准性</li><li>复用性</li><li>可维护性</li></ul><p><strong>模块化</strong></p><p><strong>为什么要模块化</strong></p><p>早期的javascript版本没有块级作用域、没有类、没有包、也没有模块,这样会带来一些问题,如复用、依赖、冲突、代码组织混乱等,随着前端的膨胀,模块化显得非常迫切</p><p><strong>模块化的好处</strong></p><ul><li>避免变量污染,命名冲突</li><li>提高代码复用率</li><li>提高了可维护性</li><li>方便依赖关系管理</li></ul><p><strong>模块化的几种方法</strong></p><ul><li>函数封装</li></ul><div data-card-editable="false" data-syntax="plain"></div><div data-card-editable="false" data-syntax="plain"></div><ul><li>立即执行函数表达式(IIFE)</li></ul><div data-card-editable="false" data-syntax="plain"></div><div data-card-editable="false" data-syntax="plain"></div><h4 id="h28">图片的预加载和懒加载</h4><ul><li>预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染</li><li>懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数</li></ul><p>两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。预加载则会增加服务器前端压力,懒加载对服务器有一定的缓解压力作用。</p><h4 id="h29">mouseover和mouseenter的区别</h4><p>mouseover:当鼠标移入元素或其子元素都会触发事件,所以有一个重复触发,冒泡的过程。对应的移除事件是mouseout</p><p>mouseenter:当鼠标移除元素本身(不包含元素的子元素)会触发事件,也就是不会冒泡,对应的移除事件是mouseleave</p><h4 id="h30">解决异步回调地狱</h4><p>promise、generator、async/await</p><h4 id="h31">对This对象的理解</h4><p>this总是指向函数的直接调用者(而非间接调用者)</p><p>如果有new关键字,this指向new出来的那个对象</p><p>在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window</p><h4 id="h33">vue生命周期</h4><p><strong>什么是Vue生命周期?</strong></p><p>Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期</p><p><strong>Vue生命周期的作用是什么?</strong></p><p>它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑</p><p><strong>Vue生命周期总共有几个阶段?</strong></p><p>它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后</p><p><strong>第一次页面加载会触发哪几个钩子?</strong></p><p>第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子</p><p><strong>DOM渲染在哪个周期中就已经完成?</strong></p><p>DOM 渲染在 mounted 中就已经完成了</p><p><strong>每个生命周期适合哪些场景?</strong></p><p>生命周期钩子的一些使用方法:</p><p>beforecreate : 可以在这加个loading事件,在加载实例时触发</p><p>created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用</p><p>mounted : 挂载元素,获取到DOM节点</p><p>updated : 如果对数据统一处理,在这里写上相应函数</p><p>beforeDestroy : 可以做一个确认停止事件的确认框</p><p>nextTick : 更新数据后立即操作dom</p><h4 id="h34">v-show与v-if区别</h4><p>v-show是css切换,v-if是完整的销毁和重新创建</p><p>使用 频繁切换时用v-show,运行时较少改变时用v-if</p><p>v-if=‘false’ v-if是条件渲染,当false的时候不会渲染</p><h4 id="h35">开发中常用的指令有哪些</h4><p>v-model :一般用在表达输入,很轻松的实现表单控件和数据的双向绑定</p><p>v-html: 更新元素的 innerHTML</p><p>v-show 与 v-if: 条件渲染, 注意二者区别</p><div data-card-editable="false" data-syntax="plain"></div><p>v-on : click: 可以简写为@click,@绑定一个事件。如果事件触发了,就可以指定事件的处理函数 v-for:基于源数据多次渲染元素或模板块 v-bind: 当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM</p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h36">绑定class的数组用法</h4><p>对象方法 v-bind:class="{'orange': isRipe, 'green': isNotRipe}"</p><p>数组方法 v-bind:class="[class1, class2]"</p><p>行内 v-bind:style="{color: color, fontSize: fontSize+'px' }"</p><h4 id="h37">组件之间的传值通信</h4><p><strong>父组件给子组件传值</strong></p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>使用props,父组件可以使用props向子组件传递数据</p></blockquote><p>父组件vue模板father.vue</p><div data-card-editable="false" data-syntax="plain"></div><p>子组件vue模板child.vue:</p><div data-card-editable="false" data-syntax="plain"></div><p><strong>子组件向父组件通信</strong></p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>父组件向子组件传递事件方法,子组件通过\)emit触发事件,回调给父组件

父组件vue模板father.vue:

子组件vue模板child.vue:

非父子,兄弟组件之间通信

可以通过实例一个vue实例Bus作为媒介,要相互通信的兄弟组件之中,都引入Bus,然后通过分别调用Bus事件触发和监听来实现通信和参数传递

Bus.js可以是这样:

在需要通信的组件都引入Bus.js:

另一个组件也import Bus.js 在钩子函数中监听on事件

路由跳转方式

MVVM

computed和watch有什么区别?

computed:

watch:

小结:

key

key是为Vue中的vnode标记的唯一id,通过这个key,我们的diff操作可以 更准确、更快速

准确:
如果不加key,那么vue会选择复用节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产生一系列的bug

快速:
key的唯一性可以被Map数据结构充分利用

组件中的data为什么是函数?

为什么组件中的data必须是一个函数,然后return一个对象,而new Vue实例里,data可以直接是一个对象?

因为组件是用来复用的,JS里对象是引用关系,这样作用域没有隔离,而new Vue的实例,是不会被复用的,因此不存在引用对象问题

Class 与 Style 如何动态绑定?

Class 可以通过对象语法和数组语法进行动态绑定:

对象语法

数组语法

Style 也可以通过对象语法和数组语法进行动态绑定:

对象语法

数组语法

vue的单项数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解

额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 \(emit 派发一个自定义事件,父组件接收到后,由父组件修改</p><p>有两种常见的试图改变一个 prop 的情形 :</p><p>这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><p>这个 prop 以一种原始的值传入且需要进行转换</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>在这种情况下,最好使用这个 prop 的值来定义一个计算属性</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><h4 id="h45">keep-alive</h4><p>keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,其有以下特性:</p><ul><li>一般结合路由和动态组件一起使用,用于缓存组件;</li><li>提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;</li><li>对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。</li></ul><h4 id="h46">v-model 的原理</h4><p>vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定,我们知道 v-model 本质上不过是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:</p><ul><li>text 和 textarea 元素使用 value 属性和 input 事件;</li><li>checkbox 和 radio 使用 checked 属性和 change 事件;</li><li>select 字段将 value 作为 prop 并将 change 作为事件;</li></ul><p>以 input 表单元素为例:</p><div data-card-editable="false" data-syntax="plain"></div><p>相当于</p><div data-card-editable="false" data-syntax="plain"></div><p>如果在自定义组件中,v-model 默认会利用名为 value 的 prop 和名为 input 的事件,如下所示:</p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h47">nextTick()</h4><p>在下次DOM更新循环结束之后执行延迟回调。在修改数据之后,立即使用的这个回调函数,获取更新后的DOM</p><div data-card-editable="false" data-syntax="plain"></div><p>​​</p><p><strong>单个插槽</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>命名插槽</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>作用域插槽</strong></p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h48">vue-router有哪几种导航钩子</h4><p>第一种:是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截</p><p>第二种:组件内的钩子</p><p>第三种:单独路由独享组件</p><h4 id="h49">vuex</h4><p><strong>vuex是什么?</strong></p><div data-card-loading="true" data-card-editable="false" data-syntax="plain"></div><p>Vuex有5种属性: 分别是 state、getter、mutation、action、module;</p><p><strong>state</strong><br> Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据</p><p><strong>mutations</strong><br> mutations定义的方法动态修改Vuex 的 store 中的状态或数据</p><p><strong>getters</strong><br> 类似vue的计算属性,主要用来过滤一些数据</p><p><strong>action</strong><br> actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action</p><p><strong>总结</strong><br> vuex 一般用于中大型 web 单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用 vuex 的必要性不是很大,因为完全可以用组件 prop 属性或者事件来完成父子组件之间的通信,vuex 更多地用于解决跨组件通信以及作为数据中心集中式存储数据</p><h4 id="h50">你有对 Vue 项目进行哪些优化?</h4><p><strong>代码层面的优化</strong></p><p><strong>Webpack 层面的优化</strong></p><p><strong>基础的 Web 技术的优化</strong></p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h52">var、let、const之间的区别</h4><p>var声明变量可以重复声明,而let不可以重复声明</p><p>var是不受限于块级的,而let是受限于块级</p><p>var会与window相映射(会挂一个属性),而let不与window相映射</p><p>var可以在声明的上面访问变量,而let有暂存死区,在声明的上面访问变量会报错</p><p>const声明之后必须赋值,否则会报错</p><p>const定义不可变的量,改变了就会报错</p><p>const和let一样不会与window相映射、支持块级作用域、在声明的上面访问变量会报错</p><h4 id="h53">解构赋值</h4><p><strong>数组解构</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>对象解构</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>函数参数的定义</strong></p><p>一般我们在定义函数的时候,如果函数有多个参数时,在es5语法中函数调用时参数必须一一对应,否则就会出现赋值错误的情况,来看一个例子:</p><p>上面这个例子在对用户信息的时候需要传递四个参数,且需要一一对应,这样就会极易出现参数顺序传错的情况,从而导致bug,接下来来看es6解构赋值是怎么解决这个问题的:</p><div data-card-editable="false" data-syntax="plain"></div><p>这么写我们只知道要传声明参数就行来,不需要知道参数的顺序也没关系</p><p><strong>交换变量的值</strong></p><p>在es5中我们需要交换两个变量的值需要借助临时变量的帮助,来看一个例子:</p><div data-card-editable="false" data-syntax="plain"></div><p>来看es6怎么实现:</p><div data-card-editable="false" data-syntax="plain"></div><p>是不是比es5的写法更加方便呢</p><p><br></p><p><strong>函数默认参数</strong></p><p>在日常开发中,经常会有这种情况:函数的参数需要默认值,如果没有默认值在使用的时候就会报错,来看es5中是怎么做的:</p><div data-card-editable="false" data-syntax="plain"></div><p>在函数离 main先对参数做一个默认值赋值,然后再使用避免使用的过程中报错,再来看es6中的使用的方法:</p><div data-card-editable="false" data-syntax="plain"></div><p>在函数定义的时候就定义了默认参数,这样就免了后面给参数赋值默认值的过程,是不是看起来简单多了</p><h4 id="h54">forEach、for in、for of三者区别</h4><p>forEach更多的用来遍历数</p><p>for in 一般常用来遍历对象或json</p><p>for of数组对象都可以遍历,遍历对象需要通过和Object.keys()</p><p>for in循环出的是key,for of循环出的是value</p><h4 id="h55">使用箭头函数应注意什么?</h4><p>1、用了箭头函数,this就不是指向window,而是父级(指向是可变的)<br> 2、不能够使用arguments对象<br> 3、不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误<br> 4、不可以使用yield命令,因此箭头函数不能用作 Generator 函数</p><h4 id="h56">Set、Map的区别</h4><p>应用场景Set用于数据重组,Map用于数据储存</p><p><strong>Set:</strong><br> 1,成员不能重复<br> 2,只有键值没有键名,类似数组<br> 3,可以遍历,方法有add, delete,has</p><p><strong>Map:</strong><br> 1,本质上是健值对的集合,类似集合<br> 2,可以遍历,可以跟各种数据格式转换</p><h4 id="h57">promise对象的用法,手写一个promise</h4><p>promise是一个构造函数,下面是一个简单实例</p><div data-card-loading="true" data-card-editable="false" data-syntax="plain"></div><h4 id="h59">如何创建一个ajax</h4><p>(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象<br> (2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息<br> (3)设置响应HTTP请求状态变化的函数<br> (4)发送HTTP请求<br> (5)获取异步调用返回的数据<br> (6)使用JavaScript和DOM实现局部刷新</p><h4 id="h60">同步和异步的区别</h4><p><strong>同步:</strong><br> 浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作</p><p><strong>异步:</strong><br> 浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容</p><h4 id="h61">ajax的优点和缺点</h4><p><strong>ajax的优点</strong></p><p>1、无刷新更新数据(在不刷新整个页面的情况下维持与服务器通信)<br> 2、异步与服务器通信(使用异步的方式与服务器通信,不打断用户的操作)<br> 3、前端和后端负载均衡(将一些后端的工作交给前端,减少服务器与宽度的负担)<br> 4、界面和应用相分离(ajax将界面和应用分离也就是数据与呈现相分离)</p><p><strong>ajax的缺点</strong></p><p>1、ajax不支持浏览器back按钮<br> 2、安全问题 Aajax暴露了与服务器交互的细节<br> 3、对搜索引擎的支持比较弱<br> 4、破坏了Back与History后退按钮的正常行为等浏览器机制</p><h4 id="h62">get和post的区别</h4><p>1、get和post在HTTP中都代表着请求数据,其中get请求相对来说更简单、快速,效率高些 2、get相对post安全性低<br> 3、get有缓存,post没有<br> 4、get体积小,post可以无限大<br> 5、get的url参数可见,post不可见<br> 6、get只接受ASCII字符的参数数据类型,post没有限制<br> 7、get请求参数会保留历史记录,post中参数不会保留<br> 8、get会被浏览器主动catch,post不会,需要手动设置<br> 9、get在浏览器回退时无害,post会再次提交请求</p><p><strong>什么时候使用post?</strong></p><p>post一般用于修改服务器上的资源,对所发送的信息没有限制。比如</p><p>1、无法使用缓存文件(更新服务器上的文件或数据库)<br> 2、向服务器发送大量数据(POST 没有数据量限制)<br> 3、发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠</p><p><br></p><h4 id="h63">如何解决跨域问题</h4><p>跨域的概念:协议、域名、端口都相同才同域,否则都是跨域</p><p><strong>解决跨域问题:</strong></p><p>1、使用JSONP(json+padding)把数据内填充起来<br> 2、CORS方式(跨域资源共享),在后端上配置可跨域<br> 3、服务器代理,通过服务器的文件能访问第三方资源</p><h4 id="h64">什么是Ajax和JSON,它们的优点和缺点</h4><p><strong>Ajax:</strong></p><p>Ajax是异步JavaScript和XML,用于在Web页面中实现异步数据交互</p><p><strong>Ajax优点:</strong></p><p>异步请求响应快,用户体验好;页面无刷新、数据局部更新;按需取数据,减少了冗余请求和服务器的负担;</p><p><strong>Ajax缺点:</strong></p><p>异步回调问题、this指向问题、路由跳转back问题;对搜索引擎的支持比较弱,对于一些手机还不是很好的支持</p><p><strong>JSON:</strong></p><p>是一种轻量级的数据交换格式,看着像对象,本质是字符串</p><p><strong>JSON优点:</strong></p><p>轻量级、易于人的阅读和编写,便于js解析,支持复合数据类型</p><p><strong>JSON缺点:</strong></p><p>没有XML格式这么推广的深入人心和使用广泛, 没有XML那么通用性</p><h4 id="h66">git常用的命令</h4><p>从远程库克隆到本地:git clone 网站上的仓库地址</p><p>新增文件的命令:git add .</p><p>提交文件的命令:git commit –m或者git commit –a</p><p>查看工作区状况:git status –s</p><p>拉取合并远程分支的操作:git fetch/git merge或者git pull</p><p>查看提交记录命令:git reflog</p><h4 id="h68">webpack打包原理</h4><p>webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。webpack就是识别你的 入口文件。识别你的模块依赖,来打包你的代码。至于你的代码使用的是commonjs还是amd或者es6的import。webpack都会对其进行分析。来获取代码的依赖。webpack做的就是分析代码。转换代码,编译代码,输出代码。webpack本身是一个node的模块,所以webpack.config.js是以commonjs形式书写的(node中的模块化是commonjs规范的)</p><h4 id="h69">模块热更新</h4><p>模块热更新是webpack的一个功能,他可以使代码修改过后不用刷新就可以更新,是高级版的自动刷新浏览器</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>devServer中通过hot属性可以控制模块的热替换</p></blockquote><p><strong>通过配置文件</strong></p><div data-card-editable="false" data-syntax="plain"></div><p><strong>通过命令行</strong></p><div data-card-editable="false" data-syntax="plain"></div><h4 id="h70">如何提高webpack构建速度</h4><p>1、通过externals配置来提取常用库</p><p>2、利用DllPlugin和DllReferencePlugin预编译资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来</p><p>3、使用Happypack 实现多线程加速编译</p><p>要注意的第一点是,它对file-loader和url-loader支持不好,所以这两个loader就不需要换成happypack了,其他loader可以类似地换一下</p><p>4、使用Tree-shaking和Scope Hoisting来剔除多余代码 5、使用fast-sass-loader代替sass-loader 6、babel-loader开启缓存</p><p>babel-loader在执行的时候,可能会产生一些运行期间重复的公共文件,造成代码体积大冗余,同时也会减慢编译效率 可以加上cacheDirectory参数或使用 transform-runtime 插件试试</p><div data-card-editable="false" data-syntax="plain"></div><p><br></p><p>不需要打包编译的插件库换成全局"script"标签引入的方式</p><p>比如jQuery插件,react, react-dom等,代码量是很多的,打包起来可能会很耗时 可以直接用标签引入,然后在webpack配置里使用 expose-loader 或 externals 或 ProvidePlugin 提供给模块内部使用相应的变量</p><div data-card-editable="false" data-syntax="plain"></div><p>8、优化构建时的搜索路径</p><p>在webpack打包时,会有各种各样的路径要去查询搜索,我们可以加上一些配置,让它搜索地更快 比如说,方便改成绝对路径的模块路径就改一下,以纯模块名来引入的可以加上一些目录路径 还可以善于用下resolve alias别名 这个字段来配置 还有exclude等的配置,避免多余查找的文件,比如使用babel别忘了剔除不需要遍历的</p><h4 id="h71">webpack的优点</h4><p>专注于处理模块化的项目,能做到开箱即用,一步到位</p><p>可通过plugin扩展,完整好用又不失灵活</p><p>使用场景不局限于web开发</p><p>社区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展</p><p>良好的开发体验</p><h4 id="h72">webpack的缺点</h4><p>webpack的缺点是只能用于采用模块化开发的项目</p><h4 id="h74">文件主要目录及文件作用</h4><div data-card-editable="false" data-syntax="plain"></div><h4 id="h75">微信小程序生命周期</h4><div data-card-editable="false" data-syntax="plain"></div><h4 id="h76">如何封装数据请求</h4><p><strong>1,封装接口</strong></p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>项目/utils/api.js</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><p><strong>2,调用接口</strong></p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>项目/pages/login/login.js</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><p><strong>3,使用接口</strong></p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>项目/pages/login/login.js</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><h4 id="h77">页面数据传递</h4><p>通过 url 携带参数,在 onLoad() 中通过 options 获取 url 上的参数:</p><div data-card-editable="false" data-syntax="plain"></div><p>通过 Storage 来传递参数:</p><div data-card-editable="false" data-syntax="plain"></div><p>WXML传递数据到 JS</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>login.wxml</p></blockquote><div data-card-loading="true" data-card-editable="false" data-syntax="plain"></div><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>login.js</p></blockquote><div data-card-loading="true" data-card-editable="false" data-syntax="plain"></div><p>组件调用传参</p><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>组件接收数据:component-tag-name</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>使用组件的页面定义 json</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><blockquote style="margin-top: 5px; margin-bottom: 5px; padding-left: 1em; margin-left: 0px; border-left: 3px solid rgb(238, 238, 238); opacity: 0.6;"><p>使用组件的页面 HTML 代码</p></blockquote><div data-card-editable="false" data-syntax="plain"></div><p>通过接口调用传递参数</p><h4 id="h78">加载性能优化方法</h4><p>1、通过 this.\)preload() 预加载用户可能点击的第二个页面

2、组件化页面,出现两次以上的部分都进行封装成组件

3、提取共用的 CSS 样式

4、优化图片:TinyPNG

微信小程序与原生APP、Vue、H5差异

微信小程序优势

微信小程序劣势

微信小程序 VS 原生APP
微信小程序有着低开发成本、低获客成本、无需下载的优势

微信小程序 VS H5
1、依赖环境不同。一个能在多种手机浏览器运行。一个只能在微信中的非完整的浏览器
2、开发成本不同。一个可能在各种浏览器出问题。一个只能在微信中运行




微信小程序 VS Vue
微信小程序看似就是**版的 Vue

微信小程序原理

本质上就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面中进行

架构为数据驱动的模式,UI 和数据分离,所有页面的更新,都需要通过对数据的更改来实现

微信小程序分为两个部分:webview 和 appService。其中 webview 主要用来展示 UI,appServer 用来处理业务逻辑、数据及接口调用。它们在两个进程中进行,通过系统层 JSBridge 实现通信,实现 UI 的渲染、事件的处理

wxml与标准的html的异同

wxml基于xml设计,标签只能在微信小程序中使用,不能使用html的标签

网络分层

目前网络分层可分为两种:OSI 模型和 TCP/IP 模型

OSI模型
应用层(Application)
表示层(Presentation)
会话层(Session)
传输层(Transport)
网络层(Network)
数据链路层(Data Link)
物理层(Physical)



















TCP/IP模型
应用层(Application)
传输层(Host-to-Host Transport)
互联网层(Internet)
网络接口层(Network Interface)










HTTP/HTTPS

HTTP状态码

区分状态码
1××开头 - 信息提示
2××开头 - 请求成功
3××开头 - 请求被重定向
4××开头 - 请求错误
5××开头 - 服务器错误













常见状态码
200 - 请求成功,Ajax 接受到信息了
400 - 服务器不理解请求
403 - 服务器拒绝请求
404 - 请求页面错误
500 - 服务器内部错误,无法完成请求













HTML优化

CSS优化

JavaScript优化

常问

人事面

  • 实现界面交互
  • 提升用户体验
  • 有了Node.js,前端可以实现服务端的一些事情

前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好,

与团队成员,UI设计,产品经理的沟通;

做好的页面结构,页面重构和用户体验;

你觉得前端工程的价值体现在哪?

平时如何管理你的项目?

  • 先期团队必须确定好全局样式(globe.css),编码模式(utf-8) 等;
  • 编写习惯必须一致(例如都是采用继承式的写法,单样式都写成一行);
  • 标注样式编写人,各模块都及时标注(标注关键样式调用的地方);
  • 页面进行标注(例如 页面 模块 开始和结束);
  • CSS跟HTML 分文件夹并行存放,命名都得统一(例如style.css);
  • JS 分文件夹存放 命名以该JS功能为准的英文翻译。
  • 图片采用整合的 images.png png8 格式文件使用 - 尽量整合在一起使用方便将来的管理

移动端(Android IOS)怎么做好用户体验?

小讯
上一篇 2025-04-18 15:18
下一篇 2025-06-12 09:16

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/136288.html